@@ -302,8 +302,28 @@ impl MultiWorkspace {
}
fn focus_active_workspace(&self, window: &mut Window, cx: &mut App) {
- let pane = self.workspace().read(cx).active_pane().clone();
- let focus_handle = pane.read(cx).focus_handle(cx);
+ // If a dock panel is zoomed, focus it instead of the center pane.
+ // Otherwise, focusing the center pane triggers dismiss_zoomed_items_to_reveal
+ // which closes the zoomed dock.
+ let focus_handle = {
+ let workspace = self.workspace().read(cx);
+ let mut target = None;
+ for dock in workspace.all_docks() {
+ let dock = dock.read(cx);
+ if dock.is_open() {
+ if let Some(panel) = dock.active_panel() {
+ if panel.is_zoomed(window, cx) {
+ target = Some(panel.panel_focus_handle(cx));
+ break;
+ }
+ }
+ }
+ }
+ target.unwrap_or_else(|| {
+ let pane = workspace.active_pane().clone();
+ pane.read(cx).focus_handle(cx)
+ })
+ };
window.focus(&focus_handle, cx);
}
@@ -12724,6 +12724,101 @@ mod tests {
});
}
+ #[gpui::test]
+ async fn test_panel_zoom_preserved_across_workspace_switch(cx: &mut TestAppContext) {
+ init_test(cx);
+ let fs = FakeFs::new(cx.executor());
+
+ let project_a = Project::test(fs.clone(), [], cx).await;
+ let project_b = Project::test(fs, [], cx).await;
+
+ let multi_workspace_handle =
+ cx.add_window(|window, cx| MultiWorkspace::test_new(project_a.clone(), window, cx));
+
+ let workspace_a = multi_workspace_handle
+ .read_with(cx, |mw, _| mw.workspace().clone())
+ .unwrap();
+
+ let _workspace_b = multi_workspace_handle
+ .update(cx, |mw, window, cx| {
+ mw.test_add_workspace(project_b, window, cx)
+ })
+ .unwrap();
+
+ // Switch to workspace A
+ multi_workspace_handle
+ .update(cx, |mw, window, cx| {
+ mw.activate_index(0, window, cx);
+ })
+ .unwrap();
+
+ let cx = &mut VisualTestContext::from_window(multi_workspace_handle.into(), cx);
+
+ // Add a panel to workspace A's right dock and open the dock
+ let panel = workspace_a.update_in(cx, |workspace, window, cx| {
+ let panel = cx.new(|cx| TestPanel::new(DockPosition::Right, 100, cx));
+ workspace.add_panel(panel.clone(), window, cx);
+ workspace
+ .right_dock()
+ .update(cx, |dock, cx| dock.set_open(true, window, cx));
+ panel
+ });
+
+ // Focus the panel through the workspace (matching existing test pattern)
+ workspace_a.update_in(cx, |workspace, window, cx| {
+ workspace.toggle_panel_focus::<TestPanel>(window, cx);
+ });
+
+ // Zoom the panel
+ panel.update_in(cx, |panel, window, cx| {
+ panel.set_zoomed(true, window, cx);
+ });
+
+ // Verify the panel is zoomed and the dock is open
+ workspace_a.update_in(cx, |workspace, window, cx| {
+ assert!(
+ workspace.right_dock().read(cx).is_open(),
+ "dock should be open before switch"
+ );
+ assert!(
+ panel.is_zoomed(window, cx),
+ "panel should be zoomed before switch"
+ );
+ assert!(
+ panel.read(cx).focus_handle(cx).contains_focused(window, cx),
+ "panel should be focused before switch"
+ );
+ });
+
+ // Switch to workspace B
+ multi_workspace_handle
+ .update(cx, |mw, window, cx| {
+ mw.activate_index(1, window, cx);
+ })
+ .unwrap();
+ cx.run_until_parked();
+
+ // Switch back to workspace A
+ multi_workspace_handle
+ .update(cx, |mw, window, cx| {
+ mw.activate_index(0, window, cx);
+ })
+ .unwrap();
+ cx.run_until_parked();
+
+ // Verify the panel is still zoomed and the dock is still open
+ workspace_a.update_in(cx, |workspace, window, cx| {
+ assert!(
+ workspace.right_dock().read(cx).is_open(),
+ "dock should still be open after switching back"
+ );
+ assert!(
+ panel.is_zoomed(window, cx),
+ "panel should still be zoomed after switching back"
+ );
+ });
+ }
+
fn pane_items_paths(pane: &Entity<Pane>, cx: &App) -> Vec<String> {
pane.read(cx)
.items()