@@ -1484,7 +1484,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| {
@@ -1497,7 +1497,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();
@@ -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);
@@ -636,9 +638,14 @@ impl MultiWorkspace {
})
}
- pub fn remove_workspace(&mut self, index: usize, window: &mut Window, cx: &mut Context<Self>) {
+ pub fn remove_workspace(
+ &mut self,
+ index: usize,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> Option<Entity<Workspace>> {
if self.workspaces.len() <= 1 || index >= self.workspaces.len() {
- return;
+ return None;
}
let removed_workspace = self.workspaces.remove(index);
@@ -679,6 +686,49 @@ impl MultiWorkspace {
));
cx.emit(MultiWorkspaceEvent::ActiveWorkspaceChanged);
cx.notify();
+
+ Some(removed_workspace)
+ }
+
+ pub fn move_workspace_to_new_window(
+ &mut self,
+ index: usize,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ if self.workspaces.len() <= 1 || index >= self.workspaces.len() {
+ return;
+ }
+
+ let Some(workspace) = self.remove_workspace(index, window, cx) else {
+ return;
+ };
+
+ let app_state: Arc<crate::AppState> = workspace.read(cx).app_state().clone();
+
+ cx.defer(move |cx| {
+ let options = (app_state.build_window_options)(None, cx);
+
+ let Ok(window) = cx.open_window(options, |window, cx| {
+ cx.new(|cx| MultiWorkspace::new(workspace, window, cx))
+ }) else {
+ return;
+ };
+
+ let _ = window.update(cx, |_, window, _| {
+ window.activate_window();
+ });
+ });
+ }
+
+ fn move_active_workspace_to_new_window(
+ &mut self,
+ _: &MoveWorkspaceToNewWindow,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let index = self.active_workspace_index;
+ self.move_workspace_to_new_window(index, window, cx);
}
pub fn open_project(
@@ -799,6 +849,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),
@@ -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,
]
);
}