Introduce a new `WindowContext::remove_window` API

Antonio Scandurra and Nathan Sobo created

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

crates/collab_ui/src/project_shared_notification.rs |  6 +--
crates/copilot/src/sign_in.rs                       |  8 +----
crates/gpui/src/app.rs                              |  4 ++
crates/gpui/src/app/window.rs                       |  7 +++++
crates/theme/src/ui.rs                              |  3 -
crates/workspace/src/pane.rs                        | 21 +++++---------
crates/workspace/src/pane/dragged_item_receiver.rs  |  2 
crates/workspace/src/workspace.rs                   |  3 -
8 files changed, 25 insertions(+), 29 deletions(-)

Detailed changes

crates/collab_ui/src/project_shared_notification.rs 🔗

@@ -94,14 +94,12 @@ impl ProjectSharedNotification {
     }
 
     fn join(&mut self, _: &JoinProject, cx: &mut ViewContext<Self>) {
-        let window_id = cx.window_id();
-        cx.remove_window(window_id);
+        cx.remove_window();
         cx.propagate_action();
     }
 
     fn dismiss(&mut self, _: &DismissProject, cx: &mut ViewContext<Self>) {
-        let window_id = cx.window_id();
-        cx.remove_window(window_id);
+        cx.remove_window();
     }
 
     fn render_owner(&self, cx: &mut ViewContext<Self>) -> Element<Self> {

crates/copilot/src/sign_in.rs 🔗

@@ -273,10 +273,7 @@ impl CopilotCodeVerification {
                     style.auth.content_width,
                     &style.auth.cta_button,
                     cx,
-                    |_, _, cx| {
-                        let window_id = cx.window_id();
-                        cx.remove_window(window_id)
-                    },
+                    |_, _, cx| cx.remove_window(),
                 )
                 .boxed(),
             ])
@@ -335,8 +332,7 @@ impl CopilotCodeVerification {
                     &style.auth.cta_button,
                     cx,
                     |_, _, cx| {
-                        let window_id = cx.window_id();
-                        cx.remove_window(window_id);
+                        cx.remove_window();
                         cx.platform().open_url(COPILOT_SIGN_UP_URL)
                     },
                 )

crates/gpui/src/app.rs 🔗

@@ -868,7 +868,9 @@ impl AppContext {
             let mut window = app_context.windows.remove(&window_id)?;
             let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
             let result = callback(&mut window_context);
-            app_context.windows.insert(window_id, window);
+            if !window_context.removed {
+                app_context.windows.insert(window_id, window);
+            }
             Some(result)
         })
     }

crates/gpui/src/app/window.rs 🔗

@@ -116,6 +116,7 @@ pub struct WindowContext<'a: 'b, 'b> {
     pub(crate) window: Reference<'b, Window>,
     pub(crate) window_id: usize,
     pub(crate) refreshing: bool,
+    pub(crate) removed: bool,
 }
 
 impl Deref for WindowContext<'_, '_> {
@@ -216,6 +217,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
             window: Reference::Mutable(window),
             window_id,
             refreshing: false,
+            removed: false,
         }
     }
 
@@ -225,9 +227,14 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
             window: Reference::Immutable(window),
             window_id,
             refreshing: false,
+            removed: false,
         }
     }
 
+    pub fn remove_window(&mut self) {
+        self.removed = true;
+    }
+
     pub fn window_id(&self) -> usize {
         self.window_id
     }

crates/theme/src/ui.rs 🔗

@@ -265,8 +265,7 @@ where
                         icon(style).boxed()
                     })
                     .on_click(platform::MouseButton::Left, move |_, _, cx| {
-                        let window_id = cx.window_id();
-                        cx.remove_window(window_id);
+                        cx.remove_window();
                     })
                     .with_cursor_style(platform::CursorStyle::PointingHand)
                     .aligned()

crates/workspace/src/pane.rs 🔗

@@ -1741,8 +1741,6 @@ impl View for Pane {
     }
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
-        let this = cx.handle().downgrade();
-
         enum MouseNavigationHandler {}
 
         Stack::new()
@@ -1836,20 +1834,17 @@ impl View for Pane {
                         .boxed()
                     }
                 })
-                .on_down(MouseButton::Navigate(NavigationDirection::Back), {
-                    let this = this.clone();
+                .on_down(
+                    MouseButton::Navigate(NavigationDirection::Back),
                     move |_, _, cx| {
-                        cx.dispatch_action(GoBack {
-                            pane: Some(this.clone()),
-                        });
-                    }
-                })
+                        let pane = cx.weak_handle();
+                        cx.dispatch_action(GoBack { pane: Some(pane) });
+                    },
+                )
                 .on_down(MouseButton::Navigate(NavigationDirection::Forward), {
-                    let this = this.clone();
                     move |_, _, cx| {
-                        cx.dispatch_action(GoForward {
-                            pane: Some(this.clone()),
-                        })
+                        let pane = cx.weak_handle();
+                        cx.dispatch_action(GoForward { pane: Some(pane) })
                     }
                 })
                 .boxed(),

crates/workspace/src/pane/dragged_item_receiver.rs 🔗

@@ -74,8 +74,8 @@ where
             .boxed()
     })
     .on_up(MouseButton::Left, {
-        let pane = cx.handle().downgrade();
         move |event, _, cx| {
+            let pane = cx.weak_handle();
             handle_dropped_item(event, &pane, drop_index, allow_same_pane, split_margin, cx);
             cx.notify();
         }

crates/workspace/src/workspace.rs 🔗

@@ -700,8 +700,7 @@ impl Workspace {
                 }
 
                 project::Event::Closed => {
-                    let window_id = cx.window_id();
-                    cx.remove_window(window_id);
+                    cx.remove_window();
                 }
 
                 _ => {}