Merge pull request #2263 from SusieeTheLinuxUser/fix/2227-clear-text-edit-standdown

Edit: an open text edit stands down the Project-panel Clear redirect (#2227)
This commit is contained in:
BFlat
2026-10-30 05:11:05 +07:00
committed by GitHub
3 changed files with 34 additions and 2 deletions
+2 -1
View File
@@ -119,7 +119,8 @@ pub(crate) fn entry_enabled(app: &EffectcraftApp, e: &MenuEntry) -> bool {
}
}
if e.command == "edit.clear" && app.ui.focused == PanelKind::Project {
return app.session.is_enabled("project.delete");
// An open text edit stands down: Clear must not delete the comp being typed into (#2227).
return app.session.state.text_edit.is_none() && app.session.is_enabled("project.delete");
}
if e.command == "edit.clear" && app.ui.focused == PanelKind::RenderQueue {
return !app.session.is_rendering() && !app.session.project.render_queue.is_empty();
+6 -1
View File
@@ -232,8 +232,13 @@ pub fn invoke(app: &mut EffectcraftApp, ctx: &egui::Context, id: &str, params: V
return run_engine(app, ctx, "edit.pasteSvg", json!({"svg": svg}));
}
}
// Clear follows panel focus, including the Edit menu and keyboard shortcut.
// Clear follows panel focus, including the Edit menu and keyboard shortcut. An open text
// edit stands down: the user is working in a composition, and the Project-panel redirect
// would delete it without asking when nothing uses it (#2227).
if id == "edit.clear" && params.as_object().is_some_and(|p| p.is_empty()) && app.ui.focused == PanelKind::Project {
if app.session.state.text_edit.is_some() {
return Ok(Value::Null);
}
// Through `invoke`, so deleting items that compositions use still asks first (M3.16).
return invoke(app, ctx, "project.delete", json!({}));
}
@@ -364,3 +364,29 @@ fn a_cut_is_read_with_the_modifiers_where_it_is_in_the_frame() {
assert_eq!(h.state().session.project.item(solid).is_none(), deletes, "case {n}: {events:?} after {before:?}");
}
}
/// An open text edit stands down the Project-panel Clear redirect: the composition being typed
/// into must not be deleted out from under it, with no confirmation when nothing uses it (#2227).
#[test]
fn clear_with_the_project_focused_stands_down_during_a_text_edit() {
let (mut h, _, _) = harness();
let working = h.state().session.active_comp_id().unwrap();
// the composition being typed into is also the Project panel's selection, as when it was opened
click(&mut h, &format!("project.item.{}.name", working.0), Modifiers::NONE);
let text = h.state_mut().session.execute("layer.newText", json!({"text": "Title", "size": 80})).unwrap()["layer"].as_u64().unwrap();
h.state_mut().session.execute("text.edit", json!({"layer": text, "created": true})).unwrap();
h.state_mut().ui.focused = PanelKind::Project;
h.run_steps(2);
assert!(h.state().session.state.project_selection.contains(&working), "the comp is the project selection");
let project = h.state().session.project.clone();
// Edit > Clear (the menu, or the control channel) dispatches through `invoke`
let ctx = h.ctx.clone();
let cleared = effectcraft_ui_egui::menus::invoke(h.state_mut(), &ctx, "edit.clear", json!({}));
h.run_steps(3);
cleared.expect("Clear stands down during a text edit");
assert!(h.state().session.project.item(working).is_some(), "the composition being typed into survives");
assert_eq!(h.state().session.project, project, "nothing was deleted");
assert!(h.state().session.state.text_edit.is_some(), "the text edit stays open");
}