Remove `ViewContext::is_child`

Antonio Scandurra created

Change summary

crates/gpui/src/app.rs            | 10 ---
crates/workspace/src/dock.rs      |  6 -
crates/workspace/src/pane.rs      |  2 
crates/workspace/src/workspace.rs | 89 ++++++++++++--------------------
4 files changed, 37 insertions(+), 70 deletions(-)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -2833,16 +2833,6 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
         }
     }
 
-    pub fn is_child(&self, view: impl Into<AnyViewHandle>) -> bool {
-        let view = view.into();
-        if self.window_id != view.window_id {
-            return false;
-        }
-        self.ancestors(view.view_id)
-            .skip(1) // Skip self id
-            .any(|parent| parent == self.view_id)
-    }
-
     pub fn blur(&mut self) {
         let window_id = self.window_id;
         self.window_context.focus(window_id, None);

crates/workspace/src/dock.rs 🔗

@@ -178,11 +178,7 @@ impl Dock {
         pane.update(cx, |pane, cx| {
             pane.set_active(false, cx);
         });
-        let pane_id = pane.id();
-        cx.subscribe(&pane, move |workspace, _, event, cx| {
-            workspace.handle_pane_event(pane_id, event, cx);
-        })
-        .detach();
+        cx.subscribe(&pane, Workspace::handle_pane_event).detach();
 
         Self {
             pane,

crates/workspace/src/pane.rs 🔗

@@ -134,6 +134,7 @@ pub enum Event {
     RemoveItem { item_id: usize },
     Split(SplitDirection),
     ChangeItemTitle,
+    Focus,
 }
 
 pub struct Pane {
@@ -1797,6 +1798,7 @@ impl View for Pane {
     }
 
     fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
+        cx.emit(Event::Focus);
         self.toolbar.update(cx, |toolbar, cx| {
             toolbar.pane_focus_update(true, cx);
         });

crates/workspace/src/workspace.rs 🔗

@@ -64,7 +64,7 @@ use crate::{
     persistence::model::{SerializedPane, SerializedPaneGroup, SerializedWorkspace},
 };
 use lazy_static::lazy_static;
-use log::{error, warn};
+use log::warn;
 use notifications::{NotificationHandle, NotifyResultExt};
 pub use pane::*;
 pub use pane_group::*;
@@ -524,11 +524,7 @@ impl Workspace {
 
         let center_pane = cx
             .add_view(|cx| Pane::new(weak_handle.clone(), None, app_state.background_actions, cx));
-        let pane_id = center_pane.id();
-        cx.subscribe(&center_pane, move |this, _, event, cx| {
-            this.handle_pane_event(pane_id, event, cx)
-        })
-        .detach();
+        cx.subscribe(&center_pane, Self::handle_pane_event).detach();
         cx.focus(&center_pane);
         cx.emit(Event::PaneAdded(center_pane.clone()));
         let dock = Dock::new(
@@ -1420,11 +1416,7 @@ impl Workspace {
                 cx,
             )
         });
-        let pane_id = pane.id();
-        cx.subscribe(&pane, move |this, _, event, cx| {
-            this.handle_pane_event(pane_id, event, cx)
-        })
-        .detach();
+        cx.subscribe(&pane, Self::handle_pane_event).detach();
         self.panes.push(pane.clone());
         cx.focus(&pane);
         cx.emit(Event::PaneAdded(pane.clone()));
@@ -1621,47 +1613,46 @@ impl Workspace {
 
     fn handle_pane_event(
         &mut self,
-        pane_id: usize,
+        pane: ViewHandle<Pane>,
         event: &pane::Event,
         cx: &mut ViewContext<Self>,
     ) {
-        if let Some(pane) = self.pane(pane_id) {
-            let is_dock = &pane == self.dock.pane();
-            match event {
-                pane::Event::Split(direction) if !is_dock => {
-                    self.split_pane(pane, *direction, cx);
+        let is_dock = &pane == self.dock.pane();
+        match event {
+            pane::Event::Split(direction) if !is_dock => {
+                self.split_pane(pane, *direction, cx);
+            }
+            pane::Event::Remove if !is_dock => self.remove_pane(pane, cx),
+            pane::Event::Remove if is_dock => Dock::hide(self, cx),
+            pane::Event::ActivateItem { local } => {
+                if *local {
+                    self.unfollow(&pane, cx);
                 }
-                pane::Event::Remove if !is_dock => self.remove_pane(pane, cx),
-                pane::Event::Remove if is_dock => Dock::hide(self, cx),
-                pane::Event::ActivateItem { local } => {
-                    if *local {
-                        self.unfollow(&pane, cx);
-                    }
-                    if &pane == self.active_pane() {
-                        self.active_item_path_changed(cx);
-                    }
+                if &pane == self.active_pane() {
+                    self.active_item_path_changed(cx);
                 }
-                pane::Event::ChangeItemTitle => {
-                    if pane == self.active_pane {
-                        self.active_item_path_changed(cx);
-                    }
-                    self.update_window_edited(cx);
+            }
+            pane::Event::ChangeItemTitle => {
+                if pane == self.active_pane {
+                    self.active_item_path_changed(cx);
                 }
-                pane::Event::RemoveItem { item_id } => {
-                    self.update_window_edited(cx);
-                    if let hash_map::Entry::Occupied(entry) = self.panes_by_item.entry(*item_id) {
-                        if entry.get().id() == pane.id() {
-                            entry.remove();
-                        }
+                self.update_window_edited(cx);
+            }
+            pane::Event::RemoveItem { item_id } => {
+                self.update_window_edited(cx);
+                if let hash_map::Entry::Occupied(entry) = self.panes_by_item.entry(*item_id) {
+                    if entry.get().id() == pane.id() {
+                        entry.remove();
                     }
                 }
-                _ => {}
             }
-
-            self.serialize_workspace(cx);
-        } else if self.dock.visible_pane().is_none() {
-            error!("pane {} not found", pane_id);
+            pane::Event::Focus => {
+                self.handle_pane_focused(pane.clone(), cx);
+            }
+            _ => {}
         }
+
+        self.serialize_workspace(cx);
     }
 
     pub fn split_pane(
@@ -1760,10 +1751,6 @@ impl Workspace {
         &self.panes
     }
 
-    fn pane(&self, pane_id: usize) -> Option<ViewHandle<Pane>> {
-        self.panes.iter().find(|pane| pane.id() == pane_id).cloned()
-    }
-
     pub fn active_pane(&self) -> &ViewHandle<Pane> {
         &self.active_pane
     }
@@ -2783,17 +2770,9 @@ impl View for Workspace {
             .into_any_named("workspace")
     }
 
-    fn focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {
+    fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
         if cx.is_self_focused() {
             cx.focus(&self.active_pane);
-        } else {
-            for pane in self.panes() {
-                let view = view.clone();
-                if pane.update(cx, |_, cx| view.id() == cx.view_id() || cx.is_child(view)) {
-                    self.handle_pane_focused(pane.clone(), cx);
-                    break;
-                }
-            }
         }
     }