Hold a weak handle to `Presenter` when dispatching events

Antonio Scandurra created

This ensures that the only strong reference to the presenter is held
by `App`. This is important because we want to call `flush_effects`
when removing a window and implicit drops of the `Presenter` would
make that hard.

Before this commit, if a rendered view contained strong handles to
views and models, we would only drop them on the next `flush_effects`.
This was manifesting itself in `Project`s not being released when
closing their containing window.

Change summary

crates/gpui/src/app.rs | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -1635,20 +1635,22 @@ impl MutableAppContext {
 
         {
             let mut app = self.upgrade();
-            let presenter = presenter.clone();
+            let presenter = Rc::downgrade(&presenter);
             window.on_event(Box::new(move |event| {
                 app.update(|cx| {
-                    if let Event::KeyDown { keystroke, .. } = &event {
-                        if cx.dispatch_keystroke(
-                            window_id,
-                            presenter.borrow().dispatch_path(cx.as_ref()),
-                            keystroke,
-                        ) {
-                            return;
+                    if let Some(presenter) = presenter.upgrade() {
+                        if let Event::KeyDown { keystroke, .. } = &event {
+                            if cx.dispatch_keystroke(
+                                window_id,
+                                presenter.borrow().dispatch_path(cx.as_ref()),
+                                keystroke,
+                            ) {
+                                return;
+                            }
                         }
-                    }
 
-                    presenter.borrow_mut().dispatch_event(event, cx);
+                        presenter.borrow_mut().dispatch_event(event, cx);
+                    }
                 })
             }));
         }