Browse Source

Fix missing root automation peer in x11/atspi (#20775)

* Fix missing root automation peer in x11/atspi

* Root nodes are special case; fix GetIndexInParentAsync to handle root nodes since their parents == null.
pull/19747/merge
Jumar Macato 3 weeks ago
committed by GitHub
parent
commit
d957cb391e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 16
      src/Avalonia.FreeDesktop.AtSpi/Handlers/AtSpiAccessibleHandler.cs
  2. 7
      src/Avalonia.X11/X11AtSpiAccessibility.cs
  3. 12
      src/Avalonia.X11/X11Window.cs

16
src/Avalonia.FreeDesktop.AtSpi/Handlers/AtSpiAccessibleHandler.cs

@ -63,6 +63,22 @@ namespace Avalonia.FreeDesktop.AtSpi.Handlers
public ValueTask<int> GetIndexInParentAsync()
{
// Window nodes are children of the ApplicationAtSpiNode, but their
// internal Parent field is null (they are attached with parent: null).
// Mirror the Parent property's special case so that backward path
// walks (e.g. accerciser's get_index_in_parent) work correctly.
if (node is RootAtSpiNode { AppRoot: { } appRoot })
{
var windows = appRoot.WindowChildren;
for (var i = 0; i < windows.Count; i++)
{
if (ReferenceEquals(windows[i], node))
return ValueTask.FromResult(i);
}
return ValueTask.FromResult(-1);
}
var parent = node.Parent;
if (parent is null)
return ValueTask.FromResult(-1);

7
src/Avalonia.X11/X11AtSpiAccessibility.cs

@ -142,8 +142,11 @@ namespace Avalonia.X11
{
try
{
if (window.InputRoot.RootElement is Control control)
return ControlAutomationPeer.CreatePeerForElement(control);
if (window.InputRoot.FocusRoot is Control control)
{
var peer = ControlAutomationPeer.CreatePeerForElement(control);
return peer?.GetAutomationRoot() ?? peer;
}
}
catch (Exception e)
{

12
src/Avalonia.X11/X11Window.cs

@ -1029,9 +1029,10 @@ namespace Avalonia.X11
// Remove from AT-SPI tree before closing
_platform.UntrackWindow(this);
if (_platform.AtSpiServer is { } atSpiServer
&& _inputRoot?.RootElement is Control atSpiControl)
&& _inputRoot?.FocusRoot is Control atSpiControl)
{
var atSpiPeer = atSpiControl.GetAutomationPeer();
var atSpiPeer = atSpiControl.GetAutomationPeer()?.GetAutomationRoot()
?? atSpiControl.GetAutomationPeer();
if (atSpiPeer is not null)
atSpiServer.RemoveWindow(atSpiPeer);
}
@ -1125,11 +1126,12 @@ namespace Avalonia.X11
_platform.TrackWindow(this);
if (_platform.AtSpiServer is { } server
&& _inputRoot?.RootElement is Control c)
&& _inputRoot?.FocusRoot is Control c)
{
var peer = Avalonia.Automation.Peers.ControlAutomationPeer.CreatePeerForElement(c);
if (peer is not null)
server.AddWindow(peer);
var rootPeer = peer?.GetAutomationRoot() ?? peer;
if (rootPeer is not null)
server.AddWindow(rootPeer);
}
}

Loading…
Cancel
Save