Remove all windows before quitting

Antonio Scandurra created

This gives all entities a chance of running `Drop::drop` which,
in turn, could cause them to spawn a critical task. For example,
we use this capability when a language server is dropped and we
need to asynchronously send a shutdown message.

Change summary

crates/gpui/src/app.rs | 7 +++++++
crates/zed/src/main.rs | 1 +
2 files changed, 8 insertions(+)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -1230,6 +1230,13 @@ impl MutableAppContext {
         self.remove_dropped_entities();
     }
 
+    pub fn remove_all_windows(&mut self) {
+        for (window_id, _) in self.cx.windows.drain() {
+            self.presenters_and_platform_windows.remove(&window_id);
+        }
+        self.remove_dropped_entities();
+    }
+
     fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
         let mut window =
             self.cx

crates/zed/src/main.rs 🔗

@@ -30,6 +30,7 @@ fn main() {
     languages.set_theme(&settings.borrow().theme.editor.syntax);
 
     app.on_quit(|cx| {
+        cx.remove_all_windows();
         let did_finish = cx
             .background()
             .block_on_critical_tasks(Duration::from_millis(100));