@@ -714,6 +714,26 @@ impl MultiWorkspace {
cx.emit(MultiWorkspaceEvent::WorkspaceAdded(workspace));
}
+ pub(crate) fn activate_provisional_workspace(
+ &mut self,
+ workspace: Entity<Workspace>,
+ provisional_key: ProjectGroupKey,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ if workspace != self.active_workspace {
+ self.register_workspace(&workspace, window, cx);
+ }
+
+ self.ensure_project_group_state(provisional_key);
+ if !self.is_workspace_retained(&workspace) {
+ self.retained_workspaces.push(workspace.clone());
+ }
+
+ self.activate(workspace.clone(), window, cx);
+ cx.emit(MultiWorkspaceEvent::WorkspaceAdded(workspace));
+ }
+
fn register_workspace(
&mut self,
workspace: &Entity<Workspace>,
@@ -667,44 +667,52 @@ async fn test_switching_projects_with_sidebar_closed_detaches_old_active_workspa
}
#[gpui::test]
-async fn test_remote_worktree_without_git_updates_project_group(cx: &mut TestAppContext) {
+async fn test_remote_project_root_dir_changes_update_groups(cx: &mut TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.executor());
- fs.insert_tree("/local", json!({ "file.txt": "" })).await;
- let project = Project::test(fs.clone(), ["/local".as_ref()], cx).await;
+ fs.insert_tree("/root_a", json!({ "file.txt": "" })).await;
+ fs.insert_tree("/local_b", json!({ "file.txt": "" })).await;
+ let project_a = Project::test(fs.clone(), ["/root_a".as_ref()], cx).await;
+ let project_b = Project::test(fs.clone(), ["/local_b".as_ref()], cx).await;
let (multi_workspace, cx) =
- cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
+ cx.add_window_view(|window, cx| MultiWorkspace::test_new(project_a, window, cx));
multi_workspace.update(cx, |mw, cx| {
mw.open_sidebar(cx);
});
cx.run_until_parked();
- let initial_key = project.read_with(cx, |p, cx| p.project_group_key(cx));
+ let workspace_b = multi_workspace.update_in(cx, |mw, window, cx| {
+ let workspace = cx.new(|cx| Workspace::test_new(project_b.clone(), window, cx));
+ let key = workspace.read(cx).project_group_key(cx);
+ mw.activate_provisional_workspace(workspace.clone(), key, window, cx);
+ workspace
+ });
+ cx.run_until_parked();
+
+ multi_workspace.read_with(cx, |mw, _cx| {
+ assert_eq!(
+ mw.workspace().entity_id(),
+ workspace_b.entity_id(),
+ "registered workspace should become active"
+ );
+ });
+
+ let initial_key = project_b.read_with(cx, |p, cx| p.project_group_key(cx));
multi_workspace.read_with(cx, |mw, _cx| {
let keys = mw.project_group_keys();
- assert_eq!(keys.len(), 1);
- assert_eq!(keys[0], initial_key);
+ assert!(
+ keys.contains(&initial_key),
+ "project groups should contain the initial key for the registered workspace"
+ );
});
- // Add a remote worktree without git repo info.
- let remote_worktree = project.update(cx, |project, cx| {
+ let remote_worktree = project_b.update(cx, |project, cx| {
project.add_test_remote_worktree("/remote/project", cx)
});
cx.run_until_parked();
- // The remote worktree has no entries yet, so project_group_key should
- // still exclude it.
- let key_after_add = project.read_with(cx, |p, cx| p.project_group_key(cx));
- assert_eq!(
- key_after_add, initial_key,
- "remote worktree without entries should not affect the group key"
- );
-
- // Send an UpdateWorktree to the remote worktree with entries but no repo.
- // This triggers UpdatedRootRepoCommonDir on the first update (the fix),
- // which propagates through WorktreeStore → Project → MultiWorkspace.
let worktree_id = remote_worktree.read_with(cx, |wt, _| wt.id().to_proto());
remote_worktree.update(cx, |worktree, _cx| {
worktree
@@ -741,17 +749,21 @@ async fn test_remote_worktree_without_git_updates_project_group(cx: &mut TestApp
});
cx.run_until_parked();
- let updated_key = project.read_with(cx, |p, cx| p.project_group_key(cx));
+ let updated_key = project_b.read_with(cx, |p, cx| p.project_group_key(cx));
assert_ne!(
initial_key, updated_key,
- "adding a remote worktree should change the project group key"
+ "remote worktree update should change the project group key"
);
multi_workspace.read_with(cx, |mw, _cx| {
let keys = mw.project_group_keys();
assert!(
keys.contains(&updated_key),
- "should contain the updated key; got {keys:?}"
+ "project groups should contain the updated key after remote change; got {keys:?}"
+ );
+ assert!(
+ !keys.contains(&initial_key),
+ "project groups should no longer contain the stale initial key; got {keys:?}"
);
});
}
@@ -9959,9 +9959,15 @@ async fn open_remote_project_inner(
});
if let Some(project_group_key) = provisional_project_group_key.clone() {
- multi_workspace.retain_workspace(new_workspace.clone(), project_group_key, cx);
+ multi_workspace.activate_provisional_workspace(
+ new_workspace.clone(),
+ project_group_key,
+ window,
+ cx,
+ );
+ } else {
+ multi_workspace.activate(new_workspace.clone(), window, cx);
}
- multi_workspace.activate(new_workspace.clone(), window, cx);
new_workspace
})?;