diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index 50662f364..d594eea8c 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -370,12 +370,14 @@ namespace Terminal.Gui { return keyMod != Key.Null ? keyMod | key : key; } + Action keyDownHandler; Action keyHandler; Action keyUpHandler; private CursorVisibility savedCursorVisibility; public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { + this.keyDownHandler = keyDownHandler; this.keyHandler = keyHandler; this.keyUpHandler = keyUpHandler; @@ -400,6 +402,7 @@ namespace Terminal.Gui { keyModifiers.Ctrl = true; } + keyDownHandler (new KeyEvent (map, keyModifiers)); keyHandler (new KeyEvent (map, keyModifiers)); keyUpHandler (new KeyEvent (map, keyModifiers)); } diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 67dfdf755..ea9d80885 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -1932,8 +1932,14 @@ namespace Terminal.Gui { if (args.Handled) { return true; } - if (Focused?.Enabled == true && Focused?.OnKeyDown (keyEvent) == true) { - return true; + if (Focused?.Enabled == true) { + Focused.KeyDown?.Invoke (args); + if (args.Handled) { + return true; + } + if (Focused?.OnKeyDown (keyEvent) == true) { + return true; + } } return false; @@ -1956,8 +1962,14 @@ namespace Terminal.Gui { if (args.Handled) { return true; } - if (Focused?.Enabled == true && Focused?.OnKeyUp (keyEvent) == true) { - return true; + if (Focused?.Enabled == true) { + Focused.KeyUp?.Invoke (args); + if (args.Handled) { + return true; + } + if (Focused?.OnKeyUp (keyEvent) == true) { + return true; + } } return false; diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 3c03abe3f..baf66c497 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -3910,5 +3910,73 @@ This is a tes Assert.True (viewCalled); Assert.True (tvCalled); } + + [Fact, AutoInitShutdown] + public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () + { + var view = new DerivedView (); + view.KeyDown += (e) => { + Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.False (view.IsKeyDown); + e.Handled = true; + }; + view.KeyPress += (e) => { + Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.False (view.IsKeyPress); + e.Handled = true; + }; + view.KeyUp += (e) => { + Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.False (view.IsKeyUp); + e.Handled = true; + }; + + var iterations = -1; + + Application.Iteration += () => { + iterations++; + if (iterations == 0) { + Console.MockKeyPresses.Push (new ConsoleKeyInfo ('a', ConsoleKey.A, false, false, false)); + } else if (iterations == 1) { + Application.RequestStop (); + } + }; + + Application.Top.Add (view); + + Assert.True (view.CanFocus); + + Application.Run (); + Application.Shutdown (); + } + + public class DerivedView : View { + public DerivedView () + { + CanFocus = true; + } + + public bool IsKeyDown { get; set; } + public bool IsKeyPress { get; set; } + public bool IsKeyUp { get; set; } + + public override bool OnKeyDown (KeyEvent keyEvent) + { + IsKeyDown = true; + return base.OnKeyDown (keyEvent); + } + + public override bool ProcessKey (KeyEvent keyEvent) + { + IsKeyPress = true; + return base.ProcessKey (keyEvent); + } + + public override bool OnKeyUp (KeyEvent keyEvent) + { + IsKeyUp = true; + return base.OnKeyUp (keyEvent); + } + } } }