Avoid holding a potentially-stale reference to drawer's focus handle

Max Brunsfeld created

Change summary

crates/workspace/src/workspace.rs | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)

Detailed changes

crates/workspace/src/workspace.rs 🔗

@@ -7012,8 +7012,7 @@ impl Workspace {
         view: Entity<V>,
         cx: &mut Context<Self>,
     ) {
-        let focus_handle = view.focus_handle(cx);
-        self.left_drawer = Some(Drawer::new(view.into(), focus_handle));
+        self.left_drawer = Some(Drawer::new(view));
         cx.notify();
     }
 
@@ -7022,8 +7021,7 @@ impl Workspace {
         view: Entity<V>,
         cx: &mut Context<Self>,
     ) {
-        let focus_handle = view.focus_handle(cx);
-        self.right_drawer = Some(Drawer::new(view.into(), focus_handle));
+        self.right_drawer = Some(Drawer::new(view));
         cx.notify();
     }
 
@@ -7282,8 +7280,9 @@ impl Workspace {
             }
         };
 
+        let focus_handle = drawer.focus_handle(cx);
         let base = div()
-            .track_focus(&drawer.focus_handle)
+            .track_focus(&focus_handle)
             .flex()
             .flex_col()
             .overflow_hidden()
@@ -7921,20 +7920,25 @@ pub enum DrawerPosition {
 
 pub struct Drawer {
     view: AnyView,
-    focus_handle: FocusHandle,
+    focus_handle_fn: Box<dyn Fn(&App) -> FocusHandle>,
     open: bool,
     custom_width: Option<Pixels>,
 }
 
 impl Drawer {
-    fn new(view: AnyView, focus_handle: FocusHandle) -> Self {
+    fn new<V: Render + Focusable + 'static>(view: Entity<V>) -> Self {
+        let entity = view.clone();
         Self {
-            view,
-            focus_handle,
+            view: view.into(),
+            focus_handle_fn: Box::new(move |cx| entity.focus_handle(cx)),
             open: true,
             custom_width: None,
         }
     }
+
+    fn focus_handle(&self, cx: &App) -> FocusHandle {
+        (self.focus_handle_fn)(cx)
+    }
 }
 
 #[derive(Clone)]