From 36a8bbfd43128e67b376a107f0210e571bd7bb07 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 22 Jan 2024 12:28:42 -0700 Subject: [PATCH] Fix panel deserialization In the old world, panel loading happened strictly before workspace deserialization. Now it's inverted. Fix this by storing on the dock the serialized state so they can restore state as panels are loaded. --- crates/workspace/src/dock.rs | 19 +++++++++ crates/workspace/src/workspace.rs | 66 +++++++++++-------------------- crates/zed/src/zed.rs | 9 ++--- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 4ae408993572e06e97635f8fb579fbee1395238b..a649b441a60ccdce6470eb449fb704ef3708d376 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -1,3 +1,4 @@ +use crate::persistence::model::DockData; use crate::DraggedDock; use crate::{status_bar::StatusItemView, Workspace}; use gpui::{ @@ -141,6 +142,7 @@ pub struct Dock { is_open: bool, active_panel_index: usize, focus_handle: FocusHandle, + pub(crate) serialized_dock: Option, _focus_subscription: Subscription, } @@ -201,6 +203,7 @@ impl Dock { is_open: false, focus_handle: focus_handle.clone(), _focus_subscription: focus_subscription, + serialized_dock: None, } }); @@ -408,10 +411,26 @@ impl Dock { }), ]; + let name = panel.persistent_name().to_string(); + self.panel_entries.push(PanelEntry { panel: Arc::new(panel), _subscriptions: subscriptions, }); + if let Some(serialized) = self.serialized_dock.clone() { + if serialized.active_panel == Some(name) { + self.activate_panel(self.panel_entries.len() - 1, cx); + if serialized.visible { + self.set_open(true, cx); + } + if serialized.zoom { + if let Some(panel) = self.active_panel() { + panel.set_zoomed(true, cx) + }; + } + } + } + cx.notify() } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d10cef0c0f41ec18a513bbae5d478c3ff0deb3ac..2a00acc0e6e9b4e7e742d60643f14ce50c8ea1c1 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1681,6 +1681,18 @@ impl Workspace { None } + /// Open the panel of the given type + pub fn open_panel(&mut self, cx: &mut ViewContext) { + for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] { + if let Some(panel_index) = dock.read(cx).panel_index_for_type::() { + dock.update(cx, |dock, cx| { + dock.activate_panel(panel_index, cx); + dock.set_open(true, cx); + }); + } + } + } + pub fn panel(&self, cx: &WindowContext) -> Option> { for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] { let dock = dock.read(cx); @@ -3175,49 +3187,19 @@ impl Workspace { } let docks = serialized_workspace.docks; - workspace.left_dock.update(cx, |dock, cx| { - dock.set_open(docks.left.visible, cx); - if let Some(active_panel) = docks.left.active_panel { - if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) { - dock.activate_panel(ix, cx); - } - } - dock.active_panel() - .map(|panel| panel.set_zoomed(docks.left.zoom, cx)); - if docks.left.visible && docks.left.zoom { - cx.focus_self() - } - }); - // TODO: I think the bug is that setting zoom or active undoes the bottom zoom or something - workspace.right_dock.update(cx, |dock, cx| { - dock.set_open(docks.right.visible, cx); - if let Some(active_panel) = docks.right.active_panel { - if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) { - dock.activate_panel(ix, cx); - } - } - dock.active_panel() - .map(|panel| panel.set_zoomed(docks.right.zoom, cx)); - - if docks.right.visible && docks.right.zoom { - cx.focus_self() - } - }); - workspace.bottom_dock.update(cx, |dock, cx| { - dock.set_open(docks.bottom.visible, cx); - if let Some(active_panel) = docks.bottom.active_panel { - if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) { - dock.activate_panel(ix, cx); - } - } - dock.active_panel() - .map(|panel| panel.set_zoomed(docks.bottom.zoom, cx)); - - if docks.bottom.visible && docks.bottom.zoom { - cx.focus_self() - } - }); + let right = docks.right.clone(); + workspace + .right_dock + .update(cx, |dock, _| dock.serialized_dock = Some(right)); + let left = docks.left.clone(); + workspace + .left_dock + .update(cx, |dock, _| dock.serialized_dock = Some(left)); + let bottom = docks.bottom.clone(); + workspace + .bottom_dock + .update(cx, |dock, _| dock.serialized_dock = Some(bottom)); cx.notify(); })?; diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 8010f3c1b9a512bbfa1d370372f750bb21d5ea61..e2b64a1c9362a672175577de6568990e1064ab7f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -32,11 +32,11 @@ use util::{ }; use uuid::Uuid; use welcome::BaseKeymap; +use workspace::Pane; use workspace::{ create_and_open_local_file, notifications::simple_message_notification::MessageNotification, open_new, AppState, NewFile, NewWindow, Workspace, WorkspaceSettings, }; -use workspace::{dock::Panel, Pane}; use zed_actions::{OpenBrowser, OpenSettings, OpenZedURL, Quit}; actions!( @@ -178,10 +178,7 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { )?; workspace_handle.update(&mut cx, |workspace, cx| { - let (position, was_deserialized) = { - let project_panel = project_panel.read(cx); - (project_panel.position(cx), project_panel.was_deserialized()) - }; + let was_deserialized = project_panel.read(cx).was_deserialized(); workspace.add_panel(project_panel, cx); workspace.add_panel(terminal_panel, cx); workspace.add_panel(assistant_panel, cx); @@ -200,7 +197,7 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { .map_or(false, |entry| entry.is_dir()) }) { - workspace.toggle_dock(position, cx); + workspace.open_panel::(cx); } cx.focus_self(); })