diff --git a/Terminal.Gui/Application/ApplicationKeyboard.cs b/Terminal.Gui/Application/ApplicationKeyboard.cs index 8447f76d0..be737968f 100644 --- a/Terminal.Gui/Application/ApplicationKeyboard.cs +++ b/Terminal.Gui/Application/ApplicationKeyboard.cs @@ -143,18 +143,15 @@ partial class Application { if (view is {} && view.KeyBindings.TryGet (binding.Key, (KeyBindingScope)0xFFFF, out KeyBinding kb)) { - bool? handled = view.InvokeCommands (kb.Commands, binding.Key, kb); + //bool? handled = view.InvokeCommands (kb.Commands, binding.Key, kb); + bool? handled = view?.OnInvokingKeyBindings (keyEvent, kb.Scope); + if (handled != null && (bool)handled) { return true; } - } - //bool? handled = view?.OnInvokingKeyBindings (keyEvent, KeyBindingScope.Application); - //if (handled != null && (bool)handled) - //{ - // return true; - //} + } } } diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index 60cae2f5e..84ca4841c 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -639,7 +639,7 @@ public partial class View public virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) { // fire event only if there's an hotkey binding for the key - if (KeyBindings.TryGet (keyEvent, scope, out KeyBinding _)) + if (KeyBindings.TryGet (keyEvent, scope, out KeyBinding kb)) { InvokingKeyBindings?.Invoke (this, keyEvent); if (keyEvent.Handled) @@ -709,7 +709,10 @@ public partial class View { if (subview.KeyBindings.TryGet (keyEvent, scope, out KeyBinding binding)) { - //keyEvent.Scope = KeyBindingScope.HotKey; + if (binding.Scope == KeyBindingScope.Focused && !subview.HasFocus) + { + continue; + } handled = subview.OnInvokingKeyBindings (keyEvent, scope); if (handled is { } && (bool)handled) diff --git a/UnitTests/View/HotKeyTests.cs b/UnitTests/View/HotKeyTests.cs index f1b3109f9..d284e9b01 100644 --- a/UnitTests/View/HotKeyTests.cs +++ b/UnitTests/View/HotKeyTests.cs @@ -81,7 +81,7 @@ public class HotKeyTests [InlineData (KeyCode.ShiftMask | KeyCode.AltMask, true)] [InlineData (KeyCode.CtrlMask, false)] [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask, false)] - public void KeyPress_Runs_Default_HotKey_Command (KeyCode mask, bool expected) + public void NewKeyDownEvent_Runs_Default_HotKey_Command (KeyCode mask, bool expected) { var view = new View { HotKeySpecifier = (Rune)'^', Title = "^Test" }; view.CanFocus = true; @@ -91,10 +91,10 @@ public class HotKeyTests } [Fact] - public void ProcessKeyDown_Ignores_KeyBindings_Out_Of_Scope_SuperView () + public void NewKeyDownEvent_Ignores_Focus_KeyBindings_SuperView () { var view = new View (); - view.KeyBindings.Add (Key.A, Command.HotKey); + view.KeyBindings.Add (Key.A, Command.HotKey); // implies KeyBindingScope.Focused - so this should not be invoked view.InvokingKeyBindings += (s, e) => { Assert.Fail (); }; var superView = new View (); @@ -105,7 +105,25 @@ public class HotKeyTests } [Fact] - public void ProcessKeyDown_Invokes_HotKey_Command_With_SuperView () + public void NewKeyDownEvent_Honors_HotKey_KeyBindings_SuperView () + { + var view = new View (); + view.KeyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.HotKey); + bool invoked = false; + view.InvokingKeyBindings += (s, e) => { invoked = true; }; + + var superView = new View (); + superView.Add (view); + + var ke = Key.A; + superView.NewKeyDownEvent (ke); + + Assert.True (invoked); + } + + + [Fact] + public void NewKeyDownEvent_InNewKeyDownEventvokes_HotKey_Command_With_SuperView () { var view = new View { HotKeySpecifier = (Rune)'^', Title = "^Test" }; diff --git a/UnitTests/Views/RadioGroupTests.cs b/UnitTests/Views/RadioGroupTests.cs index faf0275f2..4ddf68321 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/UnitTests/Views/RadioGroupTests.cs @@ -73,6 +73,7 @@ public class RadioGroupTests (ITestOutputHelper output) public void KeyBindings_Command () { var rg = new RadioGroup { RadioLabels = new [] { "Test", "New Test" } }; + rg.SetFocus(); Assert.True (rg.NewKeyDownEvent (Key.CursorUp)); Assert.True (rg.NewKeyDownEvent (Key.CursorDown));