From e58bd4bdab46f7b0de02b6b3494be5a81e4940ad Mon Sep 17 00:00:00 2001 From: Danyal Ahmed <58849388+danyalahmed1995@users.noreply.github.com> Date: Tue, 30 Jun 2026 23:51:22 +0500 Subject: [PATCH] Preserve selected font face after focus changes (#20359) ## Summary Fixes the font face `AutoSuggestBox` resetting to its previous value, or stale filter text, after a keyboard-selected font is committed and focus later leaves the control. WinUI restores its cached user query when the suggestion list closes. The existing `LostFocus` path then treated that programmatic restoration as fresh user input and committed the stale value. This change distinguishes genuine user edits from programmatic text restoration, preserving the committed font value while retaining the queued selected-suggestion commit introduced by #20255. Fixes #20353. ## Validation Manually validated with a local `CascadiaPackage` Debug x64 build: - Reproduced the reset before the fix. - Selected `Lucida Console` from `Consolas` using keyboard navigation. - Pressed Enter and confirmed `Lucida Console` was applied. - Returned focus to the Font face control and tabbed out again. - Verified `Lucida Console` remained selected. - Verified stale filter text did not return. - Verified the #20245 crash did not regress. - Verified Save and Discard changes both work. --- .../TerminalSettingsEditor/Appearances.cpp | 20 +++++++++++++++++-- .../TerminalSettingsEditor/Appearances.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.cpp b/src/cascadia/TerminalSettingsEditor/Appearances.cpp index 0cc3ed8bdf..24d0e3b780 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.cpp +++ b/src/cascadia/TerminalSettingsEditor/Appearances.cpp @@ -1189,13 +1189,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Appearances::FontFaceBox_GotFocus(const Windows::Foundation::IInspectable& sender, const RoutedEventArgs&) { + const auto box = sender.as(); _updateFontNameFilter({}); - sender.as().IsSuggestionListOpen(true); + box.IsSuggestionListOpen(true); + _fontFaceBoxHasUserInput = false; } void Appearances::FontFaceBox_LostFocus(const IInspectable& sender, const RoutedEventArgs&) { - _updateFontName(sender.as().Text()); + const auto box = sender.as(); + if (_fontFaceBoxHasUserInput) + { + _updateFontName(box.Text()); + } + else + { + // AutoSuggestBox restores its cached user query when Tab closes the suggestion list. + // Programmatic Text updates don't synchronize that cache, so restore the committed value. + box.Text(Appearance().FontFace()); + } } void Appearances::FontFaceBox_QuerySubmitted(const AutoSuggestBox& sender, const AutoSuggestBoxQuerySubmittedEventArgs& args) @@ -1237,6 +1249,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis{ get_weak() }, weakSender{ winrt::make_weak(sender) }, fontSpec{ std::move(fontSpec) }]() { if (const auto self{ weakThis.get() }) { + self->_fontFaceBoxHasUserInput = false; + if (const auto box{ weakSender.get() }) { box.Text(fontSpec); @@ -1255,6 +1269,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation return; } + _fontFaceBoxHasUserInput = true; + const auto fontSpec = sender.Text(); std::wstring_view filter{ fontSpec }; diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.h b/src/cascadia/TerminalSettingsEditor/Appearances.h index e0e8248db9..886574971b 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.h +++ b/src/cascadia/TerminalSettingsEditor/Appearances.h @@ -237,6 +237,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::Foundation::Collections::IObservableVector _FontAxesNames; Windows::Foundation::Collections::IObservableVector _FontFeaturesNames; std::wstring _fontNameFilter; + bool _fontFaceBoxHasUserInput = false; bool _ShowAllFonts = false; static void _ViewModelChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);