Browse Source

fix: Button should not fire the click event on the space key when it is not active (#16619)

* test: Check that the button should not fire the click event on the space key when it is not active

* fix: Button should not fire the click event on the space key when it is not active

* fix: Address review
workgroupengineering 1 year ago
parent
commit
44528a8198
2 changed files with 33 additions and 5 deletions
  1. 5 5
      src/Avalonia.Controls/Button.cs
  2. 28 0
      tests/Avalonia.Controls.UnitTests/ButtonTests.cs

+ 5 - 5
src/Avalonia.Controls/Button.cs

@@ -289,8 +289,9 @@ namespace Avalonia.Controls
                     OnClick();
                     e.Handled = true;
                     break;
-
                 case Key.Space:
+                    // Avoid handling Space if the button isn't focused: a child TextBox might need it for text input
+                    if (IsFocused)
                     {
                         if (ClickMode == ClickMode.Press)
                         {
@@ -299,22 +300,21 @@ namespace Avalonia.Controls
 
                         IsPressed = true;
                         e.Handled = true;
-                        break;
                     }
-
+                    break;
                 case Key.Escape when Flyout != null:
                     // If Flyout doesn't have focusable content, close the flyout here
                     CloseFlyout();
                     break;
             }
-
             base.OnKeyDown(e);
         }
 
         /// <inheritdoc/>
         protected override void OnKeyUp(KeyEventArgs e)
         {
-            if (e.Key == Key.Space)
+            // Avoid handling Space if the button isn't focused: a child TextBox might need it for text input
+            if (e.Key == Key.Space && IsFocused)
             {
                 if (ClickMode == ClickMode.Release)
                 {

+ 28 - 0
tests/Avalonia.Controls.UnitTests/ButtonTests.cs

@@ -511,11 +511,39 @@ namespace Avalonia.Controls.UnitTests
             (target as IClickableControl).RaiseClick();
         }
 
+        [Fact]
+        void Should_Not_Fire_Click_Event_On_Space_Key_When_It_Is_Not_Focus()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                var raised = 0;
+                var target = new TextBox();
+                var button = new Button()
+                {
+                    Content = target,
+                };
+
+                var window = new Window { Content = button };
+                window.Show();
+
+                button.Click += (s, e) => ++raised;
+                target.Focus();
+                target.RaiseEvent(CreateKeyDownEvent(Key.Space));
+                target.RaiseEvent(CreateKeyUpEvent(Key.Space));
+                Assert.Equal(0, raised);
+            }
+        }
+
         private KeyEventArgs CreateKeyDownEvent(Key key, Interactive source = null)
         {
             return new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = key, Source = source };
         }
 
+        private KeyEventArgs CreateKeyUpEvent(Key key, Interactive source = null)
+        {
+            return new KeyEventArgs { RoutedEvent = InputElement.KeyUpEvent, Key = key, Source = source };
+        }
+
         private void RaisePointerPressed(Button button, int clickCount, MouseButton mouseButton, Point position)
         {
             _helper.Down(button, mouseButton, position, clickCount: clickCount);