From 79213637e2d0598cba3235d26bca9bc7100acdae Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:08:48 +0200 Subject: [PATCH] assistant: Display hamburger menu even when the panel is not focused (#15612) This commit gives tab button renderers control over the condition in which they should be displayed. Previously we displayed tab buttons only when the pane was focused. Now tab renderers can return an Option of AnyElement, which in turn makes it possible for them to control when and how they're rendered. Pane and Terminal handlers still check for self focus condition and Assistant Panel does not. Release Notes: - N/A --- crates/assistant/src/assistant_panel.rs | 1 + crates/terminal_view/src/terminal_panel.rs | 4 ++++ crates/workspace/src/pane.rs | 28 +++++++++++++--------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index e77647b667..a335e80b39 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -378,6 +378,7 @@ impl AssistantPanel { el.child(Pane::render_menu_overlay(new_item_menu)) }) .into_any_element() + .into() }); pane.toolbar().update(cx, |toolbar, cx| { toolbar.add_item(context_editor_toolbar.clone(), cx); diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index ee9a0ae246..f7ae2f3857 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -173,6 +173,9 @@ impl TerminalPanel { let additional_buttons = self.additional_tab_bar_buttons.clone(); self.pane.update(cx, |pane, cx| { pane.set_render_tab_bar_buttons(cx, move |pane, cx| { + if !pane.has_focus(cx) { + return None; + } h_flex() .gap_2() .children(additional_buttons.clone()) @@ -229,6 +232,7 @@ impl TerminalPanel { }) }) .into_any_element() + .into() }); }); } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 0550e937e9..c7fbee1a6e 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -237,7 +237,7 @@ pub struct Pane { Option) -> ControlFlow<(), ()>>>, can_split: bool, should_display_tab_bar: Rc) -> bool>, - render_tab_bar_buttons: Rc) -> AnyElement>, + render_tab_bar_buttons: Rc) -> Option>, _subscriptions: Vec, tab_bar_scroll_handle: ScrollHandle, /// Is None if navigation buttons are permanently turned off (and should not react to setting changes). @@ -356,6 +356,9 @@ impl Pane { can_split: true, should_display_tab_bar: Rc::new(|cx| TabBarSettings::get_global(cx).show), render_tab_bar_buttons: Rc::new(move |pane, cx| { + if !pane.has_focus(cx) { + return None; + } // Ideally we would return a vec of elements here to pass directly to the [TabBar]'s // `end_slot`, but due to needing a view here that isn't possible. h_flex() @@ -438,6 +441,7 @@ impl Pane { el.child(Self::render_menu_overlay(split_item_menu)) }) .into_any_element() + .into() }), display_nav_history_buttons: Some( TabBarSettings::get_global(cx).show_nav_history_buttons, @@ -483,10 +487,10 @@ impl Pane { pub fn has_focus(&self, cx: &WindowContext) -> bool { // We not only check whether our focus handle contains focus, but also - // whether the active_item might have focus, because we might have just activated an item - // but that hasn't rendered yet. - // So before the next render, we might have transferred focus - // to the item and `focus_handle.contains_focus` returns false because the `active_item` + // whether the active item might have focus, because we might have just activated an item + // that hasn't rendered yet. + // Before the next render, we might transfer focus + // to the item, and `focus_handle.contains_focus` returns false because the `active_item` // is not hooked up to us in the dispatch tree. self.focus_handle.contains_focused(cx) || self @@ -582,7 +586,7 @@ impl Pane { pub fn set_render_tab_bar_buttons(&mut self, cx: &mut ViewContext, render: F) where - F: 'static + Fn(&mut Pane, &mut ViewContext) -> AnyElement, + F: 'static + Fn(&mut Pane, &mut ViewContext) -> Option, { self.render_tab_bar_buttons = Rc::new(render); cx.notify(); @@ -1886,11 +1890,13 @@ impl Pane { .start_child(navigate_forward) }, ) - .when(self.has_focus(cx), |tab_bar| { - tab_bar.end_child({ - let render_tab_buttons = self.render_tab_bar_buttons.clone(); - render_tab_buttons(self, cx) - }) + .map(|tab_bar| { + let render_tab_buttons = self.render_tab_bar_buttons.clone(); + if let Some(buttons) = render_tab_buttons(self, cx) { + tab_bar.end_child(buttons) + } else { + tab_bar + } }) .children( self.items