From 71667cfcb7a7fdf18ea9c80facb3e56566e1178a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 23 Mar 2026 12:05:15 +0100 Subject: [PATCH] sidebar: Fix workspace and project leaking on window close (#52169) Release Notes: - n/a --- crates/sidebar/src/sidebar.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 9d979ffde2a56b7bfaec3c89597eb6cfa2c95c9f..62c032406cdd9d741c58e480f97dbfe3e445781d 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -449,16 +449,19 @@ impl Sidebar { } fn observe_docks(&mut self, workspace: &Entity, cx: &mut Context) { - let workspace = workspace.clone(); let docks: Vec<_> = workspace .read(cx) .all_docks() .into_iter() .cloned() .collect(); + let workspace = workspace.downgrade(); for dock in docks { let workspace = workspace.clone(); cx.observe(&dock, move |this, _dock, cx| { + let Some(workspace) = workspace.upgrade() else { + return; + }; if !this.is_active_workspace(&workspace, cx) { return; } @@ -3361,6 +3364,27 @@ mod tests { assert_eq!(Sidebar::clean_mention_links(""), ""); } + #[gpui::test] + async fn test_entities_released_on_window_close(cx: &mut TestAppContext) { + let project = init_test_project("/my-project", cx).await; + let (multi_workspace, cx) = + cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx)); + let sidebar = setup_sidebar(&multi_workspace, cx); + + let weak_workspace = multi_workspace.read_with(cx, |mw, _| mw.workspace().downgrade()); + let weak_sidebar = sidebar.downgrade(); + let weak_multi_workspace = multi_workspace.downgrade(); + + drop(sidebar); + drop(multi_workspace); + cx.update(|window, _cx| window.remove_window()); + cx.run_until_parked(); + + weak_multi_workspace.assert_released(); + weak_sidebar.assert_released(); + weak_workspace.assert_released(); + } + #[gpui::test] async fn test_single_workspace_no_threads(cx: &mut TestAppContext) { let project = init_test_project("/my-project", cx).await;