Define Automation Properties for TermControl (#4732)

Defines the following automation properties for a Terminal Control:
- [**Orientation**](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.getorientationcore):
  - The orientation of the control
  - None --> Vertical
- [**Name**](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.getnamecore):
  - The name as used by assistive technology and other Microsoft UI
    Automation clients. Generally presented by automation clients as the
    primary way to identify an element (along with the control type)
  - "" --> <profile name>
- [**HelpText**](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.gethelptextcore):
  - The help text. Generally presented by automation clients if
    requested by the user. This would be something that you would normally
    expect to appear from tooltips.
  - "" --> <tab title>
- [**LiveSetting**](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.getlivesettingcore):
  - reports the live setting notification behavior. A representation of
    how assertive this control should be when content changes.
  - none --> Polite

## Detailed Description of the Pull Request / Additional comments
ProfileName had to be added to the TerminalSettings (IControlSettings)
to pass that information along to the automation peer. In the rare event
that somebody purposefully decided to make their ProfileName empty, we
fallback to the tab title.


## Validation Steps Performed
Verified using Accessibility Insights and inspect.exe

This is are some examples of the information a general user can expect
to receive about a Terminal Control.

- Type: Terminal Control
- Name: Command Prompt
- Help Text (if requested): Command Prompt - ping bing.com

- Type: Terminal Control
- Name: Ubuntu
- Help Text (if requested): cazamor@PC-cazamor:/mnt/c/Users/cazamor$

Note, it is generally read by an automation client as follows:
"<type>, <name>"

References #2099 - Automation Properties for TerminalControl, Search Box
References #2142 - Localization

Closes #2142
This commit is contained in:
Carlos Zamora 2020-02-27 16:37:56 -08:00 committed by GitHub
parent a97048a798
commit 74cd9db383
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 166 additions and 69 deletions

View file

@ -183,6 +183,7 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
terminalSettings.CursorShape(_cursorShape);
// Fill in the remaining properties from the profile
terminalSettings.ProfileName(_name);
terminalSettings.UseAcrylic(_useAcrylic);
terminalSettings.TintOpacity(_acrylicTransparency);

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@ -117,27 +117,48 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CaseSensitivityButtonLocalizedText.ToolTipService.ToolTip" xml:space="preserve">
<data name="SearchBox_CaseSensitivity.ToolTipService.ToolTip" xml:space="preserve">
<value>Match Case</value>
<comment>The tooltip text for CaseSensitivityButton</comment>
<comment>The tooltip text for the case sensitivity button on the search box control.</comment>
</data>
<data name="CloseButtonLocalizedText.ToolTipService.ToolTip" xml:space="preserve">
<data name="SearchBox_Close.ToolTipService.ToolTip" xml:space="preserve">
<value>Close</value>
<comment>The tooltip text for CloseButton</comment>
<comment>The tooltip text for the close button on the search box control.</comment>
</data>
<data name="GoBackwardButtonLocalizedText.ToolTipService.ToolTip" xml:space="preserve">
<data name="SearchBox_SearchBackwards.ToolTipService.ToolTip" xml:space="preserve">
<value>Find Up</value>
<comment>The tooltip text for GoBackward Button</comment>
<comment>The tooltip text for the search backward button.</comment>
</data>
<data name="GoForwardButtonLocalizedText.ToolTipService.ToolTip" xml:space="preserve">
<data name="SearchBox_SearchForwards.ToolTipService.ToolTip" xml:space="preserve">
<value>Find Down</value>
<comment>The tooltip text for GoForward Button</comment>
<comment>The tooltip text for the search forward button.</comment>
</data>
<data name="TextBoxLocalizedText.PlaceholderText" xml:space="preserve">
<data name="SearchBox_TextBox.PlaceholderText" xml:space="preserve">
<value>Find...</value>
<comment>The placeholder text in the search dialog TextBox</comment>
<comment>The placeholder text in the search box control.</comment>
</data>
<data name="DragFileCaption" xml:space="preserve">
<value>Copy path to file</value>
<comment>The displayed caption for dragging a file onto a terminal.</comment>
</data>
</root>
<data name="SearchBox_CaseSensitivity.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Case Sensitivity</value>
<comment>The name of the case sensitivity button on the search box control for accessibility.</comment>
</data>
<data name="SearchBox_SearchForwards.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Search Forward</value>
<comment>The name of the search forward button for accessibility.</comment>
</data>
<data name="SearchBox_SearchBackwards.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Search Backward</value>
<comment>The name of the search backward button for accessibility.</comment>
</data>
<data name="SearchBox_TextBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Search Text</value>
<comment>The name of the text box on the search box control for accessibility.</comment>
</data>
<data name="TerminalControl_ControlType" xml:space="preserve">
<value>terminal</value>
<comment>The type of control that the terminal ahderes to. Used to identify how a user can interact with this kind of control.</comment>
</data>
</root>

View file

@ -153,29 +153,44 @@
</UserControl.Resources>
<StackPanel Orientation="Horizontal" Style="{ThemeResource SearchBoxBackground}" Padding="5" CornerRadius="0,0,2,2">
<TextBox x:Name="TextBox" x:Uid="TextBoxLocalizedText" AutomationProperties.Name="Search Text" CornerRadius="2" Width="160"
PlaceholderForeground="{ThemeResource TextBoxPlaceholderTextThemeBrush}" FontSize="15" KeyDown = "TextBoxKeyDown"
Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBox x:Name="TextBox"
x:Uid="SearchBox_TextBox"
CornerRadius="2"
Width="160"
PlaceholderForeground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
FontSize="15"
KeyDown="TextBoxKeyDown"
Margin="5"
HorizontalAlignment="Left"
VerticalAlignment="Center">
</TextBox>
<ToggleButton x:Name="GoBackwardButton" x:Uid="GoBackwardButtonLocalizedText" AutomationProperties.Name="Set Search Backward"
HorizontalAlignment="Right" Style="{StaticResource ToggleButtonStyle}"
Click="GoBackwardClicked" IsChecked="True">
<ToggleButton x:Name="GoBackwardButton"
x:Uid="SearchBox_SearchBackwards"
HorizontalAlignment="Right"
Style="{StaticResource ToggleButtonStyle}"
Click="GoBackwardClicked"
IsChecked="True">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74A;" Style="{ThemeResource FontIconStyle}"/>
</ToggleButton>
<ToggleButton x:Name="GoForwardButton" x:Uid="GoForwardButtonLocalizedText"
AutomationProperties.Name="Set Search Forward" Style="{StaticResource ToggleButtonStyle}"
<ToggleButton x:Name="GoForwardButton"
x:Uid="SearchBox_SearchForwards"
Style="{StaticResource ToggleButtonStyle}"
Click="GoForwardClicked">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74B;" Style="{ThemeResource FontIconStyle}"/>
</ToggleButton>
<ToggleButton x:Name="CaseSensitivityButton" x:Uid="CaseSensitivityButtonLocalizedText"
AutomationProperties.Name="CaseSensitivity" Style="{StaticResource ToggleButtonStyle}">
<ToggleButton x:Name="CaseSensitivityButton"
x:Uid="SearchBox_CaseSensitivity"
Style="{StaticResource ToggleButtonStyle}">
<PathIcon Data="M8.87305 10H7.60156L6.5625 7.25195H2.40625L1.42871 10H0.150391L3.91016 0.197266H5.09961L8.87305 10ZM6.18652 6.21973L4.64844 2.04297C4.59831 1.90625 4.54818 1.6875 4.49805 1.38672H4.4707C4.42513 1.66471 4.37272 1.88346 4.31348 2.04297L2.78906 6.21973H6.18652ZM15.1826 10H14.0615V8.90625H14.0342C13.5465 9.74479 12.8288 10.1641 11.8809 10.1641C11.1836 10.1641 10.6367 9.97949 10.2402 9.61035C9.84831 9.24121 9.65234 8.7513 9.65234 8.14062C9.65234 6.83268 10.4225 6.07161 11.9629 5.85742L14.0615 5.56348C14.0615 4.37402 13.5807 3.7793 12.6191 3.7793C11.776 3.7793 11.015 4.06641 10.3359 4.64062V3.49219C11.0241 3.05469 11.8171 2.83594 12.7148 2.83594C14.36 2.83594 15.1826 3.70638 15.1826 5.44727V10ZM14.0615 6.45898L12.373 6.69141C11.8535 6.76432 11.4616 6.89421 11.1973 7.08105C10.9329 7.26335 10.8008 7.58919 10.8008 8.05859C10.8008 8.40039 10.9215 8.68066 11.1631 8.89941C11.4092 9.11361 11.735 9.2207 12.1406 9.2207C12.6966 9.2207 13.1546 9.02702 13.5146 8.63965C13.8792 8.24772 14.0615 7.75326 14.0615 7.15625V6.45898Z"/>
</ToggleButton>
<Button x:Name="CloseButton" x:Uid="CloseButtonLocalizedText" AutomationProperties.Name="Close"
Padding="0" Click="CloseClick" Style="{ ThemeResource ButtonStyle}">
<Button x:Name="CloseButton"
x:Uid="SearchBox_Close"
Padding="0"
Click="CloseClick"
Style="{ThemeResource ButtonStyle}">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE711;" FontSize="12"/>
</Button>
</StackPanel>

View file

@ -1606,6 +1606,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return hstr;
}
hstring TermControl::GetProfileName() const
{
return _settings.ProfileName();
}
// Method Description:
// - Given a copy-able selection, get the selected text from the buffer and send it to the
// Windows Clipboard (CascadiaWin32:main.cpp).

