From e6d3d56fd4c1ce50db1451314fe304f1adb2d37a Mon Sep 17 00:00:00 2001 From: cameron Date: Mon, 23 Mar 2026 14:59:25 +0000 Subject: [PATCH] Add "move to new window" action --- crates/sidebar/src/sidebar.rs | 34 ++++++++++++- crates/workspace/src/multi_workspace.rs | 63 +++++++++++++++++++++++++ crates/zed_actions/src/lib.rs | 2 + 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 9761c9f0ad835cf4cc103700c5f70b715f1b9427..5a33596c4a62d6707a672ec73dc57b14584cc1fa 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -1477,7 +1477,7 @@ impl Sidebar { let workspace_for_add = workspace.clone(); let multi_workspace_for_add = multi_workspace.clone(); - menu.separator().entry( + let menu = menu.separator().entry( "Add Folder to Project", Some(Box::new(AddFolderToProject)), move |window, cx| { @@ -1490,7 +1490,37 @@ impl Sidebar { workspace.add_folder_to_project(&AddFolderToProject, window, cx); }); }, - ) + ); + + let workspace_count = multi_workspace + .upgrade() + .map_or(0, |mw| mw.read(cx).workspaces().len()); + if workspace_count > 1 { + let workspace_for_move = workspace.clone(); + let multi_workspace_for_move = multi_workspace.clone(); + menu.entry( + "Move to New Window", + Some(Box::new( + zed_actions::agents_sidebar::MoveWorkspaceToNewWindow, + )), + move |window, cx| { + if let Some(mw) = multi_workspace_for_move.upgrade() { + mw.update(cx, |multi_workspace, cx| { + if let Some(index) = multi_workspace + .workspaces() + .iter() + .position(|w| *w == workspace_for_move) + { + multi_workspace + .move_workspace_to_new_window(index, window, cx); + } + }); + } + }, + ) + } else { + menu + } }); let this = this.clone(); diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index c3ec2e1c61e1b038f91a57dddac0b7a7b89b337e..f4337537265cb02fb9fe0a1e03ae7e23a753afee 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -11,8 +11,10 @@ use project::Project; use settings::Settings; use std::future::Future; use std::path::PathBuf; +use std::sync::Arc; use ui::prelude::*; use util::ResultExt; +use zed_actions::agents_sidebar::MoveWorkspaceToNewWindow; const SIDEBAR_RESIZE_HANDLE_SIZE: Pixels = px(6.0); @@ -671,6 +673,66 @@ impl MultiWorkspace { cx.notify(); } + pub fn move_workspace_to_new_window( + &mut self, + index: usize, + window: &mut Window, + cx: &mut Context, + ) { + if self.workspaces.len() <= 1 || index >= self.workspaces.len() { + return; + } + + let is_active = index == self.active_workspace_index; + let workspace = &self.workspaces[index]; + let paths: Vec = workspace + .read(cx) + .worktrees(cx) + .map(|worktree| worktree.read(cx).abs_path().to_path_buf()) + .collect(); + let app_state: Arc = workspace.read(cx).app_state().clone(); + + self.remove_workspace(index, window, cx); + + let open_task = cx.spawn(async move |_, cx| { + let open_result = cx + .update(|cx| { + crate::open_paths( + &paths, + app_state, + crate::OpenOptions { + open_new_workspace: Some(true), + ..Default::default() + }, + cx, + ) + }) + .await?; + + if is_active { + open_result + .window + .update(cx, |_, window, _cx| { + window.activate_window(); + }) + .log_err(); + } + + anyhow::Ok(()) + }); + open_task.detach_and_log_err(cx); + } + + fn move_active_workspace_to_new_window( + &mut self, + _: &MoveWorkspaceToNewWindow, + window: &mut Window, + cx: &mut Context, + ) { + let index = self.active_workspace_index; + self.move_workspace_to_new_window(index, window, cx); + } + pub fn open_project( &mut self, paths: Vec, @@ -789,6 +851,7 @@ impl Render for MultiWorkspace { )) .on_action(cx.listener(Self::next_workspace)) .on_action(cx.listener(Self::previous_workspace)) + .on_action(cx.listener(Self::move_active_workspace_to_new_window)) }) .when( self.sidebar_open() && self.multi_workspace_enabled(cx), diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 0306854c0ad546998c122bc79aa9caf18bbace81..f64df42e050023f9f8615dc468e7c3459a4af063 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -786,6 +786,8 @@ pub mod agents_sidebar { [ /// Moves focus to the sidebar's search/filter editor. FocusSidebarFilter, + /// Moves the active workspace to a new window. + MoveWorkspaceToNewWindow, ] ); }