Browse Source

fix(controls): stop HotKeyManager from executing on hidden controls (#21714)

- Added a check for 'target.IsEffectivelyVisible' inside 'HotkeyCommandWrapper.CanExecute'.
- Prevents HotKey from globally triggering and swallowing keyboard input when the host control or its parent panels are invisible (IsVisible="False").
- Added a corresponding unit test to verify input routing for hidden clickable controls.

Closes #21708

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/21812/head
Autumn 2 months ago
committed by GitHub
parent
commit
6644982306
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      src/Avalonia.Controls/HotkeyManager.cs
  2. 31
      tests/Avalonia.Controls.UnitTests/HotKeyedControlsTests.cs

12
src/Avalonia.Controls/HotkeyManager.cs

@ -38,8 +38,18 @@ namespace Avalonia.Controls
public bool CanExecute(object? parameter)
{
if (reference.Target is { } target)
if (reference.Target is InputElement target)
{
var current = target as Visual;
while (current != null && current is not TopLevel)
{
if (!current.IsVisible)
{
return false;
}
current = current.VisualParent;
}
if (target is ICommandSource commandSource && commandSource.Command is { } command)
{
return commandSource.IsEffectivelyEnabled

31
tests/Avalonia.Controls.UnitTests/HotKeyedControlsTests.cs

@ -119,5 +119,36 @@ namespace Avalonia.Controls.UnitTests
Assert.True(hotKeyedTextBox.IsFocused);
}
[Fact]
public void Hidden_Button_HotKey_Should_Not_Swallow_Input()
{
using var _ = CreateServicesWithFocus();
var keyboardDevice = new KeyboardDevice();
var root = PreparedWindow();
var panel = new StackPanel { IsVisible = false };
var button = new Button { HotKey = KeyGesture.Parse("Escape") };
bool buttonClicked = false;
button.Click += (s, e) => buttonClicked = true;
panel.Children.Add(button);
root.Content = panel;
root.Show();
keyboardDevice.ProcessRawEvent(
new RawKeyEventArgs(
keyboardDevice,
0,
root.InputRoot,
RawKeyEventType.KeyDown,
Key.Escape,
RawInputModifiers.None,
PhysicalKey.Escape,
""));
Assert.False(buttonClicked);
}
}
}

Loading…
Cancel
Save