Implement WindowContext::remove_window

Antonio Scandurra created

Change summary

crates/gpui2/src/app.rs             | 11 +++++++----
crates/gpui2/src/window.rs          |  7 +++++++
crates/workspace2/src/workspace2.rs |  3 +--
3 files changed, 15 insertions(+), 6 deletions(-)

Detailed changes

crates/gpui2/src/app.rs 🔗

@@ -789,10 +789,13 @@ impl Context for AppContext {
 
             let root_view = window.root_view.clone().unwrap();
             let result = update(root_view, &mut WindowContext::new(cx, &mut window));
-            cx.windows
-                .get_mut(handle.id)
-                .ok_or_else(|| anyhow!("window not found"))?
-                .replace(window);
+
+            if !window.removed {
+                cx.windows
+                    .get_mut(handle.id)
+                    .ok_or_else(|| anyhow!("window not found"))?
+                    .replace(window);
+            }
 
             Ok(result)
         })

crates/gpui2/src/window.rs 🔗

@@ -159,6 +159,7 @@ impl Drop for FocusHandle {
 // Holds the state for a specific window.
 pub struct Window {
     pub(crate) handle: AnyWindowHandle,
+    pub(crate) removed: bool,
     platform_window: Box<dyn PlatformWindow>,
     display_id: DisplayId,
     sprite_atlas: Arc<dyn PlatformAtlas>,
@@ -229,6 +230,7 @@ impl Window {
 
         Window {
             handle,
+            removed: false,
             platform_window,
             display_id,
             sprite_atlas,
@@ -320,6 +322,11 @@ impl<'a> WindowContext<'a> {
         self.window.dirty = true;
     }
 
+    /// Close this window.
+    pub fn remove_window(&mut self) {
+        self.window.removed = true;
+    }
+
     /// Obtain a new `FocusHandle`, which allows you to track and manipulate the keyboard focus
     /// for elements rendered within this window.
     pub fn focus_handle(&mut self) -> FocusHandle {

crates/workspace2/src/workspace2.rs 🔗

@@ -621,8 +621,7 @@ impl Workspace {
                 }
 
                 project2::Event::Closed => {
-                    // todo!()
-                    // cx.remove_window();
+                    cx.remove_window();
                 }
 
                 project2::Event::DeletedEntry(entry_id) => {