Browse Source

Fix: TalkBack should highlight controls instead of their ancestors (#21654)

* Fix: TalkBack should highlight controls instead of their ancestors

* Fix: make parent controls navigable for specific types

---------

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/21710/head
Isabelle Santin 3 months ago
committed by GitHub
parent
commit
0f4fb6e71a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 45
      src/Android/Avalonia.Android/AvaloniaAccessHelper.cs
  2. 2
      src/Avalonia.Controls/Automation/Peers/EmbeddableControlRootAutomationPeer.cs

45
src/Android/Avalonia.Android/AvaloniaAccessHelper.cs

@ -8,13 +8,42 @@ using Avalonia.Android.Automation;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Java.Lang;
namespace Avalonia.Android
{
internal class AvaloniaAccessHelper : ExploreByTouchHelper
{
private static readonly HashSet<AutomationControlType> s_containerTypes =
new HashSet<AutomationControlType>()
{
AutomationControlType.Calendar,
AutomationControlType.ComboBoxItem,
AutomationControlType.Custom,
AutomationControlType.DataGrid,
AutomationControlType.DataItem,
AutomationControlType.Document,
AutomationControlType.Expander,
AutomationControlType.Group,
AutomationControlType.List,
AutomationControlType.ListItem,
AutomationControlType.Menu,
AutomationControlType.MenuBar,
AutomationControlType.MenuItem,
AutomationControlType.None,
AutomationControlType.Pane,
AutomationControlType.ScrollViewer,
AutomationControlType.SplitButton,
AutomationControlType.Tab,
AutomationControlType.TabItem,
AutomationControlType.Table,
AutomationControlType.TitleBar,
AutomationControlType.ToolBar,
AutomationControlType.Tree,
AutomationControlType.TreeItem,
AutomationControlType.Window,
};
private readonly Dictionary<int, AutomationPeer> _peers;
private readonly Dictionary<AutomationPeer, int> _peerIds;
@ -109,7 +138,17 @@ namespace Avalonia.Android
AutomationPeer? peer = embeddedRootProvider?.GetPeerFromPoint(p);
if (peer is not null)
{
GetOrCreateNodeInfoProvidersFromPeer(peer, out int virtualViewId);
int virtualViewId;
if (peer.GetParent() is AutomationPeer parent &&
!s_containerTypes.Contains(parent.GetAutomationControlType()))
{
GetOrCreateNodeInfoProvidersFromPeer(parent, out virtualViewId);
}
else
{
GetOrCreateNodeInfoProvidersFromPeer(peer, out virtualViewId);
}
return virtualViewId == 0 ? InvalidId : virtualViewId;
}
else
@ -199,7 +238,7 @@ namespace Avalonia.Android
nodeInfo.Enabled = peer.IsEnabled();
// Control focus state
bool canFocusAtAll = peer.IsContentElement() && !peer.IsOffscreen();
bool canFocusAtAll = peer.IsControlElement() && !peer.IsOffscreen();
nodeInfo.ScreenReaderFocusable = canFocusAtAll;
nodeInfo.Focusable = canFocusAtAll && peer.IsKeyboardFocusable();

2
src/Avalonia.Controls/Automation/Peers/EmbeddableControlRootAutomationPeer.cs

@ -33,7 +33,7 @@ namespace Avalonia.Controls.Automation.Peers
public AutomationPeer? GetPeerFromPoint(Point p)
{
var hit = Owner.GetVisualAt(p)?.FindAncestorOfType<Control>();
var hit = Owner.GetVisualAt(p)?.FindAncestorOfType<Control>(includeSelf: true);
if (hit is null)
return null;

Loading…
Cancel
Save