View file

@ -61,6 +61,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
winrt::fire_and_forget UpdateSettings(Settings::IControlSettings newSettings);
hstring Title();
hstring GetProfileName() const;
bool CopySelectionToClipboard(bool trimTrailingWhitespace);
void PasteTextFromClipboard();

View file

@ -3,6 +3,7 @@
#include "pch.h"
#include <UIAutomationCore.h>
#include <LibraryResources.h>
#include "TermControlAutomationPeer.h"
#include "TermControl.h"
#include "TermControlAutomationPeer.g.cpp"
@ -77,7 +78,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
});
}
winrt::hstring TermControlAutomationPeer::GetClassNameCore() const
hstring TermControlAutomationPeer::GetClassNameCore() const
{
return L"TermControl";
}
@ -87,13 +88,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return AutomationControlType::Text;
}
winrt::hstring TermControlAutomationPeer::GetLocalizedControlTypeCore() const
hstring TermControlAutomationPeer::GetLocalizedControlTypeCore() const
{
// TODO GitHub #2142: Localize string
return L"TerminalControl";
return RS_(L"TerminalControl_ControlType");
}
winrt::Windows::Foundation::IInspectable TermControlAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
Windows::Foundation::IInspectable TermControlAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
{
switch (patternInterface)
{
@ -105,15 +105,41 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
}
AutomationOrientation TermControlAutomationPeer::GetOrientationCore() const
{
return AutomationOrientation::Vertical;
}
hstring TermControlAutomationPeer::GetNameCore() const
{
// fallback to title if profile name is empty
auto profileName = _termControl->GetProfileName();
if (profileName.empty())
{
return _termControl->Title();
}
return profileName;
}
hstring TermControlAutomationPeer::GetHelpTextCore() const
{
return _termControl->Title();
}
AutomationLiveSetting TermControlAutomationPeer::GetLiveSettingCore() const
{
return AutomationLiveSetting::Polite;
}
#pragma region ITextProvider
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
{
SAFEARRAY* pReturnVal;
THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal));
return WrapArrayOfTextRangeProviders(pReturnVal);
}
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
{
SAFEARRAY* pReturnVal;
THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal));
@ -152,7 +178,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return xutr.as<XamlAutomation::ITextRangeProvider>();
}
Windows::UI::Xaml::Automation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
{
UIA::SupportedTextSelection returnVal;
THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal));
@ -214,7 +240,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// - SAFEARRAY of UIA::UiaTextRange (ITextRangeProviders)
// Return Value:
// - com_array of Xaml Wrapped UiaTextRange (ITextRangeProviders)
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
{
// transfer ownership of UiaTextRanges to this new vector
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
@ -225,11 +251,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
auto parentProvider = this->ProviderFromPeer(*this);
for (int i = 0; i < count; i++)
{
auto xutr = winrt::make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
auto xutr = make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
vec.emplace_back(xutr.as<XamlAutomation::ITextRangeProvider>());
}
winrt::com_array<XamlAutomation::ITextRangeProvider> result{ vec };
com_array<XamlAutomation::ITextRangeProvider> result{ vec };
return result;
}

View file

@ -39,12 +39,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
::Microsoft::Console::Types::IControlAccessibilityInfo
{
public:
TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* owner);
TermControlAutomationPeer(Microsoft::Terminal::TerminalControl::implementation::TermControl* owner);
winrt::hstring GetClassNameCore() const;
winrt::Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
winrt::hstring GetLocalizedControlTypeCore() const;
winrt::Windows::Foundation::IInspectable GetPatternCore(winrt::Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const;
#pragma region FrameworkElementAutomationPeer
hstring GetClassNameCore() const;
Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
hstring GetLocalizedControlTypeCore() const;
Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const;
Windows::UI::Xaml::Automation::Peers::AutomationOrientation GetOrientationCore() const;
hstring GetNameCore() const;
hstring GetHelpTextCore() const;
Windows::UI::Xaml::Automation::Peers::AutomationLiveSetting GetLiveSettingCore() const;
#pragma endregion
#pragma region IUiaEventDispatcher
void SignalSelectionChanged() override;
@ -55,8 +61,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
#pragma region ITextProvider Pattern
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromPoint(Windows::Foundation::Point screenLocation);
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromChild(Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple childElement);
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetVisibleRanges();
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetSelection();
com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetVisibleRanges();
com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetSelection();
Windows::UI::Xaml::Automation::SupportedTextSelection SupportedTextSelection();
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
#pragma endregion

View file

@ -18,6 +18,7 @@
<ClCompile Include="TermControlUiaProvider.cpp" />
<ClCompile Include="UiaTextRange.cpp" />
<ClCompile Include="SearchBoxControl.cpp" />
<ClCompile Include="init.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
@ -26,12 +27,12 @@
<ClInclude Include="XamlUiaTextRange.h" />
<ClInclude Include="TermControlUiaProvider.hpp" />
<ClInclude Include="UiaTextRange.hpp" />
<ClCompile Include="SearchBoxControl.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="TermControl.idl" />
<Midl Include="TermControlAutomationPeer.idl" />
<Midl Include="SearchBoxControl.idl" />
<Midl Include="TSFInputControl.idl" />
</ItemGroup>
<ItemGroup>
<None Include="TerminalControl.def" />
@ -43,4 +44,9 @@
<ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources/Resources.language-en.resw">
<Filter>Resources</Filter>
</PRIResource>
</ItemGroup>
</Project>

View file

@ -26,6 +26,8 @@ namespace Microsoft.Terminal.Settings
// for specifically the control.
interface IControlSettings requires Microsoft.Terminal.Settings.ICoreSettings
{
String ProfileName;
Boolean UseAcrylic;
Double TintOpacity;
ScrollbarState ScrollState;

View file

@ -28,6 +28,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },
_wordDelimiters{ DEFAULT_WORD_DELIMITERS },
_copyOnSelect{ false },
_profileName{},
_useAcrylic{ false },
_tintOpacity{ 0.5 },
_padding{ DEFAULT_PADDING },
@ -196,6 +197,16 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_copyOnSelect = value;
}
void TerminalSettings::ProfileName(hstring const& value)
{
_profileName = value;
}
hstring TerminalSettings::ProfileName()
{
return _profileName;
}
bool TerminalSettings::UseAcrylic() noexcept
{
return _useAcrylic;

View file

@ -55,6 +55,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
void CopyOnSelect(bool value) noexcept;
// ------------------------ End of Core Settings -----------------------
hstring ProfileName();
void ProfileName(hstring const& value);
bool UseAcrylic() noexcept;
void UseAcrylic(bool value) noexcept;
double TintOpacity() noexcept;
@ -120,6 +122,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
uint32_t _cursorHeight;
hstring _wordDelimiters;
hstring _profileName;
bool _useAcrylic;
double _tintOpacity;
hstring _fontFace;