diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp index 9bd1a2cc14..9bd9cb7bee 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp +++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp @@ -297,7 +297,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // extract ElementToFocus and clear it; we only want to use it once auto vmImpl = get_self(_colorSchemesPageVM); const auto elementToFocus = vmImpl->ElementToFocus(); - vmImpl->ElementToFocus(L""); + vmImpl->ElementToFocus({}); const auto currentScheme = _colorSchemesPageVM.CurrentScheme(); if (_colorSchemesPageVM.CurrentPage() == ColorSchemesSubPage::EditColorScheme && currentScheme) @@ -634,31 +634,37 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto settingName{ args.PropertyName() }; if (settingName == L"CurrentPage") { + // extract ElementToFocus and clear it; we only want to use it once + auto vmImpl = get_self(profile); + const auto elementToFocus = vmImpl->ElementToFocus(); + vmImpl->ElementToFocus({}); + const auto currentPage = profile.CurrentPage(); if (currentPage == ProfileSubPage::Base) { - contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this)); + contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this, elementToFocus)); _breadcrumbs.Clear(); const auto crumb = winrt::make(breadcrumbTag, breadcrumbText, BreadcrumbSubPage::None); _breadcrumbs.Append(crumb); + SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0); } else if (currentPage == ProfileSubPage::Appearance) { - contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this)); + contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this, elementToFocus)); const auto crumb = winrt::make(breadcrumbTag, RS_(L"Profile_Appearance/Header"), BreadcrumbSubPage::Profile_Appearance); _breadcrumbs.Append(crumb); SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0); } else if (currentPage == ProfileSubPage::Terminal) { - contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this)); + contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this, elementToFocus)); const auto crumb = winrt::make(breadcrumbTag, RS_(L"Profile_Terminal/Header"), BreadcrumbSubPage::Profile_Terminal); _breadcrumbs.Append(crumb); SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0); } else if (currentPage == ProfileSubPage::Advanced) { - contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this)); + contentFrame().Navigate(xaml_typename(), winrt::make(profile, *this, elementToFocus)); const auto crumb = winrt::make(breadcrumbTag, RS_(L"Profile_Advanced/Header"), BreadcrumbSubPage::Profile_Advanced); _breadcrumbs.Append(crumb); SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0); @@ -844,23 +850,38 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation SettingsNav().SelectedItem(profileNavItem); } + // Pass along the element to focus to the ProfileViewModel. + // This will work as a staging area before we navigate to the correct sub-page + auto profileVMImpl = get_self(profile); + profileVMImpl->ElementToFocus(elementToFocus); + + // convert the BreadcrumbSubPage to ProfileSubPage + const ProfileSubPage profileSubPage = [&](BreadcrumbSubPage subPage) { + switch (subPage) + { + case BreadcrumbSubPage::None: + return ProfileSubPage::Base; + case BreadcrumbSubPage::Profile_Appearance: + return ProfileSubPage::Appearance; + case BreadcrumbSubPage::Profile_Terminal: + return ProfileSubPage::Terminal; + case BreadcrumbSubPage::Profile_Advanced: + return ProfileSubPage::Advanced; + default: + // This should never happen + assert(false); + } + }(subPage); + const bool needsForcedRefresh = profile.CurrentPage() == profileSubPage; + // Set the profile's 'CurrentPage' to the correct one, if this requires further navigation, the // event handler will do it - if (subPage == BreadcrumbSubPage::None) + profile.CurrentPage(profileSubPage); + if (needsForcedRefresh) { - profile.CurrentPage(ProfileSubPage::Base); - } - else if (subPage == BreadcrumbSubPage::Profile_Appearance) - { - profile.CurrentPage(ProfileSubPage::Appearance); - } - else if (subPage == BreadcrumbSubPage::Profile_Terminal) - { - profile.CurrentPage(ProfileSubPage::Terminal); - } - else if (subPage == BreadcrumbSubPage::Profile_Advanced) - { - profile.CurrentPage(ProfileSubPage::Advanced); + // If we're already on the correct sub-page, the PropertyChanged event won't fire. + // However, we still need to pass along the ElementToFocus, so we need to force a refresh. + profileVMImpl->ForceRefreshCurrentPage(); } } diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h index c4e70ec8a1..5d045f2053 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h @@ -59,6 +59,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void DeleteProfile(); void SetupAppearances(Windows::Foundation::Collections::IObservableVector schemesList); + void ForceRefreshCurrentPage() + { + // Used to trigger the PropertyChanged handler in MainPage.cpp + // This forces the page to refresh + _NotifyChanges(L"CurrentPage"); + } // bell style bits hstring BellStylePreview() const; @@ -177,6 +183,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation WINRT_PROPERTY(bool, IsBaseLayer, false); WINRT_PROPERTY(bool, FocusDeleteButton, false); + WINRT_PROPERTY(hstring, ElementToFocus); WINRT_PROPERTY(Windows::Foundation::Collections::IVector, IconTypes); GETSET_BINDABLE_ENUM_SETTING(AntiAliasingMode, Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode); GETSET_BINDABLE_ENUM_SETTING(CloseOnExitMode, Microsoft::Terminal::Settings::Model::CloseOnExitMode, CloseOnExit); diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.xaml b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.xaml index 44f7cca4d1..280bca2940 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.xaml +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.xaml @@ -75,7 +75,8 @@ CornerRadius="{StaticResource ControlCornerRadius}" /> - @@ -251,7 +252,8 @@ -