From 85fff4a2320d87236c3f850b5de87129e6587458 Mon Sep 17 00:00:00 2001 From: ahopper Date: Wed, 18 Sep 2024 13:28:21 +0100 Subject: [PATCH] fix Automation.HelpText on windows (#17030) * fix Automation.HelpText on windows * change breaking abstract to virtual * only fall back to tooltip if string * remove duplicate override --------- Co-authored-by: Benedikt Stebner --- .../Automation/AutomationElementIdentifiers.cs | 6 ++++++ .../Automation/Peers/AutomationPeer.cs | 6 ++++++ .../Automation/Peers/ControlAutomationPeer.cs | 10 ++++++++++ .../Automation/Peers/InteropAutomationPeer.cs | 1 + .../Peers/UnrealizedElementAutomationPeer.cs | 1 + .../Avalonia.Win32/Automation/AutomationNode.cs | 2 ++ 6 files changed, 26 insertions(+) diff --git a/src/Avalonia.Controls/Automation/AutomationElementIdentifiers.cs b/src/Avalonia.Controls/Automation/AutomationElementIdentifiers.cs index 4566cd9db5..574979c77b 100644 --- a/src/Avalonia.Controls/Automation/AutomationElementIdentifiers.cs +++ b/src/Avalonia.Controls/Automation/AutomationElementIdentifiers.cs @@ -24,5 +24,11 @@ namespace Avalonia.Automation /// by the method. /// public static AutomationProperty NameProperty { get; } = new AutomationProperty(); + + /// + /// Identifies the helpText automation property. The class name property value is returned + /// by the method. + /// + public static AutomationProperty HelpTextProperty { get; } = new AutomationProperty(); } } diff --git a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs index bda9a91183..7a53ee001d 100644 --- a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs @@ -112,6 +112,11 @@ namespace Avalonia.Automation.Peers /// Gets text that describes the element that is associated with this automation peer. /// public string GetName() => GetNameCore() ?? string.Empty; + + /// + /// Gets text that provides help for the element that is associated with this automation peer. + /// + public string GetHelpText() => GetHelpTextCore() ?? string.Empty; /// /// Gets the that is the parent of this . @@ -250,6 +255,7 @@ namespace Avalonia.Automation.Peers protected abstract string GetClassNameCore(); protected abstract AutomationPeer? GetLabeledByCore(); protected abstract string? GetNameCore(); + protected virtual string? GetHelpTextCore() => null; protected abstract AutomationPeer? GetParentCore(); protected abstract bool HasKeyboardFocusCore(); protected abstract bool IsContentElementCore(); diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs index 0c043e7577..0dff2db3c2 100644 --- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs @@ -116,7 +116,17 @@ namespace Avalonia.Automation.Peers return result; } + protected override string? GetHelpTextCore() + { + var result = AutomationProperties.GetHelpText(Owner); + if (string.IsNullOrWhiteSpace(result)) + { + result = ToolTip.GetTip(Owner) as string; + } + + return result; + } protected override AutomationPeer? GetParentCore() { EnsureConnected(); diff --git a/src/Avalonia.Controls/Automation/Peers/InteropAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/InteropAutomationPeer.cs index 367c7804c3..5dfd507e1b 100644 --- a/src/Avalonia.Controls/Automation/Peers/InteropAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/InteropAutomationPeer.cs @@ -28,6 +28,7 @@ internal class InteropAutomationPeer : AutomationPeer protected override string GetClassNameCore() => throw new NotImplementedException(); protected override AutomationPeer? GetLabeledByCore() => throw new NotImplementedException(); protected override string? GetNameCore() => throw new NotImplementedException(); + protected override string? GetHelpTextCore() => throw new NotImplementedException(); protected override IReadOnlyList GetOrCreateChildrenCore() => throw new NotImplementedException(); protected override AutomationPeer? GetParentCore() => _parent; protected override bool HasKeyboardFocusCore() => throw new NotImplementedException(); diff --git a/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs index 56d5aa79ae..0dabb1b069 100644 --- a/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs @@ -20,5 +20,6 @@ namespace Avalonia.Automation.Peers protected override void SetFocusCore() { } protected override bool ShowContextMenuCore() => false; protected internal override bool TrySetParent(AutomationPeer? parent) => false; + } } diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs index 0a6f4d8d8e..00b4f179c7 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs @@ -28,6 +28,7 @@ namespace Avalonia.Win32.Automation { AutomationElementIdentifiers.BoundingRectangleProperty, UiaPropertyId.BoundingRectangle }, { AutomationElementIdentifiers.ClassNameProperty, UiaPropertyId.ClassName }, { AutomationElementIdentifiers.NameProperty, UiaPropertyId.Name }, + { AutomationElementIdentifiers.HelpTextProperty, UiaPropertyId.HelpText }, { ExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty, UiaPropertyId.ExpandCollapseExpandCollapseState }, { RangeValuePatternIdentifiers.IsReadOnlyProperty, UiaPropertyId.RangeValueIsReadOnly}, { RangeValuePatternIdentifiers.MaximumProperty, UiaPropertyId.RangeValueMaximum }, @@ -122,6 +123,7 @@ namespace Avalonia.Win32.Automation UiaPropertyId.IsOffscreen => InvokeSync(() => Peer.IsOffscreen()), UiaPropertyId.LocalizedControlType => InvokeSync(() => Peer.GetLocalizedControlType()), UiaPropertyId.Name => InvokeSync(() => Peer.GetName()), + UiaPropertyId.HelpText => InvokeSync(() => Peer.GetHelpText()), UiaPropertyId.ProcessId => Process.GetCurrentProcess().Id, UiaPropertyId.RuntimeId => _runtimeId, _ => null,