From 13fdecd4b75173cb221c84274e0cb39236c45235 Mon Sep 17 00:00:00 2001 From: MrSubidubi Date: Sat, 10 Oct 2026 23:43:11 +0200 Subject: [PATCH] Track some more panels and be more explicit --- crates/debugger_ui/src/session/running.rs | 4 +- crates/terminal_view/src/terminal_panel.rs | 9 +-- crates/terminal_view/src/terminal_view.rs | 44 ++++++++++- crates/workspace/src/pane.rs | 87 +++++++++------------- crates/workspace/src/toolbar.rs | 7 -- crates/workspace/src/workspace.rs | 2 + 6 files changed, 86 insertions(+), 67 deletions(-) diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index e90b59876ce..523550dacaa 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -59,7 +59,7 @@ use util::ResultExt; use variable_list::VariableList; use workspace::{ ActivePaneDecorator, DraggedTab, Item, ItemHandle, ItemNavigation, Member, Pane, PaneGroup, - SplitDirection, Workspace, item::TabContentParams, move_item, pane::Event, + PaneNavigation, SplitDirection, Workspace, item::TabContentParams, move_item, pane::Event, }; static PROCESS_ID_PLACEHOLDER: LazyLock = @@ -654,6 +654,7 @@ pub(crate) fn new_debugger_pane( Some(can_drop_predicate), NoAction.boxed_clone(), true, + PaneNavigation::Disabled, window, cx, ); @@ -689,7 +690,6 @@ pub(crate) fn new_debugger_pane( } }))); pane.set_can_toggle_zoom(false, cx); - pane.display_nav_history_buttons(None); pane.set_should_display_tab_bar(|_, _| true); pane.set_render_tab_bar_buttons(cx, |_, _, _| (None, None)); pane.set_render_tab_bar(cx, { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index b9cfee0302a..6368e45aa74 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -30,8 +30,8 @@ use workspace::{ ActivateNextPane, ActivatePane, ActivatePaneDown, ActivatePaneLeft, ActivatePaneRight, ActivatePaneUp, ActivatePreviousPane, DraggedTab, ItemId, MoveItemToPane, MoveItemToPaneInDirection, MovePaneDown, MovePaneLeft, MovePaneRight, MovePaneUp, Pane, - PaneGroup, SplitDirection, SplitDown, SplitLeft, SplitMode, SplitRight, SplitUp, SwapPaneDown, - SwapPaneLeft, SwapPaneRight, SwapPaneUp, ToggleZoom, Workspace, + PaneGroup, PaneNavigation, SplitDirection, SplitDown, SplitLeft, SplitMode, SplitRight, + SplitUp, SwapPaneDown, SwapPaneLeft, SwapPaneRight, SwapPaneUp, ToggleZoom, Workspace, dock::{DockPosition, Panel, PanelEvent, PanelHandle}, item::{ItemNavigation, SerializableItem}, move_active_item, pane, @@ -1320,12 +1320,11 @@ pub fn new_terminal_pane( None, workspace::NewTerminal::default().boxed_clone(), false, + PaneNavigation::Disabled, window, cx, ); pane.set_zoomed(zoomed, cx); - pane.set_can_navigate(false, cx); - pane.display_nav_history_buttons(None); pane.set_should_display_tab_bar(|_, _| true); pane.set_zoom_out_on_close(false); @@ -1464,7 +1463,7 @@ impl workspace::Item for FailedToSpawnTerminal { type Event = (); fn navigation(&self, _: &Entity, _: &App) -> ItemNavigation { - ItemNavigation::Excluded + ItemNavigation::Visits } fn tab_content_text(&self, _detail: usize, _cx: &App) -> SharedString { diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index b2c830866fa..f6c51ad17f3 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1547,7 +1547,7 @@ impl Item for TerminalView { type Event = ItemEvent; fn navigation(&self, _: &Entity, _: &App) -> ItemNavigation { - ItemNavigation::Excluded + ItemNavigation::Visits } fn tab_tooltip_content(&self, cx: &App) -> Option { @@ -2383,6 +2383,48 @@ mod tests { }); } + #[gpui::test] + async fn center_terminal_is_a_navigation_target(cx: &mut TestAppContext) { + let (project, workspace, window_handle) = init_test_with_window(cx).await; + let (pane, _first_terminal, first_terminal_view) = + add_display_only_terminal(&project, window_handle, true, false, cx); + let (_, _second_terminal, second_terminal_view) = + add_display_only_terminal(&project, window_handle, true, false, cx); + + let cx = &mut VisualTestContext::from_window(window_handle.into(), cx); + cx.run_until_parked(); + + workspace + .update_in(cx, |workspace, window, cx| { + workspace.go_back(pane.downgrade(), window, cx) + }) + .await + .unwrap(); + cx.run_until_parked(); + let active_item_id = + pane.read_with(cx, |pane, _| pane.active_item().map(|item| item.item_id())); + assert_eq!( + active_item_id, + Some(first_terminal_view.entity_id()), + "Back should return to the previously active center terminal" + ); + + workspace + .update_in(cx, |workspace, window, cx| { + workspace.go_forward(pane.downgrade(), window, cx) + }) + .await + .unwrap(); + cx.run_until_parked(); + let active_item_id = + pane.read_with(cx, |pane, _| pane.active_item().map(|item| item.item_id())); + assert_eq!( + active_item_id, + Some(second_terminal_view.entity_id()), + "Forward should return to the second terminal" + ); + } + #[gpui::test] async fn edit_menu_copy_and_paste_are_available_when_terminal_is_focused( cx: &mut TestAppContext, diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index f5d61bd2770..1168aec60c7 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -437,9 +437,7 @@ pub struct Pane { /// This is set to true if a user scroll has occurred more recently than a system scroll /// We want to suppress certain system scrolls when the user has intentionally scrolled suppress_scroll: bool, - /// Is None if navigation buttons are permanently turned off (and should not react to setting changes). - /// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed. - display_nav_history_buttons: Option, + navigation: PaneNavigation, double_click_dispatch_action: Box, save_modals_spawned: HashSet, close_pane_if_empty: bool, @@ -485,6 +483,17 @@ struct NavHistoryState { preview_item_id: Option, } +/// Whether a pane supports going back and forward between its items. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum PaneNavigation { + /// Items are recorded in the navigation history, and the navigation buttons are shown + /// according to the tab bar settings. + Enabled, + /// Nothing is recorded, and neither navigation buttons nor actions are available, e.g. for + /// the terminal panel. + Disabled, +} + #[derive(Debug, Default, Copy, Clone)] pub(crate) enum NavigationMode { #[default] @@ -569,6 +578,7 @@ impl Pane { can_drop_predicate: Option bool + 'static>>, double_click_dispatch_action: Box, use_max_tabs: bool, + navigation: PaneNavigation, window: &mut Window, cx: &mut Context, ) -> Self { @@ -628,9 +638,7 @@ impl Pane { render_tab_bar_buttons: Rc::new(default_render_tab_bar_buttons), render_tab_bar: Rc::new(Self::render_tab_bar), show_tab_bar_buttons: TabBarSettings::get_global(cx).show_tab_bar_buttons, - display_nav_history_buttons: Some( - TabBarSettings::get_global(cx).show_nav_history_buttons, - ), + navigation, _subscriptions: subscriptions, double_click_dispatch_action, save_modals_spawned: HashSet::default(), @@ -809,10 +817,6 @@ impl Pane { fn settings_changed(&mut self, window: &mut Window, cx: &mut Context) { let tab_bar_settings = TabBarSettings::get_global(cx); - if let Some(display_nav_history_buttons) = self.display_nav_history_buttons.as_mut() { - *display_nav_history_buttons = tab_bar_settings.show_nav_history_buttons; - } - self.show_tab_bar_buttons = tab_bar_settings.show_tab_bar_buttons; if !PreviewTabsSettings::get_global(cx).enabled { @@ -877,13 +881,6 @@ impl Pane { cx.notify(); } - pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut Context) { - self.toolbar.update(cx, |toolbar, cx| { - toolbar.set_can_navigate(can_navigate, cx); - }); - cx.notify(); - } - pub fn set_render_tab_bar(&mut self, cx: &mut Context, render: F) where F: 'static + Fn(&mut Pane, &mut Window, &mut Context) -> AnyElement, @@ -914,6 +911,9 @@ impl Pane { /// Records the item's current location, called when it gets deactivated or closed. pub(crate) fn record_navigation(&self, item: &dyn ItemHandle, cx: &mut App) { + if self.navigation == PaneNavigation::Disabled { + return; + } if let Some(location) = item.navigation(cx).capture_location(cx) { self.nav_history_for_item(item).push(location, cx); } @@ -3595,7 +3595,8 @@ impl Pane { ) -> TabBar { tab_bar .when( - self.display_nav_history_buttons.unwrap_or_default(), + self.navigation == PaneNavigation::Enabled + && TabBarSettings::get_global(cx).show_nav_history_buttons, |tab_bar| { tab_bar .start_child(navigate_backward) @@ -4264,10 +4265,6 @@ impl Pane { .log_err(); } - pub fn display_nav_history_buttons(&mut self, display: Option) { - self.display_nav_history_buttons = display; - } - fn pinned_item_ids(&self) -> Vec { self.items .iter() @@ -4492,8 +4489,10 @@ impl Render for Pane { .on_action(cx.listener(Pane::toggle_zoom)) .on_action(cx.listener(Pane::zoom_in)) .on_action(cx.listener(Pane::zoom_out)) - .on_action(cx.listener(Self::navigate_backward)) - .on_action(cx.listener(Self::navigate_forward)) + .when(self.navigation == PaneNavigation::Enabled, |pane| { + pane.on_action(cx.listener(Self::navigate_backward)) + .on_action(cx.listener(Self::navigate_forward)) + }) .on_action(cx.listener(Self::go_to_older_tag)) .on_action(cx.listener(Self::go_to_newer_tag)) .on_action( @@ -4716,34 +4715,18 @@ impl Render for Pane { }), ) }) - .on_mouse_down( - MouseButton::Navigate(NavigationDirection::Back), - cx.listener(|pane, _, window, cx| { - if let Some(workspace) = pane.workspace.upgrade() { - let pane = cx.entity().downgrade(); - window.defer(cx, move |window, cx| { - workspace.update(cx, |workspace, cx| { - workspace.go_back(pane, window, cx).detach_and_log_err(cx) - }) - }) - } - }), - ) - .on_mouse_down( - MouseButton::Navigate(NavigationDirection::Forward), - cx.listener(|pane, _, window, cx| { - if let Some(workspace) = pane.workspace.upgrade() { - let pane = cx.entity().downgrade(); - window.defer(cx, move |window, cx| { - workspace.update(cx, |workspace, cx| { - workspace - .go_forward(pane, window, cx) - .detach_and_log_err(cx) - }) - }) - } - }), - ) + .when(self.navigation == PaneNavigation::Enabled, |pane| { + pane.on_mouse_down( + MouseButton::Navigate(NavigationDirection::Back), + cx.listener(|pane, _, window, cx| pane.navigate_backward(&GoBack, window, cx)), + ) + .on_mouse_down( + MouseButton::Navigate(NavigationDirection::Forward), + cx.listener(|pane, _, window, cx| { + pane.navigate_forward(&GoForward, window, cx) + }), + ) + }) } } diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index b14775f289d..5618f33c3d9 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -64,7 +64,6 @@ pub enum ToolbarItemLocation { pub struct Toolbar { active_item: Option>, hidden: bool, - can_navigate: bool, items: Vec<(Box, ToolbarItemLocation)>, } @@ -172,15 +171,9 @@ impl Toolbar { active_item: None, items: Default::default(), hidden: false, - can_navigate: true, } } - pub fn set_can_navigate(&mut self, can_navigate: bool, cx: &mut Context) { - self.can_navigate = can_navigate; - cx.notify(); - } - pub fn add_item(&mut self, item: Entity, window: &mut Window, cx: &mut Context) where T: 'static + ToolbarItemView, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 2ab75d6a0e4..eb886f94550 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1909,6 +1909,7 @@ impl Workspace { None, NewFile.boxed_clone(), true, + PaneNavigation::Enabled, window, cx, ); @@ -4911,6 +4912,7 @@ impl Workspace { None, NewFile.boxed_clone(), true, + PaneNavigation::Enabled, window, cx, );