diff --git a/crates/edit/src/tui.rs b/crates/edit/src/tui.rs index 314cdc30cc6..3b763dce080 100644 --- a/crates/edit/src/tui.rs +++ b/crates/edit/src/tui.rs @@ -361,6 +361,10 @@ pub struct Tui { /// need to scroll the node into view if it's within a scrollarea. focused_node_for_scrolling: u64, + /// Tracks the node ID of the menubar button that opened the current menu. + /// Used to implement toggle-close: clicking the same button again closes the menu. + menubar_toggle_id: u64, + /// A list of cached text buffers used for [`Context::editline()`]. cached_text_buffers: Vec, @@ -412,6 +416,7 @@ impl Tui { focused_node_path: Vec::with_capacity(16), focused_node_for_scrolling: ROOT_ID, + menubar_toggle_id: 0, cached_text_buffers: Vec::with_capacity(16), @@ -3165,7 +3170,19 @@ impl<'a> Context<'a, '_> { && !contains_focus && self.consume_shortcut(kbmod::ALT | InputKey::new(accelerator as u32)); + let button_id = self.tree.last_node.borrow().id; + if contains_focus && self.tui.menubar_toggle_id == button_id && self.contains_mouse_down() { + self.tui.menubar_toggle_id = 0; + self.tui.pop_focusable_node(1); + + return false; + } + if contains_focus || keyboard_focus { + if self.tui.mouse_state != InputMouseState::Left { + self.tui.menubar_toggle_id = button_id; + } + self.attr_background_rgba(self.tui.floater_default_bg); self.attr_foreground_rgba(self.tui.floater_default_fg); @@ -3278,6 +3295,10 @@ impl<'a> Context<'a, '_> { /// Ends the current menubar. pub fn menubar_end(&mut self) { self.table_end(); + + if !self.contains_focus() { + self.tui.menubar_toggle_id = 0; + } } /// Renders a button label with an optional accelerator character