From eead4eb5f05dc0b9495c845a9801d6213fed30e1 Mon Sep 17 00:00:00 2001 From: Karim Jerbi Date: Sat, 15 Aug 2026 13:12:47 +0100 Subject: [PATCH] perf(props): skip focus sweep when the properties panel is hidden The global left-click listener fires PropPointerPressed on every mouse press anywhere in the app, and the handler used to launch a full widget-tree focus sweep on each one - even when the Properties panel was closed. Gate the sweep on dock_panel_visible(Properties): when the panel is hidden the handler now returns Task::none, turning an O(whole UI) traversal per click into an O(1) boolean check in the common case. The other sweep call sites already gate via sync_active_field_if_any; this was the only ungated one. Tests: - hidden_properties_panel_skips_the_focus_sweep - a click with the panel closed returns a Task::none (units == 0), i.e. no sweep. - visible_properties_panel_runs_the_focus_sweep - a click with the panel open still fires the sweep (units > 0), preserving the select-whole-value behavior. --- src/app/update/mod.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index a21d463d9..e0bbf7ca5 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -4633,7 +4633,7 @@ impl OpenCADStudio { Message::PropAttrCommit(tag) => self.on_prop_attr_commit(tag), Message::PropPointerPressed => { - if self.tabs[self.active_tab].is_start || self.clean_screen { + if !self.dock_panel_visible(crate::ui::dock::PanelId::Properties) { return Task::none(); } crate::ui::properties::sync_active_field_task() @@ -7531,3 +7531,41 @@ impl OpenCADStudio { } } } + +#[cfg(test)] +mod prop_pointer_tests { + use super::Message; + use crate::app::OpenCADStudio; + use crate::ui::dock::PanelId; + + fn drawing_app() -> OpenCADStudio { + let mut app = OpenCADStudio::new_for_test(); + app.automation_op(r#"{"op":"new"}"#); + app + } + + #[test] + fn hidden_properties_panel_skips_the_focus_sweep() { + // A click while the panel is closed must not run the widget-tree sweep: + // the returned task is a bare `Task::none` (units == 0). + let mut app = drawing_app(); + assert!(app.dock_panel_visible(PanelId::Properties)); + app.show_properties = false; + assert!(!app.dock_panel_visible(PanelId::Properties)); + + let task = app.update(Message::PropPointerPressed); + assert_eq!(task.units(), 0); + } + + #[test] + fn visible_properties_panel_runs_the_focus_sweep() { + // A click while the panel is open must still fire the sweep (units > 0) + // so the select-whole-value feature keeps working. + let mut app = drawing_app(); + app.show_properties = true; + assert!(app.dock_panel_visible(PanelId::Properties)); + + let task = app.update(Message::PropPointerPressed); + assert!(task.units() > 0); + } +}