Repository: AvaloniaUI/Avalonia

Issue:
AccessKeyHandler should not match on disabled elements
## Describe the bug
Multiple input elements can be registered with the same access key. When the `AccessKeyHandler` attempts to locate the element associated with a key, the logic does not consider the enabled state of the element and will return the first match even if it is disabled and the second match is enabled.

## To Reproduce
Steps to reproduce the behavior:

1. Create two button controls with the same access key; e.g., "_Button1" and "_Button2"
2. Add an event handler for each button to know when it is invoked.
3. Press `Alt+B` to initiate the `AccessKeyHandler` and "_Button1" will be invoked.
4. Disable "_Button1"
5. Press `Alt+B` to initiate the `AccessKeyHandler` and nothing happens because the access key was sent to "_Button1", but it is disabled.

## Expected behavior
In Step 5 the access key should have invoked "_Button2" since it was the better match.


## Additional context
- WPF's `AccessKeyManager` ignores disabled elements when attempting to find a match, so this change will bring Avalonia closer to matching WPF's behavior.



Hints:

Patch:
diff --git a/src/Avalonia.Base/Input/AccessKeyHandler.cs b/src/Avalonia.Base/Input/AccessKeyHandler.cs
index 38692d8b77d..fe5e2c46a21 100644
--- a/src/Avalonia.Base/Input/AccessKeyHandler.cs
+++ b/src/Avalonia.Base/Input/AccessKeyHandler.cs
@@ -183,7 +183,8 @@ protected virtual void OnKeyDown(object? sender, KeyEventArgs e)
                 var text = e.Key.ToString();
                 var matches = _registered
                     .Where(x => string.Equals(x.AccessKey, text, StringComparison.OrdinalIgnoreCase)
-                        && x.Element.IsEffectivelyVisible)
+                        && x.Element.IsEffectivelyVisible
+                        && x.Element.IsEffectivelyEnabled)
                     .Select(x => x.Element);
 
                 // If the menu is open, only match controls in the menu's visual tree.


Test patch:
diff --git a/tests/Avalonia.Base.UnitTests/Input/AccessKeyHandlerTests.cs b/tests/Avalonia.Base.UnitTests/Input/AccessKeyHandlerTests.cs
index 4d8ece4ddaa..ed1061e85a9 100644
--- a/tests/Avalonia.Base.UnitTests/Input/AccessKeyHandlerTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Input/AccessKeyHandlerTests.cs
@@ -165,6 +165,30 @@ public void Should_Raise_AccessKeyPressed_For_Registered_Access_Key()
             Assert.Equal(1, raised);
         }
 
+        [Fact]
+        public void Should_Not_Raise_AccessKeyPressed_For_Registered_Access_Key_When_Not_Effectively_Enabled()
+        {
+            var button = new Button();
+            var root = new TestRoot(button) { IsEnabled = false };
+            var target = new AccessKeyHandler();
+            var raised = 0;
+
+            target.SetOwner(root);
+            target.Register('A', button);
+            button.AddHandler(AccessKeyHandler.AccessKeyPressedEvent, (s, e) => ++raised);
+
+            KeyDown(root, Key.LeftAlt);
+            Assert.Equal(0, raised);
+
+            KeyDown(root, Key.A, KeyModifiers.Alt);
+            Assert.Equal(0, raised);
+
+            KeyUp(root, Key.A, KeyModifiers.Alt);
+            KeyUp(root, Key.LeftAlt);
+
+            Assert.Equal(0, raised);
+        }
+
         [Fact]
         public void Should_Open_MainMenu_On_Alt_KeyUp()
         {