Update panels serialization from global to per-workspace (#30652)

Closes #27834

This PR changes project panel, outline panel and collab panel
serialization from global to per-workspace, so configurations are
restored only within the same workspace. Handles remote workspaces too.
Opening a new window will start with a fresh panel defaults e.g. width.

Release Notes:

- Improved project panel, outline panel, and collab panel to persist
width on a per-workspace basis. New windows will use the width specified
in the `default_width` setting.
This commit is contained in:
Smit Barmase 2025-05-13 11:35:42 -07:00 committed by GitHub
parent 1ace5a27bc
commit f98c6fb2cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 123 additions and 36 deletions

View file

@ -680,16 +680,25 @@ impl OutlinePanel {
workspace: WeakEntity<Workspace>,
mut cx: AsyncWindowContext,
) -> anyhow::Result<Entity<Self>> {
let serialized_panel = cx
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
.await
.context("loading outline panel")
.log_err()
let serialized_panel = match workspace
.read_with(&cx, |workspace, _| {
OutlinePanel::serialization_key(workspace)
})
.ok()
.flatten()
.map(|panel| serde_json::from_str::<SerializedOutlinePanel>(&panel))
.transpose()
.log_err()
.flatten();
{
Some(serialization_key) => cx
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) })
.await
.context("loading outline panel")
.log_err()
.flatten()
.map(|panel| serde_json::from_str::<SerializedOutlinePanel>(&panel))
.transpose()
.log_err()
.flatten(),
None => None,
};
workspace.update_in(&mut cx, |workspace, window, cx| {
let panel = Self::new(workspace, window, cx);
@ -845,14 +854,32 @@ impl OutlinePanel {
outline_panel
}
fn serialization_key(workspace: &Workspace) -> Option<String> {
workspace
.database_id()
.map(|id| i64::from(id).to_string())
.or(workspace.session_id())
.map(|id| format!("{}-{:?}", OUTLINE_PANEL_KEY, id))
}
fn serialize(&mut self, cx: &mut Context<Self>) {
let Some(serialization_key) = self
.workspace
.update(cx, |workspace, _| {
OutlinePanel::serialization_key(workspace)
})
.ok()
.flatten()
else {
return;
};
let width = self.width;
let active = Some(self.active);
self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
OUTLINE_PANEL_KEY.into(),
serialization_key,
serde_json::to_string(&SerializedOutlinePanel { width, active })?,
)
.await?;
@ -4803,10 +4830,12 @@ impl Panel for OutlinePanel {
.unwrap_or_else(|| OutlinePanelSettings::get_global(cx).default_width)
}
fn set_size(&mut self, size: Option<Pixels>, _: &mut Window, cx: &mut Context<Self>) {
fn set_size(&mut self, size: Option<Pixels>, window: &mut Window, cx: &mut Context<Self>) {
self.width = size;
self.serialize(cx);
cx.notify();
cx.defer_in(window, |this, _, cx| {
this.serialize(cx);
});
}
fn icon(&self, _: &Window, cx: &App) -> Option<IconName> {