diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 6a5b2c0fbf6..1e27eb3f138 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -6768,14 +6768,17 @@ impl Workspace { window: &mut Window, cx: &mut Context, ) { + let removing_active_pane = self.active_pane() == pane; self.panes.retain(|p| p != pane); if let Some(focus_on) = focus_on { + if removing_active_pane { + self.set_active_pane(focus_on, window, cx); + } focus_on.update(cx, |pane, cx| window.focus(&pane.focus_handle(cx), cx)); - } else if self.active_pane() == pane { + } else if removing_active_pane { let fallback_pane = self.panes.last().unwrap().clone(); - if self.has_active_modal(window, cx) { - self.set_active_pane(&fallback_pane, window, cx); - } else { + self.set_active_pane(&fallback_pane, window, cx); + if !self.has_active_modal(window, cx) { fallback_pane.update(cx, |pane, cx| window.focus(&pane.focus_handle(cx), cx)); } } @@ -14829,6 +14832,47 @@ mod tests { }); } + #[gpui::test] + async fn test_active_pane_updates_to_focus_target_on_removal(cx: &mut TestAppContext) { + assert_active_pane_is_replaced_after_removal(cx, true).await; + } + + #[gpui::test] + async fn test_active_pane_updates_to_fallback_on_removal(cx: &mut TestAppContext) { + assert_active_pane_is_replaced_after_removal(cx, false).await; + } + + async fn assert_active_pane_is_replaced_after_removal( + cx: &mut TestAppContext, + use_focus_target: bool, + ) { + init_test(cx); + + let fs = FakeFs::new(cx.executor()); + let project = Project::test(fs, [], cx).await; + let (workspace, cx) = + cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx)); + + workspace.update_in(cx, |workspace, window, cx| { + let first_pane = workspace.active_pane().clone(); + let second_pane = + workspace.split_pane(first_pane.clone(), SplitDirection::Right, window, cx); + workspace.set_active_pane(&second_pane, window, cx); + + let focus_target = use_focus_target.then(|| first_pane.clone()); + workspace.remove_pane(second_pane, focus_target, window, cx); + + assert_eq!(workspace.active_pane(), &first_pane); + assert!( + workspace + .panes() + .iter() + .any(|pane| pane == workspace.active_pane()), + "active pane should be one of the remaining workspace panes" + ); + }); + } + #[gpui::test] async fn test_moving_items_create_panes(cx: &mut TestAppContext) { init_test(cx);