@@ -1314,6 +1314,44 @@ impl Sidebar {
});
}
+ fn close_all_projects(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+ let Some(multi_workspace) = self.multi_workspace.upgrade() else {
+ return;
+ };
+
+ let workspace_count = multi_workspace.read(cx).workspaces().len();
+ let active_index = multi_workspace.read(cx).active_workspace_index();
+
+ // Remove all workspaces except the active one, iterating in reverse
+ // so that indices of not-yet-visited workspaces remain valid.
+ for index in (0..workspace_count).rev() {
+ if index != active_index {
+ multi_workspace.update(cx, |multi_workspace, cx| {
+ multi_workspace.remove_workspace(index, window, cx);
+ });
+ }
+ }
+
+ // Remove all worktrees from the remaining workspace so it becomes empty.
+ let workspace = multi_workspace.read(cx).workspace().clone();
+ let worktree_ids: Vec<_> = workspace
+ .read(cx)
+ .project()
+ .read(cx)
+ .visible_worktrees(cx)
+ .map(|worktree| worktree.read(cx).id())
+ .collect();
+
+ workspace.update(cx, |workspace, cx| {
+ let project = workspace.project().clone();
+ project.update(cx, |project, cx| {
+ for worktree_id in worktree_ids {
+ project.remove_worktree(worktree_id, cx);
+ }
+ });
+ });
+ }
+
fn toggle_collapse(
&mut self,
path_list: &PathList,
@@ -1913,6 +1951,22 @@ impl Sidebar {
) -> impl IntoElement {
let has_query = self.has_filter_query(cx);
let needs_traffic_light_padding = cfg!(target_os = "macos") && !window.is_fullscreen();
+ let has_open_projects = self
+ .multi_workspace
+ .upgrade()
+ .map(|mw| {
+ let mw = mw.read(cx);
+ mw.workspaces().len() > 1
+ || mw
+ .workspace()
+ .read(cx)
+ .project()
+ .read(cx)
+ .visible_worktrees(cx)
+ .next()
+ .is_some()
+ })
+ .unwrap_or(false);
v_flex()
.flex_none()
@@ -1948,6 +2002,16 @@ impl Sidebar {
})),
)
})
+ .when(has_open_projects, |this| {
+ this.child(
+ IconButton::new("close-all-projects", IconName::Exit)
+ .icon_size(IconSize::Small)
+ .tooltip(Tooltip::text("Close All Projects"))
+ .on_click(cx.listener(|this, _, window, cx| {
+ this.close_all_projects(window, cx);
+ })),
+ )
+ })
.child(
IconButton::new("archive", IconName::Archive)
.icon_size(IconSize::Small)