Fix panic on quit

Conrad Irwin created

Change summary

crates/gpui2/src/platform/mac/window.rs |  3 +++
crates/gpui2/src/window.rs              |  7 +++++++
crates/zed2/src/zed2.rs                 | 17 +++++++++++------
3 files changed, 21 insertions(+), 6 deletions(-)

Detailed changes

crates/gpui2/src/platform/mac/window.rs 🔗

@@ -683,6 +683,9 @@ impl Drop for MacWindow {
         this.executor
             .spawn(async move {
                 unsafe {
+                    // todo!() this panic()s when you click the red close button
+                    // unless should_close returns false.
+                    // (luckliy in zed it always returns false)
                     window.close();
                 }
             })

crates/gpui2/src/window.rs 🔗

@@ -1517,6 +1517,13 @@ impl<'a> WindowContext<'a> {
                 .set_input_handler(Box::new(input_handler));
         }
     }
+
+    pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
+        let mut this = self.to_async();
+        self.window
+            .platform_window
+            .on_should_close(Box::new(move || this.update(|_, cx| f(cx)).unwrap_or(true)))
+    }
 }
 
 impl Context for WindowContext<'_> {

crates/zed2/src/zed2.rs 🔗

@@ -166,12 +166,17 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
 
         //     vim::observe_keystrokes(cx);
 
-        //     cx.on_window_should_close(|workspace, cx| {
-        //         if let Some(task) = workspace.close(&Default::default(), cx) {
-        //             task.detach_and_log_err(cx);
-        //         }
-        //         false
-        //     });
+        let handle = cx.view().downgrade();
+        cx.on_window_should_close(move |cx| {
+            handle
+                .update(cx, |workspace, cx| {
+                    if let Some(task) = workspace.close(&Default::default(), cx) {
+                        task.detach_and_log_err(cx);
+                    }
+                    false
+                })
+                .unwrap_or(true)
+        });
 
         cx.spawn(|workspace_handle, mut cx| async move {
             let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());