Preserve telescope picker size on reopens (#60093)

Before:


https://github.com/user-attachments/assets/b95f3317-669a-462d-bbe8-ba80ede3e496

After:


https://github.com/user-attachments/assets/16536d14-fc91-4d68-ac0d-6b7c382dd298


Release Notes:

- Fixed telescope picker being overly small on consequent reopens
This commit is contained in:
Kirill Bulatov authored and GitHub committed 2026-06-29 14:04:35 +00:00
1 parent 2ef7f39587
commit 52db076410
2 files changed
+57 -2

No files matched your search

@@ -4380,6 +4380,41 @@ async fn test_open_without_dismiss_then_confirm_closes_finder(cx: &mut TestAppCo
});
}
#[gpui::test]
async fn test_reopen_with_preview_keeps_results_width(cx: &mut TestAppContext) {
let app_state = init_test(cx);
app_state
.fs
.as_fake()
.insert_tree(path!("/root"), json!({ "a.txt": "", "b.txt": "" }))
.await;
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
let (picker, workspace, cx) = build_find_picker(project, cx);
cx.dispatch_action(picker::SetPreviewRight);
cx.run_until_parked();
let in_session_width = picker.update_in(cx, |picker, window, _| picker.results_width(window));
cx.dispatch_action(Cancel);
cx.run_until_parked();
let picker = open_file_picker(&workspace, cx);
cx.run_until_parked();
let reopened_width = picker.update_in(cx, |picker, window, _| picker.results_width(window));
assert_eq!(
in_session_width, reopened_width,
"reopening with the side preview must keep the same results width as the in-session toggle"
);
// The preview layout is persisted in the key-value store, and tests in a
// process share one in-memory fallback store (no per-App `AppDatabase` is
// set in tests, so `AppDatabase::global` falls back to the shared static).
// Reset to the default layout so this write doesn't leak into other tests.
cx.dispatch_action(picker::SetPreviewHidden);
cx.run_until_parked();
}
async fn open_close_queried_buffer(
input: &str,
expected_matches: usize,
+22 -2
View File
@@ -571,7 +571,7 @@ impl<D: PickerDelegate> Picker<D> {
pub fn initial_width(mut self, width: impl Into<RelativeWidth>) -> Self {
let width = width.into();
self.default_shape.width = width;
if !self.shape_loaded_from_persistence {
if self.live_shape_is_hidden_default() {
self.shape.set_initial_width(width);
}
// A plain picker's whole-picker minimum tracks its opening width. Preview
@@ -591,12 +591,23 @@ impl<D: PickerDelegate> Picker<D> {
pub fn max_height(mut self, height: impl Into<RelativeHeight>) -> Self {
let height = height.into();
self.default_shape.height = height;
if !self.shape_loaded_from_persistence {
if self.live_shape_is_hidden_default() {
self.shape.set_initial_height(height);
}
self
}
/// Whether the live shape still reflects the hidden-layout default, i.e. it
/// was not restored from a persisted size and currently opens with no
/// preview. Only then may `initial_width`/`max_height` push their
/// hidden/no-preview defaults onto it; a picker reopened in a preview layout
/// keeps the larger telescope default, which those (smaller) no-preview
/// values must not shrink.
fn live_shape_is_hidden_default(&self) -> bool {
!self.shape_loaded_from_persistence
&& self.preview_layout().unwrap_or(preview::Layout::Hidden) == preview::Layout::Hidden
}
/// Whether the picker fills its full height (preview visible) or shrinks to
/// fit its content, treating the height as a maximum (no preview visible).
fn fill_height(&self) -> bool {
@@ -1242,6 +1253,15 @@ impl<D: PickerDelegate> Picker<D> {
self.preview.as_ref().map(|p| p.layout)
}
#[cfg(any(test, feature = "test-support"))]
pub fn results_width(&self, window: &Window) -> gpui::Pixels {
let layout = self.preview_layout().unwrap_or(preview::Layout::Hidden);
let pos = self
.shape
.results_position_and_size(layout, &self.size_bounds, window);
pos.right - pos.left
}
fn toggle_preview(&mut self, _: &TogglePreview, window: &mut Window, cx: &mut Context<Self>) {
self.toggle_preview_visible(window, cx);
}