Show a panel/pane as zoomed only if it's the active item in workspace

Antonio Scandurra created

Change summary

crates/gpui/src/app.rs                     |   2 
crates/project_panel/src/project_panel.rs  |  34 ++++-
crates/terminal_view/src/terminal_panel.rs |  20 ++
crates/workspace/src/dock.rs               |  87 +++++++++-----
crates/workspace/src/pane.rs               |   8 
crates/workspace/src/pane_group.rs         |  10 +
crates/workspace/src/workspace.rs          | 143 +++++++++++++----------
7 files changed, 195 insertions(+), 109 deletions(-)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -4224,7 +4224,7 @@ impl<T> Hash for WeakViewHandle<T> {
     }
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub struct AnyWeakViewHandle {
     window_id: usize,
     view_id: usize,

crates/project_panel/src/project_panel.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     keymap_matcher::KeymapContext,
     platform::{CursorStyle, MouseButton, PromptLevel},
     AnyElement, AppContext, ClipboardItem, Element, Entity, ModelHandle, Task, View, ViewContext,
-    ViewHandle, WeakViewHandle,
+    ViewHandle, WeakViewHandle, WindowContext,
 };
 use menu::{Confirm, SelectNext, SelectPrev};
 use project::{Entry, EntryKind, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId};
@@ -48,6 +48,7 @@ pub struct ProjectPanel {
     context_menu: ViewHandle<ContextMenu>,
     dragged_entry_destination: Option<Arc<Path>>,
     workspace: WeakViewHandle<Workspace>,
+    has_focus: bool,
 }
 
 #[derive(Copy, Clone)]
@@ -139,6 +140,7 @@ pub enum Event {
         focus_opened_item: bool,
     },
     DockPositionChanged,
+    Focus,
 }
 
 impl ProjectPanel {
@@ -214,6 +216,7 @@ impl ProjectPanel {
                 context_menu: cx.add_view(|cx| ContextMenu::new(view_id, cx)),
                 dragged_entry_destination: None,
                 workspace: workspace.weak_handle(),
+                has_focus: false,
             };
             this.update_visible_entries(None, cx);
 
@@ -259,7 +262,7 @@ impl ProjectPanel {
                         }
                     }
                 }
-                Event::DockPositionChanged => {}
+                _ => {}
             }
         })
         .detach();
@@ -1338,6 +1341,17 @@ impl View for ProjectPanel {
         Self::reset_to_default_keymap_context(keymap);
         keymap.add_identifier("menu");
     }
