diff --git a/native/Avalonia.Native/src/OSX/automation.mm b/native/Avalonia.Native/src/OSX/automation.mm index 0f2ae3768c..84b348e0c2 100644 --- a/native/Avalonia.Native/src/OSX/automation.mm +++ b/native/Avalonia.Native/src/OSX/automation.mm @@ -358,6 +358,20 @@ return [AvnAccessibilityElement acquire:rootPeer]; } +- (id)accessibilityHorizontalScrollBar +{ + if (_peer == nullptr) + return nil; + return [AvnAccessibilityElement acquire:_peer->ScrollProvider_GetHorizontalScrollBar()]; +} + +- (id)accessibilityVerticalScrollBar +{ + if (_peer == nullptr) + return nil; + return [AvnAccessibilityElement acquire:_peer->ScrollProvider_GetVerticalScrollBar()]; +} + - (BOOL)isAccessibilityExpanded { if (!_peer->IsExpandCollapseProvider()) diff --git a/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs index 38fe21bf1f..9e62cf0c55 100644 --- a/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs @@ -14,6 +14,12 @@ namespace Avalonia.Automation.Peers public new ScrollViewer Owner => (ScrollViewer)base.Owner; + internal AutomationPeer? GetHorizontalScrollBarPeer() + => Owner.HorizontalScrollBar is { } scrollBar ? GetOrCreate(scrollBar) : null; + + internal AutomationPeer? GetVerticalScrollBarPeer() + => Owner.VerticalScrollBar is { } scrollBar ? GetOrCreate(scrollBar) : null; + public bool HorizontallyScrollable { get => MathUtilities.GreaterThan(Owner.Extent.Width, Owner.Viewport.Width); diff --git a/src/Avalonia.Controls/ScrollViewer.cs b/src/Avalonia.Controls/ScrollViewer.cs index 96580d9d49..57b6664440 100644 --- a/src/Avalonia.Controls/ScrollViewer.cs +++ b/src/Avalonia.Controls/ScrollViewer.cs @@ -169,6 +169,18 @@ namespace Avalonia.Controls private Size _smallChange = new Size(DefaultSmallChange, DefaultSmallChange); private bool _isExpanded; private IDisposable? _scrollBarExpandSubscription; + private ScrollBar? _horizontalScrollBar; + private ScrollBar? _verticalScrollBar; + + /// + /// Gets the horizontal scroll bar from the applied template, if any. + /// + internal ScrollBar? HorizontalScrollBar => _horizontalScrollBar; + + /// + /// Gets the vertical scroll bar from the applied template, if any. + /// + internal ScrollBar? VerticalScrollBar => _verticalScrollBar; /// /// Initializes a new instance of the class. @@ -834,6 +846,9 @@ namespace Avalonia.Controls var horizontalScrollBar = e.NameScope.Find("PART_HorizontalScrollBar"); var verticalScrollBar = e.NameScope.Find("PART_VerticalScrollBar"); + _horizontalScrollBar = horizontalScrollBar; + _verticalScrollBar = verticalScrollBar; + var horizontalExpanded = GetExpandedObservable(horizontalScrollBar); var verticalExpanded = GetExpandedObservable(verticalScrollBar); diff --git a/src/Avalonia.Native/AvnAutomationPeer.cs b/src/Avalonia.Native/AvnAutomationPeer.cs index b5e9641050..dae105c8a4 100644 --- a/src/Avalonia.Native/AvnAutomationPeer.cs +++ b/src/Avalonia.Native/AvnAutomationPeer.cs @@ -182,6 +182,12 @@ namespace Avalonia.Native public int IsSelectionItemProvider() => IsProvider(); public int SelectionItemProvider_IsSelected() => SelectionItemProvider.IsSelected.AsComBool(); + + public IAvnAutomationPeer? ScrollProvider_GetHorizontalScrollBar() + => _inner is ScrollViewerAutomationPeer scrollViewer ? Wrap(scrollViewer.GetHorizontalScrollBarPeer()) : null; + + public IAvnAutomationPeer? ScrollProvider_GetVerticalScrollBar() + => _inner is ScrollViewerAutomationPeer scrollViewer ? Wrap(scrollViewer.GetVerticalScrollBarPeer()) : null; public int IsToggleProvider() => IsProvider(); public int ToggleProvider_GetToggleState() => (int)ToggleProvider.ToggleState; diff --git a/src/Avalonia.Native/avn.idl b/src/Avalonia.Native/avn.idl index 14d77d17d1..3762126989 100644 --- a/src/Avalonia.Native/avn.idl +++ b/src/Avalonia.Native/avn.idl @@ -1317,7 +1317,10 @@ interface IAvnAutomationPeer : IUnknown bool IsSelectionItemProvider(); bool SelectionItemProvider_IsSelected(); - + + IAvnAutomationPeer* ScrollProvider_GetHorizontalScrollBar(); + IAvnAutomationPeer* ScrollProvider_GetVerticalScrollBar(); + bool IsToggleProvider(); int ToggleProvider_GetToggleState(); void ToggleProvider_Toggle();