Fix `Presenter` leak when removing windows

Antonio Scandurra created

Change summary

crates/chat_panel/src/chat_panel.rs | 8 ++++++--
crates/gpui/src/app.rs              | 2 ++
2 files changed, 8 insertions(+), 2 deletions(-)

Detailed changes

crates/chat_panel/src/chat_panel.rs 🔗

@@ -101,11 +101,15 @@ impl ChatPanel {
                 cx.dispatch_action(LoadMoreMessages);
             }
         });
-        let _observe_status = cx.spawn(|this, mut cx| {
+        let _observe_status = cx.spawn_weak(|this, mut cx| {
             let mut status = rpc.status();
             async move {
                 while let Some(_) = status.recv().await {
-                    this.update(&mut cx, |_, cx| cx.notify());
+                    if let Some(this) = this.upgrade(&cx) {
+                        this.update(&mut cx, |_, cx| cx.notify());
+                    } else {
+                        break;
+                    }
                 }
             }
         });

crates/gpui/src/app.rs 🔗

@@ -852,6 +852,7 @@ impl MutableAppContext {
     pub fn remove_all_windows(&mut self) {
         for (window_id, _) in self.cx.windows.drain() {
             self.presenters_and_platform_windows.remove(&window_id);
+            self.debug_elements_callbacks.remove(&window_id);
         }
         self.flush_effects();
     }
@@ -1403,6 +1404,7 @@ impl MutableAppContext {
     pub fn remove_window(&mut self, window_id: usize) {
         self.cx.windows.remove(&window_id);
         self.presenters_and_platform_windows.remove(&window_id);
+        self.debug_elements_callbacks.remove(&window_id);
         self.flush_effects();
     }