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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with
28 additions and
7 deletions
src/Avalonia.FreeDesktop.AtSpi/Handlers/AtSpiAccessibleHandler.cs
src/Avalonia.X11/X11AtSpiAccessibility.cs
src/Avalonia.X11/X11Window.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 ) ;
@ -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 )
{
@ -1029,9 +1029,10 @@ namespace Avalonia.X11
// Remove from AT-SPI tree before closing
_ platform . UntrackWindow ( this ) ;
if ( _ platform . AtSpiServer is { } atSpiServer
& & _ inputRoot ? . RootElemen t is Control atSpiControl )
& & _ inputRoot ? . Focus Root 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 ? . RootElemen t is Control c )
& & _ inputRoot ? . Focus Root 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 ) ;
}
}