Merge pull request #1963 from zed-industries/fix-workspace-corner-cases

Mikayla Maki created

Fix small workspace deserialization corner cases

Change summary

crates/workspace/src/persistence.rs       |  6 +++---
crates/workspace/src/persistence/model.rs |  8 ++++++--
crates/workspace/src/workspace.rs         | 23 +++++++++++++++++------
3 files changed, 26 insertions(+), 11 deletions(-)

Detailed changes

crates/workspace/src/persistence.rs 🔗

@@ -210,10 +210,10 @@ impl WorkspaceDb {
     }
 
     fn get_center_pane_group(&self, workspace_id: WorkspaceId) -> Result<SerializedPaneGroup> {
-        self.get_pane_group(workspace_id, None)?
+        Ok(self.get_pane_group(workspace_id, None)?
             .into_iter()
             .next()
-            .context("No center pane group")
+            .unwrap_or_else(|| SerializedPaneGroup::Pane(SerializedPane { active: true, children: vec![] })))
     }
 
     fn get_pane_group(
@@ -267,7 +267,7 @@ impl WorkspaceDb {
         // Filter out panes and pane groups which don't have any children or items
         .filter(|pane_group| match pane_group {
             Ok(SerializedPaneGroup::Group { children, .. }) => !children.is_empty(),
-            Ok(SerializedPaneGroup::Pane(pane)) => !pane.children.is_empty(),
+            Ok(SerializedPaneGroup::Pane(pane)) => !pane.children.is_empty(), 
             _ => true,
         })
         .collect::<Result<_>>()

crates/workspace/src/persistence/model.rs 🔗

@@ -106,7 +106,6 @@ impl SerializedPaneGroup {
                         .await
                     {
                         members.push(new_member);
-
                         current_active_pane = current_active_pane.or(active_pane);
                     }
                 }
@@ -115,6 +114,10 @@ impl SerializedPaneGroup {
                     return None;
                 }
 
+                if members.len() == 1 {
+                    return Some((members.remove(0), current_active_pane));
+                }
+
                 Some((
                     Member::Axis(PaneAxis {
                         axis: *axis,
@@ -130,9 +133,10 @@ impl SerializedPaneGroup {
                     .deserialize_to(project, &pane, workspace_id, workspace, cx)
                     .await;
 
-                if pane.read_with(cx, |pane, _| pane.items().next().is_some()) {
+                if pane.read_with(cx, |pane, _| pane.items_len() != 0) {
                     Some((Member::Pane(pane.clone()), active.then(|| pane)))
                 } else {
+                    workspace.update(cx, |workspace, cx| workspace.remove_pane(pane, cx));
                     None
                 }
             }

crates/workspace/src/workspace.rs 🔗

@@ -2300,6 +2300,9 @@ impl Workspace {
         }
 
         if let Some(location) = self.location(cx) {
+            // Load bearing special case:
+            //  - with_local_workspace() relies on this to not have other stuff open
+            //    when you open your log
             if !location.paths().is_empty() {
                 let dock_pane = serialize_pane_handle(self.dock.pane(), cx);
                 let center_group = build_serialized_pane_group(&self.center.root, cx);
@@ -2327,9 +2330,14 @@ impl Workspace {
     ) {
         cx.spawn(|mut cx| async move {
             if let Some(workspace) = workspace.upgrade(&cx) {
-                let (project, dock_pane_handle) = workspace.read_with(&cx, |workspace, _| {
-                    (workspace.project().clone(), workspace.dock_pane().clone())
-                });
+                let (project, dock_pane_handle, old_center_pane) =
+                    workspace.read_with(&cx, |workspace, _| {
+                        (
+                            workspace.project().clone(),
+                            workspace.dock_pane().clone(),
+                            workspace.last_active_center_pane.clone(),
+                        )
+                    });
 
                 serialized_workspace
                     .dock_pane
@@ -2365,11 +2373,14 @@ impl Workspace {
                             cx.focus(workspace.panes.last().unwrap().clone());
                         }
                     } else {
-                        cx.focus_self();
+                        let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade(cx));
+                        if let Some(old_center_handle) = old_center_handle {
+                            cx.focus(old_center_handle)
+                        } else {
+                            cx.focus_self()
+                        }
                     }
 
-                    // Note, if this is moved after 'set_dock_position'
-                    // it causes an infinite loop.
                     if workspace.left_sidebar().read(cx).is_open()
                         != serialized_workspace.left_sidebar_open
                     {