From 40a611bf34bf73f2149f133a6c332276f58d2248 Mon Sep 17 00:00:00 2001 From: Andrew Farkas <6060305+HactarCE@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:49:44 -0500 Subject: [PATCH] tab_switcher: Subscribe to workspace events instead of pane events (#44101) Closes #43171 Previously the tab switcher only subscribed to events from a single pane so closing tabs in other panes wouldn't cause the tab switcher to update. This PR changes that so the tab switcher subscribes to the whole workspace and thus updates when tabs in other panes are closed. It also modifies the work in #44006 to sync selected index across the whole workspace instead of just the original pane in the case of the all-panes tab switcher. Release Notes: - Fixed all-panes tab switcher not updating in response to changes in other panes --- crates/tab_switcher/src/tab_switcher.rs | 49 +++++++++++++++---------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/crates/tab_switcher/src/tab_switcher.rs b/crates/tab_switcher/src/tab_switcher.rs index 2b98f6c7e329e7f98edb6b6e994de444a8b835da..85186ad504eb098264aae64ba3c2354d20d011a4 100644 --- a/crates/tab_switcher/src/tab_switcher.rs +++ b/crates/tab_switcher/src/tab_switcher.rs @@ -23,9 +23,9 @@ use ui::{ }; use util::ResultExt; use workspace::{ - ModalView, Pane, SaveIntent, Workspace, + Event as WorkspaceEvent, ModalView, Pane, SaveIntent, Workspace, item::{ItemHandle, ItemSettings, ShowDiagnostics, TabContentParams}, - pane::{Event as PaneEvent, render_item_indicator, tab_details}, + pane::{render_item_indicator, tab_details}, }; const PANEL_WIDTH_REMS: f32 = 28.; @@ -322,7 +322,7 @@ impl TabSwitcherDelegate { cx: &mut Context, original_items: Vec<(Entity, usize)>, ) -> Self { - Self::subscribe_to_updates(&pane, window, cx); + Self::subscribe_to_updates(&workspace, window, cx); Self { select_last, tab_switcher, @@ -338,34 +338,36 @@ impl TabSwitcherDelegate { } fn subscribe_to_updates( - pane: &WeakEntity, + workspace: &WeakEntity, window: &mut Window, cx: &mut Context, ) { - let Some(pane) = pane.upgrade() else { + let Some(workspace) = workspace.upgrade() else { return; }; - cx.subscribe_in(&pane, window, |tab_switcher, _, event, window, cx| { + cx.subscribe_in(&workspace, window, |tab_switcher, _, event, window, cx| { match event { - PaneEvent::AddItem { .. } | PaneEvent::Remove { .. } => { + WorkspaceEvent::ItemAdded { .. } | WorkspaceEvent::PaneRemoved => { tab_switcher.picker.update(cx, |picker, cx| { let query = picker.query(cx); picker.delegate.update_matches(query, window, cx); cx.notify(); }) } - PaneEvent::RemovedItem { .. } => tab_switcher.picker.update(cx, |picker, cx| { - let query = picker.query(cx); - picker.delegate.update_matches(query, window, cx); - - // When the Tab Switcher is being used and an item is - // removed, there's a chance that the new selected index - // will not match the actual tab that is now being displayed - // by the pane, as such, the selected index needs to be - // updated to match the pane's state. - picker.delegate.sync_selected_index(cx); - cx.notify(); - }), + WorkspaceEvent::ItemRemoved { .. } => { + tab_switcher.picker.update(cx, |picker, cx| { + let query = picker.query(cx); + picker.delegate.update_matches(query, window, cx); + + // When the Tab Switcher is being used and an item is + // removed, there's a chance that the new selected index + // will not match the actual tab that is now being displayed + // by the pane, as such, the selected index needs to be + // updated to match the pane's state. + picker.delegate.sync_selected_index(cx); + cx.notify(); + }) + } _ => {} }; }) @@ -563,7 +565,14 @@ impl TabSwitcherDelegate { /// as the pane's active item can be indirectly updated and this method /// ensures that the picker can react to those changes. fn sync_selected_index(&mut self, cx: &mut Context>) { - let Ok(Some(item)) = self.pane.read_with(cx, |pane, _cx| pane.active_item()) else { + let item = if self.is_all_panes { + self.workspace + .read_with(cx, |workspace, cx| workspace.active_item(cx)) + } else { + self.pane.read_with(cx, |pane, _cx| pane.active_item()) + }; + + let Ok(Some(item)) = item else { return; };