Reset panel saved size when default_size changes (#61855)

Closes #59235

When a panel's `default_size` changes (e.g. `git_panel.default_width` is
edited in settings), the persisted per-workspace size is now cleared so
the new default takes effect immediately. Previously the saved dragged
size took precedence forever, making `default_width` effectively useless
after the first manual resize.

This fix is at the Dock level (`crates/workspace/src/dock.rs`), so it
applies to all panels — Git Panel, Project Panel, Terminal Panel, etc.

Release Notes:

- Fixed panel `default_width` setting being ignored after manually
resizing the panel


https://github.com/user-attachments/assets/97ef69b2-387f-4e29-bc4c-0f336f24eb0b
This commit is contained in:
Tai Nguyen authored and GitHub committed 2026-07-31 09:27:11 +00:00
1 parent a502bd0eaf
commit 5e022b02bc
2 files changed
+93 -1

No files matched your search

+24 -1
View File
@@ -364,7 +364,7 @@ pub struct PanelSizeState {
struct PanelEntry {
panel: Arc<dyn PanelHandle>,
size_state: PanelSizeState,
_subscriptions: [Subscription; 3],
_subscriptions: [Subscription; 4],
}
pub struct PanelButtons {
@@ -671,6 +671,29 @@ impl Dock {
.ok();
}
}),
{
let panel = panel.clone();
let mut last_default_size = panel.read(cx).default_size(window, cx);
cx.observe_global_in::<SettingsStore>(window, move |this, window, cx| {
let default_size = panel.read(cx).default_size(window, cx);
if default_size == last_default_size {
return;
}
last_default_size = default_size;
let panel_id = Entity::entity_id(&panel);
if let Some(entry) = this
.panel_entries
.iter_mut()
.find(|entry| entry.panel.panel_id() == panel_id)
{
entry.size_state.size = None;
entry.panel.size_state_changed(window, cx);
cx.notify();
}
})
},
cx.subscribe_in(
&panel,
window,
+69
View File
@@ -14557,6 +14557,75 @@ mod tests {
}
}
#[gpui::test]
async fn test_default_size_change_resets_saved_size(cx: &mut gpui::TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.executor());
let project = Project::test(fs.clone(), [], cx).await;
let (multi_workspace, cx) =
cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx));
let workspace = multi_workspace.read_with(cx, |mw, _| mw.workspace().clone());
workspace.update(cx, |workspace, _cx| {
workspace.set_random_database_id();
workspace.bounds.size.width = px(800.);
});
let panel = workspace.update_in(cx, |workspace, window, cx| {
let panel = cx.new(|cx| TestPanel::new(DockPosition::Left, 100, cx));
workspace.add_panel(panel.clone(), window, cx);
workspace.toggle_dock(DockPosition::Left, window, cx);
panel
});
workspace.update_in(cx, |workspace, window, cx| {
workspace.resize_left_dock(px(350.), window, cx);
});
cx.run_until_parked();
let dock_size = workspace.read_with(cx, |workspace, cx| {
workspace
.left_dock()
.read(cx)
.panel::<TestPanel>()
.and_then(|panel| {
workspace
.left_dock()
.read(cx)
.stored_panel_size_state(&panel)
})
.and_then(|s| s.size)
});
assert_eq!(dock_size, Some(px(350.)));
panel.update(cx, |panel, cx| {
panel.default_size = px(500.);
cx.update_global::<SettingsStore, _>(|_, _| {});
});
cx.run_until_parked();
let dock_size = workspace.read_with(cx, |workspace, cx| {
workspace
.left_dock()
.read(cx)
.panel::<TestPanel>()
.and_then(|panel| {
workspace
.left_dock()
.read(cx)
.stored_panel_size_state(&panel)
})
.and_then(|s| s.size)
});
assert_eq!(
dock_size, None,
"saved size should be cleared after default_size changes"
);
}
#[gpui::test]
async fn test_flexible_panel_left_dock_sizing(cx: &mut gpui::TestAppContext) {
init_test(cx);