From 7adbee0cdc438a0252e6649914aa7fa063780902 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 6 Apr 2026 16:34:36 -0300 Subject: [PATCH] sidebar: Fix behavior of "Remove Project" button (#53242) - Fix an issue where the "remove project" button, available in the header's ellipsis menu, wouldn't do anything if the sidebar contained only one project - Fix another issue where attempting to remove a project when the sidebar has more than one project wouldn't actually remove it. This is fixed by cleaning up the project group keys after its been already removed. Release Notes: - N/A --- crates/workspace/src/multi_workspace.rs | 85 ++++++++++++++++++++----- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index 72cc133f83aece0c6ea68b19bea53b0f5ee65755..a0c5eaabc629073dd9a46ac1b5073ddfbd26bd28 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -6,9 +6,7 @@ use gpui::{ ManagedView, MouseButton, Pixels, Render, Subscription, Task, Tiling, Window, WindowId, actions, deferred, px, }; -#[cfg(any(test, feature = "test-support"))] -use project::Project; -use project::{DirectoryLister, DisableAiSettings, ProjectGroupKey}; +use project::{DirectoryLister, DisableAiSettings, Project, ProjectGroupKey}; use settings::Settings; pub use settings::SidebarSide; use std::future::Future; @@ -468,6 +466,9 @@ impl MultiWorkspace { } pub fn add_project_group_key(&mut self, project_group_key: ProjectGroupKey) { + if project_group_key.path_list().paths().is_empty() { + return; + } if self.project_group_keys.contains(&project_group_key) { return; } @@ -1040,26 +1041,80 @@ impl MultiWorkspace { let Some(index) = self.workspaces.iter().position(|w| w == workspace) else { return false; }; + + let old_key = workspace.read(cx).project_group_key(cx); + if self.workspaces.len() <= 1 { - return false; - } + let has_worktrees = workspace.read(cx).visible_worktrees(cx).next().is_some(); + + if !has_worktrees { + return false; + } + + let old_workspace = workspace.clone(); + let old_entity_id = old_workspace.entity_id(); - let removed_workspace = self.workspaces.remove(index); + let app_state = old_workspace.read(cx).app_state().clone(); + + let project = Project::local( + app_state.client.clone(), + app_state.node_runtime.clone(), + app_state.user_store.clone(), + app_state.languages.clone(), + app_state.fs.clone(), + None, + project::LocalProjectFlags::default(), + cx, + ); + + let new_workspace = cx.new(|cx| Workspace::new(None, project, app_state, window, cx)); + + self.workspaces[0] = new_workspace.clone(); + self.active_workspace_index = 0; + + Self::subscribe_to_workspace(&new_workspace, window, cx); + + self.sync_sidebar_to_workspace(&new_workspace, cx); + + let weak_self = cx.weak_entity(); - if self.active_workspace_index >= self.workspaces.len() { - self.active_workspace_index = self.workspaces.len() - 1; - } else if self.active_workspace_index > index { - self.active_workspace_index -= 1; + new_workspace.update(cx, |workspace, cx| { + workspace.set_multi_workspace(weak_self, cx); + }); + + self.detach_workspace(&old_workspace, cx); + + cx.emit(MultiWorkspaceEvent::WorkspaceRemoved(old_entity_id)); + cx.emit(MultiWorkspaceEvent::WorkspaceAdded(new_workspace)); + cx.emit(MultiWorkspaceEvent::ActiveWorkspaceChanged); + } else { + let removed_workspace = self.workspaces.remove(index); + + if self.active_workspace_index >= self.workspaces.len() { + self.active_workspace_index = self.workspaces.len() - 1; + } else if self.active_workspace_index > index { + self.active_workspace_index -= 1; + } + + self.detach_workspace(&removed_workspace, cx); + + cx.emit(MultiWorkspaceEvent::WorkspaceRemoved( + removed_workspace.entity_id(), + )); + cx.emit(MultiWorkspaceEvent::ActiveWorkspaceChanged); } - self.detach_workspace(&removed_workspace, cx); + let key_still_in_use = self + .workspaces + .iter() + .any(|ws| ws.read(cx).project_group_key(cx) == old_key); + + if !key_still_in_use { + self.project_group_keys.retain(|k| k != &old_key); + } self.serialize(cx); self.focus_active_workspace(window, cx); - cx.emit(MultiWorkspaceEvent::WorkspaceRemoved( - removed_workspace.entity_id(), - )); - cx.emit(MultiWorkspaceEvent::ActiveWorkspaceChanged); cx.notify(); true