mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
workspace: Persist dock state for empty workspaces (#45966)
Closes #4568 Release Notes: - Fixed project-less workspaces not persisting their dock state Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
parent
5e9ca9cf77
commit
d6bd3661e2
3 changed files with 67 additions and 3 deletions
|
|
@ -281,6 +281,25 @@ impl From<WindowBoundsJson> for WindowBounds {
|
|||
}
|
||||
}
|
||||
|
||||
const DEFAULT_DOCK_STATE_KEY: &str = "default_dock_state";
|
||||
|
||||
pub fn read_default_dock_state() -> Option<DockStructure> {
|
||||
let json_str = KEY_VALUE_STORE
|
||||
.read_kvp(DEFAULT_DOCK_STATE_KEY)
|
||||
.log_err()
|
||||
.flatten()?;
|
||||
|
||||
serde_json::from_str::<DockStructure>(&json_str).ok()
|
||||
}
|
||||
|
||||
pub async fn write_default_dock_state(docks: DockStructure) -> anyhow::Result<()> {
|
||||
let json_str = serde_json::to_string(&docks)?;
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(DEFAULT_DOCK_STATE_KEY.to_string(), json_str)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Breakpoint {
|
||||
pub position: u32,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use gpui::{AsyncWindowContext, Entity, WeakEntity};
|
|||
use language::{Toolchain, ToolchainScope};
|
||||
use project::{Project, debugger::breakpoint_store::SourceBreakpoint};
|
||||
use remote::RemoteConnectionOptions;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
path::{Path, PathBuf},
|
||||
|
|
@ -64,7 +65,7 @@ pub(crate) struct SerializedWorkspace {
|
|||
pub(crate) window_id: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct DockStructure {
|
||||
pub(crate) left: DockData,
|
||||
pub(crate) right: DockData,
|
||||
|
|
@ -114,7 +115,7 @@ impl Bind for DockStructure {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct DockData {
|
||||
pub(crate) visible: bool,
|
||||
pub(crate) active_panel: Option<String>,
|
||||
|
|
|
|||
|
|
@ -1823,6 +1823,15 @@ impl Workspace {
|
|||
};
|
||||
|
||||
notify_if_database_failed(window, cx);
|
||||
// Check if this is an empty workspace (no paths to open)
|
||||
// An empty workspace is one where project_paths is empty
|
||||
let is_empty_workspace = project_paths.is_empty();
|
||||
// Check if serialized workspace has paths before it's moved
|
||||
let serialized_workspace_has_paths = serialized_workspace
|
||||
.as_ref()
|
||||
.map(|ws| !ws.paths.is_empty())
|
||||
.unwrap_or(false);
|
||||
|
||||
let opened_items = window
|
||||
.update(cx, |_workspace, window, cx| {
|
||||
open_items(serialized_workspace, project_paths, window, cx)
|
||||
|
|
@ -1830,6 +1839,32 @@ impl Workspace {
|
|||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
// Restore default dock state for empty workspaces
|
||||
// Only restore if:
|
||||
// 1. This is an empty workspace (no paths), AND
|
||||
// 2. The serialized workspace either doesn't exist or has no paths
|
||||
if is_empty_workspace && !serialized_workspace_has_paths {
|
||||
if let Some(default_docks) = persistence::read_default_dock_state() {
|
||||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
for (dock, serialized_dock) in [
|
||||
(&mut workspace.right_dock, default_docks.right),
|
||||
(&mut workspace.left_dock, default_docks.left),
|
||||
(&mut workspace.bottom_dock, default_docks.bottom),
|
||||
]
|
||||
.iter_mut()
|
||||
{
|
||||
dock.update(cx, |dock, cx| {
|
||||
dock.serialized_dock = Some(serialized_dock.clone());
|
||||
dock.restore_state(window, cx);
|
||||
});
|
||||
}
|
||||
cx.notify();
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
|
||||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
window.activate_window();
|
||||
|
|
@ -5858,6 +5893,8 @@ impl Workspace {
|
|||
WorkspaceLocation::DetachFromSession => {
|
||||
let window_bounds = SerializedWindowBounds(window.window_bounds());
|
||||
let display = window.display(cx).and_then(|d| d.uuid().ok());
|
||||
// Save dock state for empty local workspaces
|
||||
let docks = build_serialized_docks(self, window, cx);
|
||||
window.spawn(cx, async move |_| {
|
||||
persistence::DB
|
||||
.set_window_open_status(
|
||||
|
|
@ -5871,9 +5908,16 @@ impl Workspace {
|
|||
.set_session_id(database_id, None)
|
||||
.await
|
||||
.log_err();
|
||||
persistence::write_default_dock_state(docks).await.log_err();
|
||||
})
|
||||
}
|
||||
WorkspaceLocation::None => {
|
||||
// Save dock state for empty non-local workspaces
|
||||
let docks = build_serialized_docks(self, window, cx);
|
||||
window.spawn(cx, async move |_| {
|
||||
persistence::write_default_dock_state(docks).await.log_err();
|
||||
})
|
||||
}
|
||||
WorkspaceLocation::None => Task::ready(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue