diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index fbf4a4e246..ab4bbf3b32 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -530,6 +530,15 @@ namespace winrt::TerminalApp::implementation // which will cause us to refresh the list of filterable commands. _searchBox().Text(L""); _searchBox().Focus(FocusState::Programmatic); + + if (auto automationPeer{ Automation::Peers::FrameworkElementAutomationPeer::FromElement(_searchBox()) }) + { + automationPeer.RaiseNotificationEvent( + Automation::Peers::AutomationNotificationKind::ActionCompleted, + Automation::Peers::AutomationNotificationProcessing::CurrentThenMostRecent, + fmt::format(std::wstring_view{ RS_(L"CommandPalette_NestedCommandAnnouncement") }, ParentCommandName()), + L"CommandPaletteNestingLevelChanged" /* unique name for this notification category */); + } } // Method Description: @@ -768,7 +777,19 @@ namespace winrt::TerminalApp::implementation if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::ActionMode) { - _noMatchesText().Visibility(_filteredActions.Size() > 0 ? Visibility::Collapsed : Visibility::Visible); + const auto currentNeedleHasResults{ _filteredActions.Size() > 0 }; + _noMatchesText().Visibility(currentNeedleHasResults ? Visibility::Collapsed : Visibility::Visible); + if (!currentNeedleHasResults) + { + if (auto automationPeer{ Automation::Peers::FrameworkElementAutomationPeer::FromElement(_searchBox()) }) + { + automationPeer.RaiseNotificationEvent( + Automation::Peers::AutomationNotificationKind::ActionCompleted, + Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, + NoMatchesText(), // NoMatchesText contains the right text for the current mode + L"CommandPaletteResultAnnouncement" /* unique name for this notification */); + } + } } else { @@ -897,6 +918,9 @@ namespace winrt::TerminalApp::implementation { _currentMode = mode; + const auto currentlyVisible{ Visibility() == Visibility::Visible }; + + auto modeAnnouncementResourceKey{ USES_RESOURCE(L"CommandPaletteModeAnnouncement_ActionMode") }; ParsedCommandLineText(L""); _searchBox().Text(L""); _searchBox().Select(_searchBox().Text().size(), 0); @@ -912,6 +936,7 @@ namespace winrt::TerminalApp::implementation NoMatchesText(RS_(L"TabSwitcher_NoMatchesText")); ControlName(RS_(L"TabSwitcherControlName")); PrefixCharacter(L""); + modeAnnouncementResourceKey = USES_RESOURCE(L"CommandPaletteModeAnnouncement_TabSearchSwitchMode"); break; } case CommandPaletteMode::CommandlineMode: @@ -919,6 +944,7 @@ namespace winrt::TerminalApp::implementation NoMatchesText(L""); ControlName(RS_(L"CommandPaletteControlName")); PrefixCharacter(L""); + modeAnnouncementResourceKey = USES_RESOURCE(L"CommandPaletteModeAnnouncement_CommandlineMode"); break; case CommandPaletteMode::ActionMode: default: @@ -926,9 +952,23 @@ namespace winrt::TerminalApp::implementation NoMatchesText(RS_(L"CommandPalette_NoMatchesText/Text")); ControlName(RS_(L"CommandPaletteControlName")); PrefixCharacter(L">"); + // modeAnnouncementResourceKey is already set to _ActionMode + // We did this above to deduce the type (and make it easier on ourselves later). break; } + if (currentlyVisible) + { + if (auto automationPeer{ Automation::Peers::FrameworkElementAutomationPeer::FromElement(_searchBox()) }) + { + automationPeer.RaiseNotificationEvent( + Automation::Peers::AutomationNotificationKind::ActionCompleted, + Automation::Peers::AutomationNotificationProcessing::CurrentThenMostRecent, + GetLibraryResourceString(modeAnnouncementResourceKey), + L"CommandPaletteModeSwitch" /* unique ID for this notification */); + } + } + // The smooth remove/add animations that happen during // UpdateFilteredActions don't work very well when switching between // modes because of the sheer amount of remove/adds. So, let's just diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 21c7bd4013..51b011c464 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -459,6 +459,22 @@ No matching commands + + Action search mode + This text will be read aloud using assistive technologies when the command palette switches into action (command search) mode. + + + Tab title mode + This text will be read aloud using assistive technologies when the command palette switches into a mode that filters tab names. + + + Command-line mode + This text will be read aloud using assistive technologies when the command palette switches into the raw commandline parsing mode. + + + More options for "{}" + This text will be read aloud using assistive technologies when the user selects a command that has additional options. The {} will be expanded to the name of the command containing more options. + Executing command line will invoke the following commands: Will be followed by a list of strings describing parsed commands diff --git a/src/cascadia/TerminalApp/pch.h b/src/cascadia/TerminalApp/pch.h index 5e23b3df6c..f2c5663525 100644 --- a/src/cascadia/TerminalApp/pch.h +++ b/src/cascadia/TerminalApp/pch.h @@ -46,6 +46,7 @@ #include "winrt/Windows.UI.Xaml.Markup.h" #include "winrt/Windows.UI.Xaml.Documents.h" #include "winrt/Windows.UI.Xaml.Automation.h" +#include "winrt/Windows.UI.Xaml.Automation.Peers.h" #include "winrt/Windows.UI.ViewManagement.h" #include #include