Scope the File page's back-arrow hit area to the chevron

On Windows/Linux, the back arrow in the File (Backstage) page's side
panel was clickable across the whole 200px-wide row, not just the
chevron icon drawn at its left edge. Clicking anywhere in that row —
plain sidebar background to a user's eye — closed the File page the
same as clicking the arrow itself, with no visual cue it was
clickable.

Scope the click region to a narrow band around the chevron, the same
width already used for the macOS chevron fix (#2972). The row still
reserves its full 200x40 space for layout; only the interactive rect
shrinks.

Updated two tests that relied on the old oversized hit box to click
at the chevron's actual position, and added a regression test
asserting a click beside the arrow leaves the File page open.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
SofiaAFigueredoandClaude Sonnet 5 committed 2026-10-21 07:44:04 -03:00
1 parent e05b7fe86f
commit 52fab678b6
1 file changed
+22 -10
+22 -10
View File
@@ -63,14 +63,13 @@ pub fn show(app: &mut WordApp, ui: &mut Ui) {
icons::paint(ui.painter(), Rect::from_center_size(c, vec2(18.0, 18.0)), "chevronLeft", egui::Color32::WHITE, egui::Color32::WHITE);
resp
} else {
let (r, resp) = ui.allocate_exact_size(vec2(200.0, 40.0), Sense::click());
icons::paint(
ui.painter(),
Rect::from_center_size(pos2(r.min.x + 26.0, r.center().y), vec2(18.0, 18.0)),
"chevronLeft",
egui::Color32::WHITE,
egui::Color32::WHITE,
);
// The hit area is scoped to the chevron, not the whole 200px-wide row (#3041):
// the row reads as plain sidebar background next to it, so clicking there must
// not also close the File page, same as the macOS chevron fix (#2972) below.
let (r, _) = ui.allocate_exact_size(vec2(200.0, 40.0), Sense::hover());
let c = pos2(r.min.x + 26.0, r.center().y);
let resp = ui.interact(Rect::from_center_size(c, vec2(22.0, r.height())), ui.id().with("backstage_back"), Sense::click());
icons::paint(ui.painter(), Rect::from_center_size(c, vec2(18.0, 18.0)), "chevronLeft", egui::Color32::WHITE, egui::Color32::WHITE);
resp
};
// Escape in the built-in file browser closes only the browser.
@@ -742,7 +741,7 @@ mod tests {
h.state_mut().run("ui.backstage", json!({"value": true})).unwrap();
h.run_steps(4);
// The arrow heads the File page's side bar; it has no label to find it by.
let arrow = egui::pos2(100.0, 32.0);
let arrow = egui::pos2(26.0, 32.0);
h.event(egui::Event::PointerMoved(arrow));
for pressed in [true, false] {
h.event(egui::Event::PointerButton { pos: arrow, button: egui::PointerButton::Primary, pressed, modifiers: egui::Modifiers::NONE });
@@ -752,6 +751,19 @@ mod tests {
assert!(h.state().canvas.focused, "and the page has the keyboard");
}
/// #3041: clicking the plain sidebar background next to the back arrow must not also close
/// the File page — only the chevron itself does, same scoping as the macOS chevron (#2972).
#[test]
fn clicking_beside_the_back_arrow_does_not_close_the_file_page() {
let a = WordApp::new(wordcraft_engine::Session::new(wordcraft_doc::Document::new()), Services::default());
let mut h = a11y_harness(a);
h.state_mut().run("ui.backstage", json!({"value": true})).unwrap();
h.run_steps(4);
// Well clear of the chevron (centred at x=26) but still inside the old 200px-wide row.
click_at(&mut h, egui::pos2(100.0, 32.0));
assert!(h.state().ui.backstage, "clicking beside the arrow leaves the File page open");
}
/// A harness over the whole app; kittest always runs AccessKit, so a frame that names as
/// focused a widget it didn't draw panics with "Focused ID … is not in the node list".
fn a11y_harness(a: WordApp) -> egui_kittest::Harness<'static, WordApp> {
@@ -848,7 +860,7 @@ mod tests {
a.ui.start_screen = true;
assert!(a.start_screen());
}
let back = if mac { mac_chevron(&a) } else { egui::pos2(100.0, 32.0) };
let back = if mac { mac_chevron(&a) } else { egui::pos2(26.0, 32.0) };
let mut h = a11y_harness(a);
if !start {
h.state_mut().run("ui.backstage", json!({"value": true})).unwrap();