Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[a11y] Announce new tab/pane upon creation #13575

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -746,4 +746,12 @@
<value>Suggestions found: {0}</value>
<comment>{0} will be replaced with a number.</comment>
</data>
</root>
<data name="NewTabAnnouncement" xml:space="preserve">
<value>A new tab for the "{}" profile was created successfully</value>
<comment>{} will be replaced with the name of the profile (i.e. PowerShell, Command Prompt, etc.). The name may span multiple words. This announcement is read by a screen reader.</comment>
</data>
<data name="SplitPaneAnnouncement" xml:space="preserve">
<value>A new pane for the "{}" profile was created successfully</value>
Comment on lines +750 to +754
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the wording here throws me a bit (feels clunky).. gut check how it sounds?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A11y team requested: "profile name created successfully"

We've diverged a bit since then haha. I find value in explicitly saying "pane" or "tab". I also think saying "profile" is important because some profile names could be weird. That said, what if we change it to...
"{}" pane/tab created successfully

It's more succinct? But there's still some doubts when it comes to localization. Thoughts?

<comment>{} will be replaced with the name of the profile (i.e. PowerShell, Command Prompt, etc.). The name may span multiple words. This announcement is read by a screen reader.</comment>
</data>
</root>
14 changes: 14 additions & 0 deletions src/cascadia/TerminalApp/TabManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,20 @@ namespace winrt::TerminalApp::implementation
{
auto newTabImpl = winrt::make_self<TerminalTab>(pane);
_InitializeTab(newTabImpl);

if (_autoPeer)
{
// we can't check if this is a leaf pane,
// but getting the profile returns null if we aren't, so that works!
if (const auto profile{ pane->GetProfile() })
{
_autoPeer.RaiseNotificationEvent(
Automation::Peers::AutomationNotificationKind::ActionCompleted,
Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent,
fmt::format(std::wstring_view{ RS_(L"NewTabAnnouncement") }, profile.Name()),
L"NewTab" /* unique name for this notification category */);
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ namespace winrt::TerminalApp::implementation
ShowSetAsDefaultInfoBar();
}

Automation::Peers::AutomationPeer TerminalPage::OnCreateAutomationPeer()
{
_autoPeer = Automation::Peers::FrameworkElementAutomationPeer(*this);
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
return _autoPeer;
}

// Method Description;
// - Checks if the current terminal window should load or save its layout information.
// Arguments:
Expand Down Expand Up @@ -1849,6 +1855,20 @@ namespace winrt::TerminalApp::implementation
_UnZoomIfNeeded();
tab.SplitPane(*realSplitType, splitSize, newPane);

if (_autoPeer)
{
// we can't check if this is a leaf pane,
// but getting the profile returns null if we aren't, so that works!
if (const auto profile{ newPane->GetProfile() })
{
_autoPeer.RaiseNotificationEvent(
Automation::Peers::AutomationNotificationKind::ActionCompleted,
Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent,
fmt::format(std::wstring_view{ RS_(L"SplitPaneAnnouncement") }, profile.Name()),
L"NewSplitPane" /* unique name for this notification category */);
}
}

// After GH#6586, the control will no longer focus itself
// automatically when it's finished being laid out. Manually focus
// the control here instead.
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace winrt::TerminalApp::implementation
void SetSettings(Microsoft::Terminal::Settings::Model::CascadiaSettings settings, bool needRefreshUI);

void Create();
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();

bool ShouldUsePersistedLayout(Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
bool ShouldImmediatelyHandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
Expand Down Expand Up @@ -162,6 +163,7 @@ namespace winrt::TerminalApp::implementation

private:
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events
Windows::UI::Xaml::Automation::Peers::AutomationPeer _autoPeer{ nullptr };
std::optional<HWND> _hostingHwnd;

// If you add controls here, but forget to null them either here or in
Expand Down