workspace: Fix last removed folder from workspace used to reopen on Zed startup (#34925)
Closes #34924 Now, when `local_paths` are empty, we detach `session_id` from that workspace serialization item. This way, when we restore it using the default "last_session", we don't restore this workspace back. This is same as when we use `cmd-w` to close window, which also sets `session_id` to `None` before serialization. Release Notes: - Fixed an issue where last removed folder from workspace used to reopen on Zed startup.
This commit is contained in:
parent
056003860a
commit
e90cf0b941
2 changed files with 61 additions and 34 deletions
|
@ -1336,6 +1336,14 @@ impl WorkspaceDb {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query! {
|
||||||
|
pub(crate) async fn set_session_id(workspace_id: WorkspaceId, session_id: Option<String>) -> Result<()> {
|
||||||
|
UPDATE workspaces
|
||||||
|
SET session_id = ?2
|
||||||
|
WHERE workspace_id = ?1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn toolchain(
|
pub async fn toolchain(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
|
|
|
@ -1016,6 +1016,15 @@ pub enum OpenVisible {
|
||||||
OnlyDirectories,
|
OnlyDirectories,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum WorkspaceLocation {
|
||||||
|
// Valid local paths or SSH project to serialize
|
||||||
|
Location(SerializedWorkspaceLocation),
|
||||||
|
// No valid location found hence clear session id
|
||||||
|
DetachFromSession,
|
||||||
|
// No valid location found to serialize
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
type PromptForNewPath = Box<
|
type PromptForNewPath = Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&mut Workspace,
|
&mut Workspace,
|
||||||
|
@ -1135,7 +1144,6 @@ impl Workspace {
|
||||||
this.update_window_title(window, cx);
|
this.update_window_title(window, cx);
|
||||||
this.serialize_workspace(window, cx);
|
this.serialize_workspace(window, cx);
|
||||||
// This event could be triggered by `AddFolderToProject` or `RemoveFromProject`.
|
// This event could be triggered by `AddFolderToProject` or `RemoveFromProject`.
|
||||||
// So we need to update the history.
|
|
||||||
this.update_history(cx);
|
this.update_history(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5218,48 +5226,58 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(location) = self.serialize_workspace_location(cx) {
|
match self.serialize_workspace_location(cx) {
|
||||||
let breakpoints = self.project.update(cx, |project, cx| {
|
WorkspaceLocation::Location(location) => {
|
||||||
project
|
let breakpoints = self.project.update(cx, |project, cx| {
|
||||||
.breakpoint_store()
|
project
|
||||||
.read(cx)
|
.breakpoint_store()
|
||||||
.all_source_breakpoints(cx)
|
.read(cx)
|
||||||
});
|
.all_source_breakpoints(cx)
|
||||||
|
});
|
||||||
|
|
||||||
let center_group = build_serialized_pane_group(&self.center.root, window, cx);
|
let center_group = build_serialized_pane_group(&self.center.root, window, cx);
|
||||||
let docks = build_serialized_docks(self, window, cx);
|
let docks = build_serialized_docks(self, window, cx);
|
||||||
let window_bounds = Some(SerializedWindowBounds(window.window_bounds()));
|
let window_bounds = Some(SerializedWindowBounds(window.window_bounds()));
|
||||||
let serialized_workspace = SerializedWorkspace {
|
let serialized_workspace = SerializedWorkspace {
|
||||||
id: database_id,
|
id: database_id,
|
||||||
location,
|
location,
|
||||||
center_group,
|
center_group,
|
||||||
window_bounds,
|
window_bounds,
|
||||||
display: Default::default(),
|
display: Default::default(),
|
||||||
docks,
|
docks,
|
||||||
centered_layout: self.centered_layout,
|
centered_layout: self.centered_layout,
|
||||||
session_id: self.session_id.clone(),
|
session_id: self.session_id.clone(),
|
||||||
breakpoints,
|
breakpoints,
|
||||||
window_id: Some(window.window_handle().window_id().as_u64()),
|
window_id: Some(window.window_handle().window_id().as_u64()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return window.spawn(cx, async move |_| {
|
window.spawn(cx, async move |_| {
|
||||||
persistence::DB.save_workspace(serialized_workspace).await;
|
persistence::DB.save_workspace(serialized_workspace).await;
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
WorkspaceLocation::DetachFromSession => window.spawn(cx, async move |_| {
|
||||||
|
persistence::DB
|
||||||
|
.set_session_id(database_id, None)
|
||||||
|
.await
|
||||||
|
.log_err();
|
||||||
|
}),
|
||||||
|
WorkspaceLocation::None => Task::ready(()),
|
||||||
}
|
}
|
||||||
Task::ready(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_workspace_location(&self, cx: &App) -> Option<SerializedWorkspaceLocation> {
|
fn serialize_workspace_location(&self, cx: &App) -> WorkspaceLocation {
|
||||||
if let Some(ssh_project) = &self.serialized_ssh_project {
|
if let Some(ssh_project) = &self.serialized_ssh_project {
|
||||||
Some(SerializedWorkspaceLocation::Ssh(ssh_project.clone()))
|
WorkspaceLocation::Location(SerializedWorkspaceLocation::Ssh(ssh_project.clone()))
|
||||||
} else if let Some(local_paths) = self.local_paths(cx) {
|
} else if let Some(local_paths) = self.local_paths(cx) {
|
||||||
if !local_paths.is_empty() {
|
if !local_paths.is_empty() {
|
||||||
Some(SerializedWorkspaceLocation::from_local_paths(local_paths))
|
WorkspaceLocation::Location(SerializedWorkspaceLocation::from_local_paths(
|
||||||
|
local_paths,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
WorkspaceLocation::DetachFromSession
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
WorkspaceLocation::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5267,8 +5285,9 @@ impl Workspace {
|
||||||
let Some(id) = self.database_id() else {
|
let Some(id) = self.database_id() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(location) = self.serialize_workspace_location(cx) else {
|
let location = match self.serialize_workspace_location(cx) {
|
||||||
return;
|
WorkspaceLocation::Location(location) => location,
|
||||||
|
_ => return,
|
||||||
};
|
};
|
||||||
if let Some(manager) = HistoryManager::global(cx) {
|
if let Some(manager) = HistoryManager::global(cx) {
|
||||||
manager.update(cx, |this, cx| {
|
manager.update(cx, |this, cx| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue