From 80b0c3d54c8247a6b87170a2b288e86e8cb42838 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 3 Nov 2022 00:24:17 +0100 Subject: [PATCH 01/13] Allow AccessibilityView to override peer. Setting `AutomationProperties.AccessibilityView` can now override the `IsControlElementCore` and `IsContentElementCore` settings returned from the automation peer. --- .../Automation/AutomationProperties.cs | 8 ++++++-- .../Automation/Peers/AutomationPeer.cs | 14 ++++++++++++-- .../Automation/Peers/ControlAutomationPeer.cs | 16 ++++++++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/Automation/AutomationProperties.cs b/src/Avalonia.Controls/Automation/AutomationProperties.cs index c20af148b8..a192ef6420 100644 --- a/src/Avalonia.Controls/Automation/AutomationProperties.cs +++ b/src/Avalonia.Controls/Automation/AutomationProperties.cs @@ -9,6 +9,11 @@ namespace Avalonia.Automation /// public enum AccessibilityView { + /// + /// The control's view is defined by its automation peer. + /// + Default, + /// /// The control is included in the Raw view of the automation tree. /// @@ -44,8 +49,7 @@ namespace Avalonia.Automation public static readonly AttachedProperty AccessibilityViewProperty = AvaloniaProperty.RegisterAttached( "AccessibilityView", - typeof(AutomationProperties), - defaultValue: AccessibilityView.Content); + typeof(AutomationProperties)); /// /// Defines the AutomationProperties.AccessKey attached property diff --git a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs index 71421ac136..3d3fe35d29 100644 --- a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs @@ -128,13 +128,13 @@ namespace Avalonia.Automation.Peers /// Gets a value that indicates whether the element that is associated with this automation /// peer contains data that is presented to the user. /// - public bool IsContentElement() => IsControlElement() && IsContentElementCore(); + public bool IsContentElement() => IsContentElementOverrideCore(); /// /// Gets a value that indicates whether the element is understood by the user as /// interactive or as contributing to the logical structure of the control in the GUI. /// - public bool IsControlElement() => IsControlElementCore(); + public bool IsControlElement() => IsControlElementOverrideCore(); /// /// Gets a value indicating whether the control is enabled for user interaction. @@ -247,6 +247,16 @@ namespace Avalonia.Automation.Peers return GetAutomationControlTypeCore(); } + protected virtual bool IsContentElementOverrideCore() + { + return IsControlElement() && IsContentElementCore(); + } + + protected virtual bool IsControlElementOverrideCore() + { + return IsControlElementCore(); + } + protected virtual object? GetProviderCore(Type providerType) { return providerType.IsAssignableFrom(this.GetType()) ? this : null; diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs index a93d3fa7dd..25172b2d1c 100644 --- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs @@ -149,8 +149,8 @@ namespace Avalonia.Automation.Peers protected override Rect GetBoundingRectangleCore() => GetBounds(Owner); protected override string GetClassNameCore() => Owner.GetType().Name; protected override bool HasKeyboardFocusCore() => Owner.IsFocused; - protected override bool IsContentElementCore() => AutomationProperties.GetAccessibilityView(Owner) >= AccessibilityView.Content; - protected override bool IsControlElementCore() => AutomationProperties.GetAccessibilityView(Owner) >= AccessibilityView.Control; + protected override bool IsContentElementCore() => true; + protected override bool IsControlElementCore() => true; protected override bool IsEnabledCore() => Owner.IsEnabled; protected override bool IsKeyboardFocusableCore() => Owner.Focusable; protected override void SetFocusCore() => Owner.Focus(); @@ -160,6 +160,18 @@ namespace Avalonia.Automation.Peers return AutomationProperties.GetControlTypeOverride(Owner) ?? GetAutomationControlTypeCore(); } + protected override bool IsContentElementOverrideCore() + { + var view = AutomationProperties.GetAccessibilityView(Owner); + return view == AccessibilityView.Default ? IsContentElementCore() : view >= AccessibilityView.Content; + } + + protected override bool IsControlElementOverrideCore() + { + var view = AutomationProperties.GetAccessibilityView(Owner); + return view == AccessibilityView.Default ? IsControlElementCore() : view >= AccessibilityView.Control; + } + private static Rect GetBounds(Control control) { var root = control.GetVisualRoot(); From 9a50b9ee0ccab7d96bac6e144c55aa0422303f02 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 3 Nov 2022 15:36:02 +0100 Subject: [PATCH 02/13] Added integration tests for tapped gestures. Some skipped on Windows as right button actions aren't supported by WinAppDriver. --- samples/IntegrationTestApp/MainWindow.axaml | 12 ++ .../IntegrationTestApp/MainWindow.axaml.cs | 10 ++ .../GestureTests.cs | 151 ++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 tests/Avalonia.IntegrationTests.Appium/GestureTests.cs diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml index 3377979199..2a0a758852 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml +++ b/samples/IntegrationTestApp/MainWindow.axaml @@ -69,6 +69,18 @@ + + + + + + + + + + diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index f72f83fcb8..791e221d50 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -4,6 +4,7 @@ using Avalonia; using Avalonia.Automation; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.VisualTree; @@ -20,6 +21,15 @@ namespace IntegrationTestApp this.AttachDevTools(); AddHandler(Button.ClickEvent, OnButtonClick); ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); + + var gestureBorder = this.GetControl("GestureBorder"); + var lastGesture = this.GetControl("LastGesture"); + var clearLastGesture = this.GetControl + - + + + + diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index 791e221d50..e8fb455c35 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -18,18 +18,10 @@ namespace IntegrationTestApp { InitializeComponent(); InitializeViewMenu(); + InitializeGesturesTab(); this.AttachDevTools(); AddHandler(Button.ClickEvent, OnButtonClick); ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); - - var gestureBorder = this.GetControl("GestureBorder"); - var lastGesture = this.GetControl("LastGesture"); - var clearLastGesture = this.GetControl