From 6e3356fb270591ac4b7931b64205b08f990ae90a Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 8 Aug 2026 09:45:35 +0300 Subject: [PATCH] fix(statusbar): let the cursor reach a menu without closing it A status-bar menu closed as soon as the cursor left its own rectangle. These menus hang off a pill barely wider than its icon, so reaching for a row's text means moving up and across at once, and the diagonal passes through the gap between the pill and the menu. Moving straight up worked; moving toward the thing you were aiming at did not. The safe area now extends one row of the bar in every direction, which is the room that diagonal needs. The bar's row height stops being a literal at its own call site and becomes ROW_HEIGHT, so the two stay together if the bar is ever resized. Closes #682 Co-Authored-By: Claude Opus 5 --- src/ui/statusbar/mod.rs | 8 +++++++- src/ui/statusbar/status_menu.rs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ui/statusbar/mod.rs b/src/ui/statusbar/mod.rs index a7de1029f..6a3a9630b 100644 --- a/src/ui/statusbar/mod.rs +++ b/src/ui/statusbar/mod.rs @@ -28,6 +28,12 @@ use crate::ui::statusbar::status_menu::Entry as StatusMenuEntry; use crate::ui::wrap_bar::WrapBar; use crate::t; +/// Height of one status-bar row. Matches the drawing-tab strip above it so the +/// three horizontal strips — tabs, status bar, command line — line up, and it +/// is also the reach a status-bar menu keeps around itself (see +/// `status_menu::menu_bar`). +pub const ROW_HEIGHT: f32 = 30.0; + const ST_ANNO_VISIBILITY: &[u8] = include_bytes!("../../../assets/icons/scale_list.svg"); const ST_ANNO_AUTO_ADD: &[u8] = include_bytes!("../../../assets/icons/add_scale.svg"); const ST_VP_SCALE_SYNC: &[u8] = include_bytes!("../../../assets/icons/sync.svg"); @@ -528,7 +534,7 @@ impl StatusBar { .vertical_spacing(0.0); let wrap = WrapBar::new(left_area.into(), right_status.into()) - .min_row_h(30.0) + .min_row_h(ROW_HEIGHT) .justify_end(true); container(wrap) diff --git a/src/ui/statusbar/status_menu.rs b/src/ui/statusbar/status_menu.rs index 66b96d1c7..a46b07ee9 100644 --- a/src/ui/statusbar/status_menu.rs +++ b/src/ui/statusbar/status_menu.rs @@ -48,7 +48,13 @@ pub fn menu_bar<'a>( .close_on_background_click(true); MenuBar::new(vec![Item::with_menu(root, menu)]) - .safe_bounds_margin(0.0) + // The cursor may leave the menu by this much before it closes. At zero + // the safe area was the menu's own rectangle, and these menus hang off + // a pill barely wider than its icon: reaching for a row's text meant + // moving up and across at once, and the diagonal left the rectangle + // between the pill and the menu. One row of the bar the menu belongs to + // is enough room for that diagonal, in every direction. (#682) + .safe_bounds_margin(super::ROW_HEIGHT) .close_on_background_click_global(true) .draw_path(DrawPath::Backdrop) .style(|theme: &Theme, _| {