Escape during a task pane drag cancels the drag and stays in full screen

This commit is contained in:
aiongg
2026-10-25 00:14:31 +00:00
parent f501f7cb5f
commit 9129d713ca
2 changed files with 36 additions and 3 deletions
+8 -3
View File
@@ -465,7 +465,7 @@ pub fn canvas_events(app: &mut WordApp, ctx: &egui::Context) {
}
continue;
}
if leave_full_screen(app, key, modifiers, true) {
if leave_full_screen(app, ctx, key, modifiers, true) {
continue;
}
app.canvas.swallow_text = dispatch(app, key, modifiers) && modifiers.alt;
@@ -479,12 +479,17 @@ pub fn canvas_events(app: &mut WordApp, ctx: &egui::Context) {
/// took it: a pen, a text box, a header, a dialog, a menu or a popup, a drag on the page, and in
/// the document (`canvas`) a selection, which Escape collapses first (`select.collapse`), as in a
/// normal window.
fn leave_full_screen(app: &mut WordApp, key: Key, m: Modifiers, canvas: bool) -> bool {
fn leave_full_screen(app: &mut WordApp, ctx: &egui::Context, key: Key, m: Modifiers, canvas: bool) -> bool {
let screen = crate::chrome::Screen::of(&app.session.view).exit_command();
let Some(id) = screen.or(app.session.view.full_screen.then_some("view.fullScreen")) else { return false };
if key != Key::Escape || !m.is_none() || !app.escape_free {
return false;
}
// Escape with a button held (dragging a task pane's title bar, say) cancels the drag only.
// egui has already dropped the drag itself, so the held button is what is left of it.
if ctx.input(|i| i.pointer.any_down()) {
return false;
}
let c = &app.canvas;
if c.obj_drag.is_some() || c.table_resize.is_some() || c.table_drag.is_some() || c.link_from.is_some() {
return false;
@@ -720,7 +725,7 @@ pub fn global_shortcuts(app: &mut WordApp, ctx: &egui::Context) {
let events = ctx.input(|i| i.events.clone());
for e in events {
if let egui::Event::Key { key, pressed: true, modifiers, .. } = e {
if leave_full_screen(app, key, modifiers, false) {
if leave_full_screen(app, ctx, key, modifiers, false) {
continue;
}
if is_global_shortcut(key, modifiers) {
+28
View File
@@ -1305,6 +1305,34 @@ mod tests {
assert_eq!(h.state().dialog.as_ref().map(|d| d.name()), Some("wordCount"));
}
/// Escape during a pane's title-bar drag cancels the drag and leaves full screen on.
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn escape_during_a_pane_drag_keeps_full_screen() {
use egui_kittest::kittest::Queryable;
let mut app = crate::WordApp::new(wordcraft_engine::Session::new(wordcraft_doc::Document::from_text("")), crate::Services::default());
app.run("view.navigationPane", serde_json::json!({"value": true})).unwrap();
app.run("view.fullScreen", serde_json::json!({"value": true})).unwrap();
let mut h = pane_harness(app);
let title = h.get_by_label_contains("Move Pane: ").rect().center();
let button =
|pos, pressed| egui::Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: egui::Modifiers::NONE };
h.input_mut().events.extend([egui::Event::PointerMoved(title), button(title, true)]);
h.run_steps(2);
let away = title + egui::vec2(300.0, 200.0);
h.input_mut().events.push(egui::Event::PointerMoved(away));
h.run_steps(2);
assert!(h.ctx.dragged_id().is_some(), "the title bar is dragged");
press(&mut h, egui::Key::Escape, egui::Modifiers::NONE);
assert!(h.state().session.view.full_screen);
h.input_mut().events.push(button(away, false));
h.run_steps(2);
assert!(h.state().session.view.full_screen);
let docked = craft_ui::panes::Place::Docked(craft_ui::panes::Edge::Start);
assert_eq!(super::pane_state(h.state(), Pane::Navigation).place, docked, "the drag was cancelled");
}
/// An F6 the user bound runs its command; plain F6 still moves to the panes when only
/// Shift+F6 is bound.
#[test]