From 22887d721ff724fa8f34e4403f995c8ee674511f Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 7 Oct 2020 17:49:10 -0500 Subject: [PATCH] Preview tab switching with the ATS (#7796) ## Summary of the Pull Request ![preview-ats-000](https://user-images.githubusercontent.com/18356694/94801728-18302a00-03ac-11eb-851d-760b92ebb46f.gif) This PR enables the ATS to display the active tab as the user navigates the tab switcher. We do this by dispatching the tab switch actions as the user navigates the menu, and manually _not_ focusing the new tab when the tab switcher is open. ## References * #6732 - original tab switcher PR * #6689 - That's a more involved, generic version of this, but this PR will be enough to stop most of the complaints hopefully ## PR Checklist * [x] Closes #7409 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed Opened tabs, tabbed through the menu, verified that it did what I'd expect --- src/cascadia/TerminalApp/CommandPalette.cpp | 25 +++++++++++++++++++++ src/cascadia/TerminalApp/CommandPalette.h | 3 +++ src/cascadia/TerminalApp/TerminalPage.cpp | 15 ++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index 5b0e0307bd3..15c1492e380 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -93,6 +93,8 @@ namespace winrt::TerminalApp::implementation } _sizeChangedRevoker.revoke(); }); + + _filteredActionsView().SelectionChanged({ this, &CommandPalette::_selectedCommandChanged }); } // Method Description: @@ -115,6 +117,29 @@ namespace winrt::TerminalApp::implementation _filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem()); } + // Method Description: + // - Called when the command selection changes. We'll use this in the tab + // switcher to "preview" tabs as the user navigates the list of tabs. To + // do that, we'll dispatch the switch to tab command for this tab, but not + // dismiss the switcher. + // Arguments: + // - + // Return Value: + // - + void CommandPalette::_selectedCommandChanged(const IInspectable& /*sender*/, + const Windows::UI::Xaml::RoutedEventArgs& /*args*/) + { + if (_currentMode == CommandPaletteMode::TabSwitchMode) + { + const auto& selectedCommand = _filteredActionsView().SelectedItem(); + if (const auto& command = selectedCommand.try_as()) + { + const auto& actionAndArgs = command.Action(); + _dispatch.DoAction(actionAndArgs); + } + } + } + void CommandPalette::_previewKeyDownHandler(IInspectable const& /*sender*/, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) { diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index 81b49e81b87..8ec262519a2 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -64,6 +64,9 @@ namespace winrt::TerminalApp::implementation void _keyUpHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); + void _selectedCommandChanged(Windows::Foundation::IInspectable const& sender, + Windows::UI::Xaml::RoutedEventArgs const& args); + void _updateUIForStackChange(); void _rootPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index f0aebd16d6b..d3395051a4b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2028,7 +2028,20 @@ namespace winrt::TerminalApp::implementation _tabContent.Children().Clear(); _tabContent.Children().Append(tab->GetRootElement()); - tab->SetFocused(true); + // GH#7409: If the tab switcher is open, then we _don't_ want to + // automatically focus the new tab here. The tab switcher wants + // to be able to "preview" the selected tab as the user tabs + // through the menu, but if we toss the focus to the control + // here, then the user won't be able to navigate the ATS any + // longer. + // + // When the tab swither is eventually dismissed, the focus will + // get tossed back to the focused terminal control, so we don't + // need to worry about focus getting lost. + if (CommandPalette().Visibility() != Visibility::Visible) + { + tab->SetFocused(true); + } // Raise an event that our title changed _titleChangeHandlers(*this, tab->GetActiveTitle());