diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index a7618e369..d220bd6a3 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -403,6 +403,9 @@ namespace Terminal.Gui { static void ProcessKeyEvent (KeyEvent ke) { + if(RootKeyEvent?.Invoke(ke) ?? false) { + return; + } var chain = toplevels.ToList (); foreach (var topLevel in chain) { @@ -588,6 +591,15 @@ namespace Terminal.Gui { /// public static Action RootMouseEvent; + /// + /// + /// Called for new KeyPress events before any processing is performed or + /// views evaluate. Use for global key handling and/or debugging. + /// + /// Return true to suppress the KeyPress event + /// + public static Func RootKeyEvent; + internal static View wantContinuousButtonPressedView; static View lastMouseOwnerView; @@ -872,6 +884,7 @@ namespace Terminal.Gui { Driver = null; Iteration = null; RootMouseEvent = null; + RootKeyEvent = null; Resized = null; _initialized = false; mouseGrabView = null; diff --git a/UnitTests/TextFieldTests.cs b/UnitTests/TextFieldTests.cs index 959ce2a43..41c7c0dfd 100644 --- a/UnitTests/TextFieldTests.cs +++ b/UnitTests/TextFieldTests.cs @@ -1178,5 +1178,38 @@ namespace Terminal.Gui.Views { Assert.Equal ("-1", oldText); Assert.Equal ("-", tf.Text); } + + [Fact] + [AutoInitShutdown] + public void Test_RootKeyEvent_Cancel() + { + Application.RootKeyEvent += SuppressKey; + + var tf = new TextField(); + + Application.Top.Add (tf); + Application.Begin (Application.Top); + + Application.Driver.SendKeys('a',ConsoleKey.A,false,false,false); + Assert.Equal("a", tf.Text.ToString ()); + + // SuppressKey suppresses the 'j' key + Application.Driver.SendKeys('j',ConsoleKey.A,false,false,false); + Assert.Equal("a", tf.Text.ToString ()); + + Application.RootKeyEvent -= SuppressKey; + + // Now that the delegate has been removed we can type j again + Application.Driver.SendKeys('j',ConsoleKey.A,false,false,false); + Assert.Equal("aj", tf.Text.ToString ()); + } + + private bool SuppressKey (KeyEvent arg) + { + if(arg.KeyValue == 'j') + return true; + + return false; + } } } \ No newline at end of file