+
+    fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
+        if !self.has_focus {
+            self.has_focus = true;
+            cx.emit(Event::Focus);
+        }
+    }
+
+    fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext<Self>) {
+        self.has_focus = false;
+    }
 }
 
 impl Entity for ProjectPanel {
@@ -1345,7 +1359,7 @@ impl Entity for ProjectPanel {
 }
 
 impl workspace::dock::Panel for ProjectPanel {
-    fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
+    fn position(&self, cx: &WindowContext) -> DockPosition {
         let settings = cx.global::<Settings>();
         match settings.project_panel.dock {
             settings::ProjectPanelDockPosition::Left => DockPosition::Left,
@@ -1369,7 +1383,7 @@ impl workspace::dock::Panel for ProjectPanel {
         })
     }
 
-    fn default_size(&self, cx: &gpui::WindowContext) -> f32 {
+    fn default_size(&self, cx: &WindowContext) -> f32 {
         cx.global::<Settings>().project_panel.default_width
     }
 
@@ -1395,13 +1409,21 @@ impl workspace::dock::Panel for ProjectPanel {
         matches!(event, Event::DockPositionChanged)
     }
 
-    fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+    fn should_activate_on_event(_: &Self::Event) -> bool {
         false
     }
 
-    fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+    fn should_close_on_event(_: &Self::Event) -> bool {
         false
     }
+
+    fn has_focus(&self, _: &WindowContext) -> bool {
+        self.has_focus
+    }
+
+    fn is_focus_event(event: &Self::Event) -> bool {
+        matches!(event, Event::Focus)
+    }
 }
 
 impl ClipboardEntry {

crates/terminal_view/src/terminal_panel.rs 🔗

@@ -20,6 +20,7 @@ pub enum Event {
     DockPositionChanged,
     ZoomIn,
     ZoomOut,
+    Focus,
 }
 
 pub struct TerminalPanel {
@@ -100,6 +101,7 @@ impl TerminalPanel {
             pane::Event::Remove => cx.emit(Event::Close),
             pane::Event::ZoomIn => cx.emit(Event::ZoomIn),
             pane::Event::ZoomOut => cx.emit(Event::ZoomOut),
+            pane::Event::Focus => cx.emit(Event::Focus),
             _ => {}
         }
     }
@@ -149,6 +151,10 @@ impl View for TerminalPanel {
         if self.pane.read(cx).items_len() == 0 {
             self.add_terminal(&Default::default(), cx)
         }
+
+        if cx.is_self_focused() {
+            cx.focus(&self.pane);
+        }
     }
 }
 
@@ -211,7 +217,7 @@ impl Panel for TerminalPanel {
         "Terminals".to_string()
     }
 
-    fn icon_label(&self, cx: &AppContext) -> Option<String> {
+    fn icon_label(&self, cx: &WindowContext) -> Option<String> {
         let count = self.pane.read(cx).items_len();
         if count == 0 {
             None
@@ -224,11 +230,19 @@ impl Panel for TerminalPanel {
         matches!(event, Event::DockPositionChanged)
     }
 
-    fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+    fn should_activate_on_event(_: &Self::Event) -> bool {
         false
     }
 
-    fn should_close_on_event(&self, event: &Event, _: &AppContext) -> bool {
+    fn should_close_on_event(event: &Event) -> bool {
         matches!(event, Event::Close)
     }
+
+    fn has_focus(&self, cx: &WindowContext) -> bool {
+        self.pane.read(cx).has_focus()
+    }
+
+    fn is_focus_event(event: &Self::Event) -> bool {
+        matches!(event, Event::Focus)
+    }
 }

crates/workspace/src/dock.rs 🔗

@@ -1,9 +1,8 @@
 use crate::{StatusItemView, Workspace};
 use context_menu::{ContextMenu, ContextMenuItem};
 use gpui::{
-    elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle,
-    AppContext, Axis, Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
-    WindowContext,
+    elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle, Axis,
+    Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
 };
 use serde::Deserialize;
 use settings::Settings;
@@ -16,15 +15,17 @@ pub trait Panel: View {
     fn default_size(&self, cx: &WindowContext) -> f32;
     fn icon_path(&self) -> &'static str;
     fn icon_tooltip(&self) -> String;
-    fn icon_label(&self, _: &AppContext) -> Option<String> {
+    fn icon_label(&self, _: &WindowContext) -> Option<String> {
         None
     }
     fn should_change_position_on_event(_: &Self::Event) -> bool;
     fn should_zoom_in_on_event(_: &Self::Event) -> bool;
     fn should_zoom_out_on_event(_: &Self::Event) -> bool;
     fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>);
-    fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool;
-    fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool;
+    fn should_activate_on_event(_: &Self::Event) -> bool;
+    fn should_close_on_event(_: &Self::Event) -> bool;
+    fn has_focus(&self, cx: &WindowContext) -> bool;
+    fn is_focus_event(_: &Self::Event) -> bool;
 }
 
 pub trait PanelHandle {
@@ -37,7 +38,7 @@ pub trait PanelHandle {
     fn icon_path(&self, cx: &WindowContext) -> &'static str;
     fn icon_tooltip(&self, cx: &WindowContext) -> String;
     fn icon_label(&self, cx: &WindowContext) -> Option<String>;
-    fn is_focused(&self, cx: &WindowContext) -> bool;
+    fn has_focus(&self, cx: &WindowContext) -> bool;
     fn as_any(&self) -> &AnyViewHandle;
 }
 
@@ -81,8 +82,8 @@ where
         self.read(cx).icon_label(cx)
     }
 
-    fn is_focused(&self, cx: &WindowContext) -> bool {
-        ViewHandle::is_focused(self, cx)
+    fn has_focus(&self, cx: &WindowContext) -> bool {
+        self.read(cx).has_focus(cx)
     }
 
     fn as_any(&self) -> &AnyViewHandle {
@@ -170,6 +171,11 @@ impl Dock {
         self.is_open
     }
 
+    pub fn has_focus(&self, cx: &WindowContext) -> bool {
+        self.active_panel()
+            .map_or(false, |panel| panel.has_focus(cx))
+    }
+
     pub fn active_panel_index(&self) -> usize {
         self.active_panel_index
     }
@@ -220,7 +226,7 @@ impl Dock {
         let subscriptions = [
             cx.observe(&panel, |_, _, cx| cx.notify()),
             cx.subscribe(&panel, |this, panel, event, cx| {
-                if panel.read(cx).should_activate_on_event(event, cx) {
+                if T::should_activate_on_event(event) {
                     if let Some(ix) = this
                         .panel_entries
                         .iter()
@@ -230,7 +236,7 @@ impl Dock {
                         this.activate_panel(ix, cx);
                         cx.focus(&panel);
                     }
-                } else if panel.read(cx).should_close_on_event(event, cx)
+                } else if T::should_close_on_event(event)
                     && this.active_panel().map_or(false, |p| p.id() == panel.id())
                 {
                     this.set_open(false, cx);
@@ -302,10 +308,10 @@ impl Dock {
         }
     }
 
-    pub fn zoomed_panel(&self) -> Option<AnyViewHandle> {
+    pub fn zoomed_panel(&self) -> Option<Rc<dyn PanelHandle>> {
         let entry = self.active_entry()?;
         if entry.zoomed {
-            Some(entry.panel.as_any().clone())
+            Some(entry.panel.clone())
         } else {
             None
         }
@@ -344,6 +350,24 @@ impl Dock {
             cx.notify();
         }
     }
+
+    pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> {
+        if let Some(active_entry) = self.active_entry() {
+            let style = &cx.global::<Settings>().theme.workspace.dock;
+            Empty::new()
+                .into_any()
+                .contained()
+                .with_style(style.container)
+                .resizable(
+                    self.position.to_resize_handle_side(),
+                    active_entry.size,
+                    |_, _, _| {},
+                )
+                .into_any()
+        } else {
+            Empty::new().into_any()
+        }
+    }
 }
 
 impl Entity for Dock {
@@ -357,21 +381,16 @@ impl View for Dock {
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
         if let Some(active_entry) = self.active_entry() {
-            if active_entry.zoomed {
-                Empty::new().into_any()
-            } else {
-                let size = self.active_panel_size().unwrap();
-                let style = &cx.global::<Settings>().theme.workspace.dock;
-                ChildView::new(active_entry.panel.as_any(), cx)
-                    .contained()
-                    .with_style(style.container)
-                    .resizable(
-                        self.position.to_resize_handle_side(),
-                        size,
-                        |dock: &mut Self, size, cx| dock.resize_active_panel(size, cx),
-                    )
-                    .into_any()
-            }
+            let style = &cx.global::<Settings>().theme.workspace.dock;
+            ChildView::new(active_entry.panel.as_any(), cx)
+                .contained()
+                .with_style(style.container)
+                .resizable(
+                    self.position.to_resize_handle_side(),
+                    active_entry.size,
+                    |dock: &mut Self, size, cx| dock.resize_active_panel(size, cx),
+                )
+                .into_any()
         } else {
             Empty::new().into_any()
         }
@@ -604,12 +623,20 @@ pub(crate) mod test {
             false
         }
 
-        fn should_activate_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool {
+        fn should_activate_on_event(event: &Self::Event) -> bool {
             matches!(event, TestPanelEvent::Activated)
         }
 
-        fn should_close_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool {
+        fn should_close_on_event(event: &Self::Event) -> bool {
             matches!(event, TestPanelEvent::Closed)
         }
+
+        fn has_focus(&self, _cx: &WindowContext) -> bool {
+            unimplemented!()
+        }
+
+        fn is_focus_event(_: &Self::Event) -> bool {
+            unimplemented!()
+        }
     }
 }

crates/workspace/src/pane.rs 🔗

@@ -1699,7 +1699,11 @@ impl View for Pane {
     }
 
     fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
-        self.has_focus = true;
+        if !self.has_focus {
+            self.has_focus = true;
+            cx.emit(Event::Focus);
+        }
+
         self.toolbar.update(cx, |toolbar, cx| {
             toolbar.pane_focus_update(true, cx);
         });
@@ -1725,8 +1729,6 @@ impl View for Pane {
                     .insert(active_item.id(), focused.downgrade());
             }
         }
-
-        cx.emit(Event::Focus);
     }
 
     fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {

crates/workspace/src/pane_group.rs 🔗

@@ -7,7 +7,7 @@ use gpui::{
     elements::*,
     geometry::{rect::RectF, vector::Vector2F},
     platform::{CursorStyle, MouseButton},
-    Axis, Border, ModelHandle, ViewContext, ViewHandle,
+    AnyViewHandle, Axis, Border, ModelHandle, ViewContext, ViewHandle,
 };
 use project::Project;
 use serde::Deserialize;
@@ -72,6 +72,7 @@ impl PaneGroup {
         follower_states: &FollowerStatesByLeader,
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
+        zoomed: Option<&AnyViewHandle>,
         app_state: &Arc<AppState>,
         cx: &mut ViewContext<Workspace>,
     ) -> AnyElement<Workspace> {
@@ -81,6 +82,7 @@ impl PaneGroup {
             follower_states,
             active_call,
             active_pane,
+            zoomed,
             app_state,
             cx,
         )
@@ -135,6 +137,7 @@ impl Member {
         follower_states: &FollowerStatesByLeader,
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
+        zoomed: Option<&AnyViewHandle>,
         app_state: &Arc<AppState>,
         cx: &mut ViewContext<Workspace>,
     ) -> AnyElement<Workspace> {
@@ -142,7 +145,7 @@ impl Member {
 
         match self {
             Member::Pane(pane) => {
-                let pane_element = if pane.read(cx).is_zoomed() {
+                let pane_element = if Some(&**pane) == zoomed {
                     Empty::new().into_any()
                 } else {
                     ChildView::new(pane, cx).into_any()
@@ -274,6 +277,7 @@ impl Member {
                 follower_states,
                 active_call,
                 active_pane,
+                zoomed,
                 app_state,
                 cx,
             ),
@@ -378,6 +382,7 @@ impl PaneAxis {
         follower_state: &FollowerStatesByLeader,
         active_call: Option<&ModelHandle<ActiveCall>>,
         active_pane: &ViewHandle<Pane>,
+        zoomed: Option<&AnyViewHandle>,
         app_state: &Arc<AppState>,
         cx: &mut ViewContext<Workspace>,
     ) -> AnyElement<Workspace> {
@@ -395,6 +400,7 @@ impl PaneAxis {
                     follower_state,
                     active_call,
                     active_pane,
+                    zoomed,
                     app_state,
                     cx,
                 );

crates/workspace/src/workspace.rs 🔗

@@ -893,6 +893,8 @@ impl Workspace {
                     dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, true, cx));
                 } else if T::should_zoom_out_on_event(event) {
                     this.zoom_out(cx);
+                } else if T::is_focus_event(event) {
+                    cx.notify();
                 }
             }
         })
@@ -1309,16 +1311,42 @@ impl Workspace {
         }
     }
 
-    fn zoomed(&self, cx: &AppContext) -> Option<AnyViewHandle> {
-        self.left_dock
-            .read(cx)
-            .zoomed_panel()
-            .or(self.bottom_dock.read(cx).zoomed_panel())
-            .or(self.right_dock.read(cx).zoomed_panel())
-            .or_else(|| {
-                let pane = self.panes.iter().find(|pane| pane.read(cx).is_zoomed())?;
-                Some(pane.clone().into_any())
-            })
+    fn zoomed(&self, cx: &WindowContext) -> Option<AnyViewHandle> {
+        self.zoomed_panel_for_dock(DockPosition::Left, cx)
+            .or_else(|| self.zoomed_panel_for_dock(DockPosition::Bottom, cx))
+            .or_else(|| self.zoomed_panel_for_dock(DockPosition::Right, cx))
+            .or_else(|| self.zoomed_pane(cx))
+    }
+
+    fn zoomed_panel_for_dock(
+        &self,
+        position: DockPosition,
+        cx: &WindowContext,
+    ) -> Option<AnyViewHandle> {
+        let (dock, other_docks) = match position {
+            DockPosition::Left => (&self.left_dock, [&self.bottom_dock, &self.right_dock]),
+            DockPosition::Bottom => (&self.bottom_dock, [&self.left_dock, &self.right_dock]),
+            DockPosition::Right => (&self.right_dock, [&self.left_dock, &self.bottom_dock]),
+        };
+
+        let zoomed_panel = dock.read(&cx).zoomed_panel()?;
+        if other_docks.iter().all(|dock| !dock.read(cx).has_focus(cx))
+            && !self.active_pane.read(cx).has_focus()
+        {
+            Some(zoomed_panel.as_any().clone())
+        } else {
+            None
+        }
+    }
+
+    fn zoomed_pane(&self, cx: &WindowContext) -> Option<AnyViewHandle> {
+        let active_pane = self.active_pane.read(cx);
+        let docks = [&self.left_dock, &self.bottom_dock, &self.right_dock];
+        if active_pane.is_zoomed() && docks.iter().all(|dock| !dock.read(cx).has_focus(cx)) {
+            Some(self.active_pane.clone().into_any())
+        } else {
+            None
+        }
     }
 
     pub fn items<'a>(
@@ -1433,7 +1461,7 @@ impl Workspace {
         });
 
         if let Some(active_item) = active_item {
-            if active_item.is_focused(cx) {
+            if active_item.has_focus(cx) {
                 cx.focus_self();
             } else {
                 cx.focus(active_item.as_any());
@@ -1464,7 +1492,7 @@ impl Workspace {
             dock.active_panel().cloned()
         });
         if let Some(active_item) = active_item {
-            if active_item.is_focused(cx) {
+            if active_item.has_focus(cx) {
                 cx.focus_self();
             } else {
                 cx.focus(active_item.as_any());
@@ -1663,7 +1691,6 @@ impl Workspace {
             });
             self.active_item_path_changed(cx);
             self.last_active_center_pane = Some(pane.downgrade());
-            cx.notify();
         }
 
         self.update_followers(
@@ -1677,6 +1704,8 @@ impl Workspace {
             }),
             cx,
         );
+
+        cx.notify();
     }
 
     fn handle_pane_event(
@@ -1716,9 +1745,11 @@ impl Workspace {
                 self.handle_pane_focused(pane.clone(), cx);
             }
             pane::Event::ZoomIn => {
-                self.zoom_out(cx);
-                pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
-                cx.notify();
+                if pane == self.active_pane {
+                    self.zoom_out(cx);
+                    pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
+                    cx.notify();
+                }
             }
             pane::Event::ZoomOut => self.zoom_out(cx),
         }
@@ -2646,6 +2677,33 @@ impl Workspace {
         });
         Self::new(None, 0, project, app_state, cx)
     }
+
+    fn render_dock(&self, position: DockPosition, cx: &WindowContext) -> Option<AnyElement<Self>> {
+        let dock = match position {
+            DockPosition::Left => &self.left_dock,
+            DockPosition::Right => &self.right_dock,
+            DockPosition::Bottom => &self.bottom_dock,
+        };
+        let active_panel = dock.read(cx).active_panel()?;
+        let element = if Some(active_panel.as_any()) == self.zoomed(cx).as_ref() {
+            dock.read(cx).render_placeholder(cx)
+        } else {
+            ChildView::new(dock, cx).into_any()
+        };
+
+        Some(
+            element
+                .constrained()
+                .dynamically(move |constraint, _, cx| match position {
+                    DockPosition::Left | DockPosition::Right => SizeConstraint::new(
+                        Vector2F::new(20., constraint.min.y()),
+                        Vector2F::new(cx.window_size().x() * 0.8, constraint.max.y()),
+                    ),
+                    _ => constraint,
+                })
+                .into_any(),
+        )
+    }
 }
 
 fn notify_if_database_failed(workspace: &WeakViewHandle<Workspace>, cx: &mut AsyncAppContext) {
@@ -2702,25 +2760,7 @@ impl View for Workspace {
                             .with_child({
                                 let project = self.project.clone();
                                 Flex::row()
-                                    .with_children(
-                                        if self.left_dock.read(cx).active_panel().is_some() {
-                                            Some(
-                                                ChildView::new(&self.left_dock, cx)
-                                                    .constrained()
-                                                    .dynamically(|constraint, _, cx| {
-                                                        SizeConstraint::new(
-                                                            Vector2F::new(20., constraint.min.y()),
-                                                            Vector2F::new(
-                                                                cx.window_size().x() * 0.8,
-                                                                constraint.max.y(),
-                                                            ),
-                                                        )
-                                                    }),
-                                            )
-                                        } else {
-                                            None
-                                        },
-                                    )
+                                    .with_children(self.render_dock(DockPosition::Left, cx))
                                     .with_child(
                                         Flex::column()
                                             .with_child(
@@ -2730,44 +2770,18 @@ impl View for Workspace {
                                                     &self.follower_states_by_leader,
                                                     self.active_call(),
                                                     self.active_pane(),
+                                                    self.zoomed(cx).as_ref(),
                                                     &self.app_state,
                                                     cx,
                                                 ))
                                                 .flex(1., true),
                                             )
                                             .with_children(
-                                                if self
-                                                    .bottom_dock
-                                                    .read(cx)
-                                                    .active_panel()
-                                                    .is_some()
-                                                {
-                                                    Some(ChildView::new(&self.bottom_dock, cx))
-                                                } else {
-                                                    None
-                                                },
+                                                self.render_dock(DockPosition::Bottom, cx),
                                             )
                                             .flex(1., true),
                                     )
-                                    .with_children(
-                                        if self.right_dock.read(cx).active_panel().is_some() {
-                                            Some(
-                                                ChildView::new(&self.right_dock, cx)
-                                                    .constrained()
-                                                    .dynamically(|constraint, _, cx| {
-                                                        SizeConstraint::new(
-                                                            Vector2F::new(20., constraint.min.y()),
-                                                            Vector2F::new(
-                                                                cx.window_size().x() * 0.8,
-                                                                constraint.max.y(),
-                                                            ),
-                                                        )
-                                                    }),
-                                            )
-                                        } else {
-                                            None
-                                        },
-                                    )
+                                    .with_children(self.render_dock(DockPosition::Right, cx))
                             })
                             .with_child(Overlay::new(
                                 Stack::new()
@@ -2810,6 +2824,7 @@ impl View for Workspace {
         if cx.is_self_focused() {
             cx.focus(&self.active_pane);
         }
+        cx.notify();
     }
 }