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