From 79039f93d75473285b1a68b1cba2ff9b08e85ef3 Mon Sep 17 00:00:00 2001 From: ozacod <47009516+ozacod@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:19:23 +0300 Subject: [PATCH] picker: Fix layout persistency with preview setting change (#59827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary When you change a picker's preview position (toggle it, or set it right/below/hidden), that choice should be remembered the next time the picker opens. Previously it wasn't: the last-used layout was only written to the database as a side effect of `store_shape_for_this_layout`, which runs exclusively when a resize completes (`render.rs`). So changing only the preview position without also dragging to resize, was forgotten on the next open. All layout changes funnel through a single chokepoint, `set_preview_layout`, but it only updated the in-memory `preview.layout` and reloaded the per-layout shape; it never persisted the layout key. ## Solution `set_preview_layout` now persists the layout immediately via a new `store_last_layout` helper, which writes just the `LAST_PREVIEW_LAYOUT` key — deliberately without writing the current shape, so a never-resized layout's default size isn't frozen into the database as if the user had chosen it. Both persistence paths are now correct: - Resize completes — saves size and layout (unchanged). - Position-only change (toggle / set right / set below / set hidden) saves the layout right away. This applies to every picker with a preview (file finder, text finder), since the persistence is keyed generically by the picker delegate name. ## Testing - Manual: open the file and text finder → switch the preview to Below (or Right) without resizing → close and reopen → it returns in that position; hide the preview → reopen → it stays hidden. Resizing still persists size as before. Release Notes: - Fixed picker preview position not being remembered when changed without resizing the picker --------- Co-authored-by: ozacod --- crates/picker/src/persistence.rs | 20 ++++++++++++++++++++ crates/picker/src/picker.rs | 2 ++ 2 files changed, 22 insertions(+) diff --git a/crates/picker/src/persistence.rs b/crates/picker/src/persistence.rs index ab61859abd..59de6cf8bf 100644 --- a/crates/picker/src/persistence.rs +++ b/crates/picker/src/persistence.rs @@ -36,6 +36,26 @@ pub(crate) fn store_shape_for_this_layout( }); } +/// Persist the last-used preview layout without touching the stored shape. +/// +/// Changing the preview position (e.g. right/below/hidden) without resizing +/// must still be remembered, so this is called whenever the layout changes. +pub(crate) fn store_last_layout( + picker_delegate: &'static str, + preview_layout: Option, + cx: &App, +) { + let kvp = KeyValueStore::global(cx); + db::write_and_log(cx, async move || { + kvp.scoped(PICKERS_NAMESPACE) + .write( + last_layout_key(picker_delegate), + layout_as_str(preview_layout).to_string(), + ) + .await + }); +} + pub(crate) fn try_load_shape( picker_delegate: &'static str, preview_layout: impl Into>, diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index c655cb0a46..352f60168e 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -1260,6 +1260,8 @@ impl Picker { _window: &mut Window, cx: &mut Context, ) { + persistence::store_last_layout(D::name(), self.preview.as_ref().map(|_| layout), cx); + let Some(preview) = &mut self.preview else { return; };