Icon theme selector: Don't select last list item when fuzzy searching (#29560)

Adds manual icon-theme selection persistence

Store manually selected icon-themes to maintain selection when query
changes. This allows the theme selector to remember the user's choice
rather than resetting selection when filtering results.

mentioned in #28081 and #28278

Release Notes:

- Improved persistence when selecting themes and icon themes.

---------

Co-authored-by: Peter Tripp <peter@zed.dev>
This commit is contained in:
Hendrik Sollich 2025-05-30 22:37:38 +02:00 committed by GitHub
parent 1f17df7fb0
commit eefa6c4882
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -50,6 +50,7 @@ pub(crate) struct IconThemeSelectorDelegate {
matches: Vec<StringMatch>, matches: Vec<StringMatch>,
original_theme: Arc<IconTheme>, original_theme: Arc<IconTheme>,
selection_completed: bool, selection_completed: bool,
selected_theme: Option<Arc<IconTheme>>,
selected_index: usize, selected_index: usize,
selector: WeakEntity<IconThemeSelector>, selector: WeakEntity<IconThemeSelector>,
} }
@ -98,6 +99,7 @@ impl IconThemeSelectorDelegate {
matches, matches,
original_theme: original_theme.clone(), original_theme: original_theme.clone(),
selected_index: 0, selected_index: 0,
selected_theme: None,
selection_completed: false, selection_completed: false,
selector, selector,
}; };
@ -106,17 +108,24 @@ impl IconThemeSelectorDelegate {
this this
} }
fn show_selected_theme(&mut self, cx: &mut Context<Picker<IconThemeSelectorDelegate>>) { fn show_selected_theme(
&mut self,
cx: &mut Context<Picker<IconThemeSelectorDelegate>>,
) -> Option<Arc<IconTheme>> {
if let Some(mat) = self.matches.get(self.selected_index) { if let Some(mat) = self.matches.get(self.selected_index) {
let registry = ThemeRegistry::global(cx); let registry = ThemeRegistry::global(cx);
match registry.get_icon_theme(&mat.string) { match registry.get_icon_theme(&mat.string) {
Ok(theme) => { Ok(theme) => {
Self::set_icon_theme(theme, cx); Self::set_icon_theme(theme.clone(), cx);
Some(theme)
} }
Err(err) => { Err(err) => {
log::error!("error loading icon theme {}: {err}", mat.string); log::error!("error loading icon theme {}: {err}", mat.string);
None
} }
} }
} else {
None
} }
} }
@ -201,7 +210,7 @@ impl PickerDelegate for IconThemeSelectorDelegate {
cx: &mut Context<Picker<IconThemeSelectorDelegate>>, cx: &mut Context<Picker<IconThemeSelectorDelegate>>,
) { ) {
self.selected_index = ix; self.selected_index = ix;
self.show_selected_theme(cx); self.selected_theme = self.show_selected_theme(cx);
} }
fn update_matches( fn update_matches(
@ -244,11 +253,24 @@ impl PickerDelegate for IconThemeSelectorDelegate {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.delegate.matches = matches; this.delegate.matches = matches;
this.delegate.selected_index = this if query.is_empty() && this.delegate.selected_theme.is_none() {
.delegate this.delegate.selected_index = this
.selected_index .delegate
.min(this.delegate.matches.len().saturating_sub(1)); .selected_index
this.delegate.show_selected_theme(cx); .min(this.delegate.matches.len().saturating_sub(1));
} else if let Some(selected) = this.delegate.selected_theme.as_ref() {
this.delegate.selected_index = this
.delegate
.matches
.iter()
.enumerate()
.find(|(_, mtch)| mtch.string == selected.name)
.map(|(ix, _)| ix)
.unwrap_or_default();
} else {
this.delegate.selected_index = 0;
}
this.delegate.selected_theme = this.delegate.show_selected_theme(cx);
}) })
.log_err(); .log_err();
}) })