From da3f02a6e2f085038f7f1aeda881ba01f412da02 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 23 Mar 2021 06:24:27 -0700 Subject: [PATCH] Command Palette: announce various mode and state changes to UIA (#9582) This commit introduces a few different announcements to the command palette. When you delete the `>`, it will announce that you have entered "command-line mode". When you reintroduce the `>`, it will announce that you are in "action search mode." When you enter a nested command, it will announce that you are looking at "more options for new tab..." or "more options for select color scheme...". When you search and find nothing, it will announce that there were no matching commands (or tabs!) Related to #7907. --- src/cascadia/TerminalApp/CommandPalette.cpp | 42 ++++++++++++++++++- .../Resources/en-US/Resources.resw | 16 +++++++ src/cascadia/TerminalApp/pch.h | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) 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