Maintain workspace's zoom state when opening/closing docks, activating panels

Max Brunsfeld created

Change summary

crates/workspace2/src/dock.rs       | 46 ++++++++++++++++++++++--------
crates/workspace2/src/workspace2.rs | 12 ++------
2 files changed, 37 insertions(+), 21 deletions(-)

Detailed changes

crates/workspace2/src/dock.rs 🔗

@@ -192,21 +192,43 @@ pub struct PanelButtons {
 }
 
 impl Dock {
-    pub fn new(position: DockPosition, cx: &mut ViewContext<'_, Self>) -> Self {
+    pub fn new(position: DockPosition, cx: &mut ViewContext<Workspace>) -> View<Self> {
         let focus_handle = cx.focus_handle();
-        let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
-            if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
-                active_entry.panel.focus_handle(cx).focus(cx)
+
+        let dock = cx.build_view(|cx: &mut ViewContext<Self>| {
+            let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
+                if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
+                    active_entry.panel.focus_handle(cx).focus(cx)
+                }
+            });
+            Self {
+                position,
+                panel_entries: Default::default(),
+                active_panel_index: 0,
+                is_open: false,
+                focus_handle: focus_handle.clone(),
+                _focus_subscription: focus_subscription,
             }
         });
-        Self {
-            position,
-            panel_entries: Default::default(),
-            active_panel_index: 0,
-            is_open: false,
-            focus_handle,
-            _focus_subscription: focus_subscription,
-        }
+
+        cx.observe(&dock, move |workspace, dock, cx| {
+            if dock.read(cx).is_open() {
+                if let Some(panel) = dock.read(cx).active_panel() {
+                    if panel.is_zoomed(cx) {
+                        workspace.zoomed = Some(panel.to_any().downgrade());
+                        workspace.zoomed_position = Some(position);
+                        return;
+                    }
+                }
+            }
+            if workspace.zoomed_position == Some(position) {
+                workspace.zoomed = None;
+                workspace.zoomed_position = None;
+            }
+        })
+        .detach();
+
+        dock
     }
 
     pub fn position(&self) -> DockPosition {

crates/workspace2/src/workspace2.rs 🔗

@@ -586,9 +586,9 @@ impl Workspace {
 
         cx.emit(Event::WorkspaceCreated(weak_handle.clone()));
 
-        let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx));
-        let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx));
-        let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx));
+        let left_dock = Dock::new(DockPosition::Left, cx);
+        let bottom_dock = Dock::new(DockPosition::Bottom, cx);
+        let right_dock = Dock::new(DockPosition::Right, cx);
         let left_dock_buttons = cx.build_view(|cx| PanelButtons::new(left_dock.clone(), cx));
         let bottom_dock_buttons = cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), cx));
         let right_dock_buttons = cx.build_view(|cx| PanelButtons::new(right_dock.clone(), cx));
@@ -1616,7 +1616,6 @@ impl Workspace {
         for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
             if let Some(panel_index) = dock.read(cx).panel_index_for_type::<T>() {
                 let mut focus_center = false;
-                let mut reveal_dock = false;
                 let panel = dock.update(cx, |dock, cx| {
                     dock.activate_panel(panel_index, cx);
 
@@ -1625,12 +1624,7 @@ impl Workspace {
                         if should_focus(&**panel, cx) {
                             dock.set_open(true, cx);
                             panel.focus_handle(cx).focus(cx);
-                            reveal_dock = true;
                         } else {
-                            // todo!()
-                            // if panel.is_zoomed(cx) {
-                            //     dock.set_open(false, cx);
-                            // }
                             focus_center = true;
                         }
                     }