diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 5023e7274f..150c544111 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -1464,6 +1464,7 @@ QWER Qxxxxxxxxxxxxxxx qzmp RAII +Ralph RALT rasterbar rasterfont @@ -2013,6 +2014,7 @@ WHelper wic WIDTHSCROLL Widthx +Wiggum wil WImpl WINAPI diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.cpp b/src/cascadia/TerminalSettingsEditor/Appearances.cpp index 39a82aaf1f..4e6bc3b74f 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.cpp +++ b/src/cascadia/TerminalSettingsEditor/Appearances.cpp @@ -1052,22 +1052,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Appearances::FontFaceBox_LostFocus(const IInspectable& sender, const RoutedEventArgs&) { - const auto appearance = Appearance(); - const auto fontSpec = sender.as().Text(); - - if (fontSpec.empty()) - { - appearance.ClearFontFace(); - } - else - { - appearance.FontFace(fontSpec); - } + _updateFontName(sender.as().Text()); } - void Appearances::FontFaceBox_SuggestionChosen(const AutoSuggestBox& sender, const AutoSuggestBoxSuggestionChosenEventArgs& args) + void Appearances::FontFaceBox_QuerySubmitted(const AutoSuggestBox& sender, const AutoSuggestBoxQuerySubmittedEventArgs& args) { - const auto font = unbox_value(args.SelectedItem()); + // When pressing Enter within the input line, this callback will be invoked with no suggestion. + const auto font = unbox_value_or(args.ChosenSuggestion(), nullptr); + if (!font) + { + return; + } + const auto fontName = font.Name(); auto fontSpec = sender.Text(); @@ -1084,6 +1080,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } sender.Text(fontSpec); + + // Normally we'd just update the model property in LostFocus above, but because WinUI is the Ralph Wiggum + // among the UI frameworks, it raises the LostFocus event _before_ the QuerySubmitted event. + // So, when you press Save, the model will have the wrong font face string, because LostFocus was raised too early. + // Also, this causes the first tab in the application to be focused, so when you press Enter it'll switch tabs. + // + // You can't just assign focus back to the AutoSuggestBox, because the FocusState() within the GotFocus event handler + // contains random values. This prevents us from avoiding the IsSuggestionListOpen(true) in our GotFocus event handler. + // You can't just do IsSuggestionListOpen(false) either, because you can show the list with that property but not hide it. + // So, we update the model manually and assign focus to the parent container. + // + // BUT you can't just focus the parent container, because of a weird interaction with AutoSuggestBox where it'll refuse to lose + // focus if you picked a suggestion that matches the current fontSpec. So, we unfocus it first and then focus the parent container. + _updateFontName(fontSpec); + sender.Focus(FocusState::Unfocused); + FontFaceContainer().Focus(FocusState::Programmatic); } void Appearances::FontFaceBox_TextChanged(const AutoSuggestBox& sender, const AutoSuggestBoxTextChangedEventArgs& args) @@ -1106,6 +1118,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _updateFontNameFilter(filter); } + void Appearances::_updateFontName(hstring fontSpec) + { + const auto appearance = Appearance(); + if (fontSpec.empty()) + { + appearance.ClearFontFace(); + } + else + { + appearance.FontFace(std::move(fontSpec)); + } + } + void Appearances::_updateFontNameFilter(std::wstring_view filter) { if (_fontNameFilter != filter) diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.h b/src/cascadia/TerminalSettingsEditor/Appearances.h index c5afdc9b7b..aba3abd45f 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.h +++ b/src/cascadia/TerminalSettingsEditor/Appearances.h @@ -187,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void FontFaceBox_GotFocus(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); void FontFaceBox_LostFocus(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); - void FontFaceBox_SuggestionChosen(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox&, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxSuggestionChosenEventArgs&); + void FontFaceBox_QuerySubmitted(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox&, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxQuerySubmittedEventArgs&); void FontFaceBox_TextChanged(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox&, const winrt::Windows::UI::Xaml::Controls::AutoSuggestBoxTextChangedEventArgs&); void DeleteFontKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); safe_void_coroutine BackgroundImage_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); @@ -222,9 +222,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::Foundation::Collections::IObservableVector _FontFeaturesNames; std::wstring _fontNameFilter; bool _ShowAllFonts = false; + bool _suppressFontFaceBoxList = false; static void _ViewModelChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e); + void _updateFontName(winrt::hstring fontSpec); void _updateFontNameFilter(std::wstring_view filter); void _updateFilteredFontList(); void _UpdateBIAlignmentControl(const int32_t val); diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.xaml b/src/cascadia/TerminalSettingsEditor/Appearances.xaml index 0ad7674c12..0ed87caa62 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.xaml +++ b/src/cascadia/TerminalSettingsEditor/Appearances.xaml @@ -202,7 +202,8 @@ - + TextChanged="FontFaceBox_TextChanged" + UpdateTextOnSelect="False" />