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(
|
||||
&self,
|
||||
workspace_id: WorkspaceId,
|
||||
|
|
|
@ -1016,6 +1016,15 @@ pub enum OpenVisible {
|
|||
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<
|
||||
dyn Fn(
|
||||
&mut Workspace,
|
||||
|
@ -1135,7 +1144,6 @@ impl Workspace {
|
|||
this.update_window_title(window, cx);
|
||||
this.serialize_workspace(window, cx);
|
||||
// This event could be triggered by `AddFolderToProject` or `RemoveFromProject`.
|
||||
// So we need to update the history.
|
||||
this.update_history(cx);
|
||||
}
|
||||
|
||||
|
@ -5218,48 +5226,58 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(location) = self.serialize_workspace_location(cx) {
|
||||
let breakpoints = self.project.update(cx, |project, cx| {
|
||||
project
|
||||
.breakpoint_store()
|
||||
.read(cx)
|
||||
.all_source_breakpoints(cx)
|
||||
});
|
||||
match self.serialize_workspace_location(cx) {
|
||||
WorkspaceLocation::Location(location) => {
|
||||
let breakpoints = self.project.update(cx, |project, cx| {
|
||||
project
|
||||
.breakpoint_store()
|
||||
.read(cx)
|
||||
.all_source_breakpoints(cx)
|
||||
});
|
||||
|
||||
let center_group = build_serialized_pane_group(&self.center.root, window, cx);
|
||||
let docks = build_serialized_docks(self, window, cx);
|
||||
let window_bounds = Some(SerializedWindowBounds(window.window_bounds()));
|
||||
let serialized_workspace = SerializedWorkspace {
|
||||
id: database_id,
|
||||
location,
|
||||
center_group,
|
||||
window_bounds,
|
||||
display: Default::default(),
|
||||
docks,
|
||||
centered_layout: self.centered_layout,
|
||||
session_id: self.session_id.clone(),
|
||||
breakpoints,
|
||||
window_id: Some(window.window_handle().window_id().as_u64()),
|
||||
};
|
||||
let center_group = build_serialized_pane_group(&self.center.root, window, cx);
|
||||
let docks = build_serialized_docks(self, window, cx);
|
||||
let window_bounds = Some(SerializedWindowBounds(window.window_bounds()));
|
||||
let serialized_workspace = SerializedWorkspace {
|
||||
id: database_id,
|
||||
location,
|
||||
center_group,
|
||||
window_bounds,
|
||||
display: Default::default(),
|
||||
docks,
|
||||
centered_layout: self.centered_layout,
|
||||
session_id: self.session_id.clone(),
|
||||
breakpoints,
|
||||
window_id: Some(window.window_handle().window_id().as_u64()),
|
||||
};
|
||||
|
||||
return window.spawn(cx, async move |_| {
|
||||
persistence::DB.save_workspace(serialized_workspace).await;
|
||||
});
|
||||
window.spawn(cx, async move |_| {
|
||||
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 {
|
||||
Some(SerializedWorkspaceLocation::Ssh(ssh_project.clone()))
|
||||
WorkspaceLocation::Location(SerializedWorkspaceLocation::Ssh(ssh_project.clone()))
|
||||
} else if let Some(local_paths) = self.local_paths(cx) {
|
||||
if !local_paths.is_empty() {
|
||||
Some(SerializedWorkspaceLocation::from_local_paths(local_paths))
|
||||
WorkspaceLocation::Location(SerializedWorkspaceLocation::from_local_paths(
|
||||
local_paths,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
WorkspaceLocation::DetachFromSession
|
||||
}
|
||||
} else {
|
||||
None
|
||||
WorkspaceLocation::None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5267,8 +5285,9 @@ impl Workspace {
|
|||
let Some(id) = self.database_id() else {
|
||||
return;
|
||||
};
|
||||
let Some(location) = self.serialize_workspace_location(cx) else {
|
||||
return;
|
||||
let location = match self.serialize_workspace_location(cx) {
|
||||
WorkspaceLocation::Location(location) => location,
|
||||
_ => return,
|
||||
};
|
||||
if let Some(manager) = HistoryManager::global(cx) {
|
||||
manager.update(cx, |this, cx| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue