Browse Source

Expose tree item selection to macOS accessibility (#21598)

TreeViewItemAutomationPeer implements ISelectionItemProvider, and AvnAccessibilityElement maps setAccessibilitySelected to it, so AX clients can select a TreeViewItem.
pull/21602/head
Jumar Macato 4 months ago
committed by GitHub
parent
commit
e08c7f8149
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      native/Avalonia.Native/src/OSX/automation.mm
  2. 49
      src/Avalonia.Controls/Automation/Peers/TreeViewItemAutomationPeer.cs
  3. 1
      src/Avalonia.Native/AvnAutomationPeer.cs
  4. 1
      src/Avalonia.Native/avn.idl

10
native/Avalonia.Native/src/OSX/automation.mm

@ -474,6 +474,12 @@
return NO; return NO;
} }
- (void)setAccessibilitySelected:(BOOL)accessibilitySelected
{
if (accessibilitySelected && _peer->IsSelectionItemProvider())
_peer->SelectionItemProvider_Select();
}
- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector - (BOOL)isAccessibilitySelectorAllowed:(SEL)selector
{ {
if (selector == @selector(setAccessibilityValue:)) if (selector == @selector(setAccessibilityValue:))
@ -492,6 +498,10 @@
{ {
return _peer->IsInvokeProvider() || _peer->IsExpandCollapseProvider() || _peer->IsToggleProvider(); return _peer->IsInvokeProvider() || _peer->IsExpandCollapseProvider() || _peer->IsToggleProvider();
} }
else if (selector == @selector(setAccessibilitySelected:))
{
return _peer->IsSelectionItemProvider();
}
else if (selector == @selector(accessibilityPerformIncrement) || else if (selector == @selector(accessibilityPerformIncrement) ||
selector == @selector(accessibilityPerformDecrement) || selector == @selector(accessibilityPerformDecrement) ||
selector == @selector(accessibilityMinValue) || selector == @selector(accessibilityMinValue) ||

49
src/Avalonia.Controls/Automation/Peers/TreeViewItemAutomationPeer.cs

@ -1,14 +1,59 @@
using Avalonia.Automation.Provider;
using Avalonia.Controls; using Avalonia.Controls;
namespace Avalonia.Automation.Peers; namespace Avalonia.Automation.Peers;
public class TreeViewItemAutomationPeer : ItemsControlAutomationPeer public class TreeViewItemAutomationPeer : ItemsControlAutomationPeer,
ISelectionItemProvider
{ {
public TreeViewItemAutomationPeer(TreeViewItem owner) public TreeViewItemAutomationPeer(TreeViewItem owner)
: base(owner) : base(owner)
{ {
} }
public bool IsSelected => Owner.GetValue(TreeViewItem.IsSelectedProperty);
public ISelectionProvider? SelectionContainer
{
get
{
if (Owner is TreeViewItem { TreeViewOwner: { } treeView })
{
var parentPeer = GetOrCreate(treeView);
return parentPeer.GetProvider<ISelectionProvider>();
}
return null;
}
}
public void Select()
{
EnsureEnabled();
if (Owner is TreeViewItem item)
{
item.TreeViewOwner?.SelectedItems.Clear();
item.IsSelected = true;
}
}
void ISelectionItemProvider.AddToSelection()
{
EnsureEnabled();
if (Owner is TreeViewItem item)
item.IsSelected = true;
}
void ISelectionItemProvider.RemoveFromSelection()
{
EnsureEnabled();
if (Owner is TreeViewItem item)
item.IsSelected = false;
}
protected override AutomationControlType GetAutomationControlTypeCore() protected override AutomationControlType GetAutomationControlTypeCore()
{ {
return AutomationControlType.TreeItem; return AutomationControlType.TreeItem;

1
src/Avalonia.Native/AvnAutomationPeer.cs

@ -187,6 +187,7 @@ namespace Avalonia.Native
public int IsSelectionItemProvider() => IsProvider<ISelectionItemProvider>(); public int IsSelectionItemProvider() => IsProvider<ISelectionItemProvider>();
public int SelectionItemProvider_IsSelected() => SelectionItemProvider.IsSelected.AsComBool(); public int SelectionItemProvider_IsSelected() => SelectionItemProvider.IsSelected.AsComBool();
public void SelectionItemProvider_Select() => SelectionItemProvider.Select();
public IAvnAutomationPeer? ScrollProvider_GetHorizontalScrollBar() public IAvnAutomationPeer? ScrollProvider_GetHorizontalScrollBar()
=> _inner is ScrollViewerAutomationPeer scrollViewer ? Wrap(scrollViewer.GetHorizontalScrollBarPeer()) : null; => _inner is ScrollViewerAutomationPeer scrollViewer ? Wrap(scrollViewer.GetHorizontalScrollBarPeer()) : null;

1
src/Avalonia.Native/avn.idl

@ -1318,6 +1318,7 @@ interface IAvnAutomationPeer : IUnknown
bool IsSelectionItemProvider(); bool IsSelectionItemProvider();
bool SelectionItemProvider_IsSelected(); bool SelectionItemProvider_IsSelected();
void SelectionItemProvider_Select();
IAvnAutomationPeer* ScrollProvider_GetHorizontalScrollBar(); IAvnAutomationPeer* ScrollProvider_GetHorizontalScrollBar();
IAvnAutomationPeer* ScrollProvider_GetVerticalScrollBar(); IAvnAutomationPeer* ScrollProvider_GetVerticalScrollBar();

Loading…
Cancel
Save