Fix project panel being toggled on workspace startup. (#4059)

Piotr Osiewicz created

A sequence of events: Launch Zed -> Quit Zed -> Launch Zed would leave
you with a project panel in a a different state on each open (e.g. if it
is open on 1st one, 2nd run will have it closed). We were essentially
not tracking whether the deserialization took place.

Release Notes:

- Fixed project panel being toggled on/off on startup due to incorrect
tracking of serialization state (solves
https://github.com/zed-industries/community/issues/2406)

Change summary

crates/project_panel/src/project_panel.rs |  6 ++++++
crates/zed/src/zed.rs                     | 24 ++++++++++++++----------
2 files changed, 20 insertions(+), 10 deletions(-)

Detailed changes

crates/project_panel/src/project_panel.rs 🔗

@@ -58,6 +58,7 @@ pub struct ProjectPanel {
     workspace: WeakView<Workspace>,
     width: Option<Pixels>,
     pending_serialization: Task<Option<()>>,
+    was_deserialized: bool,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -243,6 +244,7 @@ impl ProjectPanel {
                 workspace: workspace.weak_handle(),
                 width: None,
                 pending_serialization: Task::ready(None),
+                was_deserialized: false,
             };
             this.update_visible_entries(None, cx);
 
@@ -322,6 +324,7 @@ impl ProjectPanel {
             if let Some(serialized_panel) = serialized_panel {
                 panel.update(cx, |panel, cx| {
                     panel.width = serialized_panel.width;
+                    panel.was_deserialized = true;
                     cx.notify();
                 });
             }
@@ -1465,6 +1468,9 @@ impl ProjectPanel {
             cx.notify();
         }
     }
+    pub fn was_deserialized(&self) -> bool {
+        self.was_deserialized
+    }
 }
 
 impl Render for ProjectPanel {

crates/zed/src/zed.rs 🔗

@@ -178,7 +178,10 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
             )?;
 
             workspace_handle.update(&mut cx, |workspace, cx| {
-                let position = project_panel.read(cx).position(cx);
+                let (position, was_deserialized) = {
+                    let project_panel = project_panel.read(cx);
+                    (project_panel.position(cx), project_panel.was_deserialized())
+                };
                 workspace.add_panel(project_panel, cx);
                 workspace.add_panel(terminal_panel, cx);
                 workspace.add_panel(assistant_panel, cx);
@@ -186,15 +189,16 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
                 workspace.add_panel(chat_panel, cx);
                 workspace.add_panel(notification_panel, cx);
 
-                if workspace
-                    .project()
-                    .read(cx)
-                    .visible_worktrees(cx)
-                    .any(|tree| {
-                        tree.read(cx)
-                            .root_entry()
-                            .map_or(false, |entry| entry.is_dir())
-                    })
+                if !was_deserialized
+                    && workspace
+                        .project()
+                        .read(cx)
+                        .visible_worktrees(cx)
+                        .any(|tree| {
+                            tree.read(cx)
+                                .root_entry()
+                                .map_or(false, |entry| entry.is_dir())
+                        })
                 {
                     workspace.toggle_dock(position, cx);
                 }