diff --git a/Terminal.Gui/Input/KeyBindings.cs b/Terminal.Gui/Input/KeyBindings.cs index 8ec38329e..cb0b079c2 100644 --- a/Terminal.Gui/Input/KeyBindings.cs +++ b/Terminal.Gui/Input/KeyBindings.cs @@ -38,7 +38,7 @@ public class KeyBindings else { Bindings.Add (key, binding); - if (binding.Scope.FastHasFlags (KeyBindingScope.Application)) + if (binding.Scope.HasFlag (KeyBindingScope.Application)) { Application.AddKeyBinding (key, BoundView); } diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 673c9103e..0448d5ef4 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -392,7 +392,7 @@ public class ScrollView : View return true; } - bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey); + bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey | KeyBindingScope.Focused); if (result is { }) { diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index d9bd4d1be..44d90ed3c 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -106,7 +106,7 @@ public partial class Toplevel : View ); // Default keybindings for this view - KeyBindings.Add (Application.QuitKey, KeyBindingScope.Application, Command.QuitToplevel); + KeyBindings.Add (Application.QuitKey, Command.QuitToplevel); KeyBindings.Add (Key.CursorRight, Command.NextView); KeyBindings.Add (Key.CursorDown, Command.NextView); @@ -119,7 +119,7 @@ public partial class Toplevel : View KeyBindings.Add (Key.Tab.WithShift.WithCtrl, Command.PreviousViewOrTop); // TODO: Refresh Key should be configurable - KeyBindings.Add (Key.F5, KeyBindingScope.Application, Command.Refresh); + KeyBindings.Add (Key.F5, Command.Refresh); KeyBindings.Add (Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix KeyBindings.Add (Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 2f0aa9b44..964fada3b 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using Microsoft.VisualBasic; +using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console @@ -147,8 +148,12 @@ public class ApplicationTests Shutdown (); } - [Fact] - public void Init_ResetState_Resets_Properties () + [Theory] + [InlineData (typeof (FakeDriver))] + [InlineData (typeof (NetDriver))] + [InlineData (typeof (WindowsDriver))] + [InlineData (typeof (CursesDriver))] + public void Init_ResetState_Resets_Properties (Type driverType) { ConfigurationManager.ThrowOnJsonErrors = true; @@ -156,7 +161,7 @@ public class ApplicationTests // Set some values - Application.Init (); + Application.Init (driverName: driverType.Name); Application._initialized = true; // Reset @@ -228,7 +233,7 @@ public class ApplicationTests Application.AlternateBackwardKey = Key.A; Application.AlternateForwardKey = Key.B; Application.QuitKey = Key.C; - Application.AddKeyBinding(Key.A, new View ()); + Application.AddKeyBinding (Key.A, new View ()); //Application.OverlappedChildren = new List (); //Application.OverlappedTop = @@ -266,6 +271,71 @@ public class ApplicationTests #endif } + [Theory] + [InlineData (typeof (FakeDriver))] + [InlineData (typeof (NetDriver))] + [InlineData (typeof (WindowsDriver))] + [InlineData (typeof (CursesDriver))] + public void Init_Shutdown_Fire_InitializedChanged (Type driverType) + { + bool initialized = false; + bool shutdown = false; + + Application.InitializedChanged += OnApplicationOnInitializedChanged; + + Application.Init (driverName: driverType.Name); + Assert.True (initialized); + Assert.False (shutdown); + + Application.Shutdown (); + Assert.True (initialized); + Assert.True (shutdown); + + Application.InitializedChanged -= OnApplicationOnInitializedChanged; + + return; + + void OnApplicationOnInitializedChanged (object s, StateEventArgs a) + { + if (a.NewValue) + { + initialized = true; + } + else + { + shutdown = true; + } + } + } + + + [Fact] + public void Run_Iteration_Fires () + { + int iteration = 0; + + Application.Init (new FakeDriver ()); + + Application.Iteration += Application_Iteration; + Application.Run ().Dispose (); + + Assert.Equal (1, iteration); + Application.Shutdown (); + + return; + + void Application_Iteration (object sender, IterationEventArgs e) + { + if (iteration > 0) + { + Assert.Fail (); + } + iteration++; + Application.RequestStop (); + } + } + + [Fact] public void Init_Unbalanced_Throws () { @@ -826,10 +896,10 @@ public class ApplicationTests Application.OnMouseEvent (new () { Flags = MouseFlags.Button1Pressed }); Assert.Equal (w.Border, Application.MouseGrabView); - Assert.Equal (new Point (0,0), w.Frame.Location); + Assert.Equal (new Point (0, 0), w.Frame.Location); // Move down and to the right. - Application.OnMouseEvent (new () { Position = new (1,1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.OnMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (new Point (1, 1), w.Frame.Location); Application.End (rs); @@ -1024,4 +1094,123 @@ public class ApplicationTests } #endregion + + + private object _timeoutLock; + + [Fact] + public void AddTimeout_Fires () + { + Assert.Null (_timeoutLock); + _timeoutLock = new object (); + + uint timeoutTime = 250; + bool initialized = false; + int iteration = 0; + bool shutdown = false; + object timeout = null; + int timeoutCount = 0; + + Application.InitializedChanged += OnApplicationOnInitializedChanged; + + Application.Init (new FakeDriver ()); + Assert.True (initialized); + Assert.False (shutdown); + + _output.WriteLine ("Application.Run ().Dispose ().."); + Application.Run ().Dispose (); + _output.WriteLine ("Back from Application.Run ().Dispose ()"); + + Assert.True (initialized); + Assert.False (shutdown); + + Assert.Equal (1, timeoutCount); + Application.Shutdown (); + + Application.InitializedChanged -= OnApplicationOnInitializedChanged; + + lock (_timeoutLock) + { + if (timeout is { }) + { + Application.RemoveTimeout (timeout); + timeout = null; + } + } + + Assert.True (initialized); + Assert.True (shutdown); + +#if DEBUG_IDISPOSABLE + Assert.Empty (Responder.Instances); +#endif + lock (_timeoutLock) + { + _timeoutLock = null; + } + + return; + + void OnApplicationOnInitializedChanged (object s, StateEventArgs a) + { + if (a.NewValue) + { + Application.Iteration += OnApplicationOnIteration; + initialized = true; + + lock (_timeoutLock) + { + _output.WriteLine ($"Setting timeout for {timeoutTime}ms"); + timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (timeoutTime), TimeoutCallback); + } + + } + else + { + Application.Iteration -= OnApplicationOnIteration; + shutdown = true; + } + } + + bool TimeoutCallback () + { + lock (_timeoutLock) + { + _output.WriteLine ($"TimeoutCallback. Count: {++timeoutCount}. Application Iteration: {iteration}"); + if (timeout is { }) + { + _output.WriteLine ($" Nulling timeout."); + timeout = null; + } + } + + // False means "don't re-do timer and remove it" + return false; + } + + void OnApplicationOnIteration (object s, IterationEventArgs a) + { + lock (_timeoutLock) + { + if (timeoutCount > 0) + { + _output.WriteLine ($"Iteration #{iteration} - Timeout fired. Calling Application.RequestStop."); + Application.RequestStop (); + + return; + } + } + iteration++; + + // Simulate a delay + Thread.Sleep ((int)timeoutTime / 10); + + // Worst case scenario - something went wrong + if (Application._initialized && iteration > 25) + { + _output.WriteLine ($"Too many iterations ({iteration}): Calling Application.RequestStop."); + Application.RequestStop (); + } + } + } } diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs index a293de45a..558619c3b 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/UnitTests/Application/KeyboardTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UICatalog; +using Xunit.Abstractions; namespace Terminal.Gui.ApplicationTests; @@ -58,6 +59,123 @@ public class KeyboardTests top.Dispose (); } + [Fact] + public void QuitKey_Default_Is_CtrlQ () + { + Application.ResetState (true); + // Before Init + Assert.Equal (Key.Empty, Application.QuitKey); + + Application.Init (new FakeDriver ()); + // After Init + Assert.Equal (Key.Q.WithCtrl, Application.QuitKey); + + Application.Shutdown(); + } + + private object _timeoutLock; + + [Fact] + public void QuitKey_Quits () + { + Assert.Null (_timeoutLock); + _timeoutLock = new object (); + + uint abortTime = 500; + bool initialized = false; + int iteration = 0; + bool shutdown = false; + object timeout = null; + + Application.InitializedChanged += OnApplicationOnInitializedChanged; + + Application.Init (new FakeDriver ()); + Assert.True (initialized); + Assert.False (shutdown); + + _output.WriteLine ("Application.Run ().Dispose ().."); + Application.Run ().Dispose (); + _output.WriteLine ("Back from Application.Run ().Dispose ()"); + + Assert.True (initialized); + Assert.False (shutdown); + + Assert.Equal (1, iteration); + + Application.Shutdown (); + + Application.InitializedChanged -= OnApplicationOnInitializedChanged; + + lock (_timeoutLock) + { + if (timeout is { }) + { + Application.RemoveTimeout (timeout); + timeout = null; + } + } + + Assert.True (initialized); + Assert.True (shutdown); + +#if DEBUG_IDISPOSABLE + Assert.Empty (Responder.Instances); +#endif + lock (_timeoutLock) + { + _timeoutLock = null; + } + + return; + + void OnApplicationOnInitializedChanged (object s, StateEventArgs a) + { + _output.WriteLine ("OnApplicationOnInitializedChanged: {0}", a.NewValue); + if (a.NewValue) + { + Application.Iteration += OnApplicationOnIteration; + initialized = true; + lock (_timeoutLock) + { + timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback); + } + } + else + { + Application.Iteration -= OnApplicationOnIteration; + shutdown = true; + } + } + + bool ForceCloseCallback () + { + lock (_timeoutLock) + { + _output.WriteLine ($"ForceCloseCallback. iteration: {iteration}"); + if (timeout is { }) + { + timeout = null; + } + } + Application.ResetState (true); + Assert.Fail ($"Failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit."); + + return false; + } + + void OnApplicationOnIteration (object s, IterationEventArgs a) + { + _output.WriteLine ("Iteration: {0}", iteration); + iteration++; + Assert.True (iteration < 2, "Too many iterations, something is wrong."); + if (Application._initialized) + { + _output.WriteLine (" Pressing QuitKey"); + Application.OnKeyDown (Application.QuitKey); + } + } + } + [Fact] public void AlternateForwardKey_AlternateBackwardKey_Tests () { diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index 5fdc874b5..71e8517a0 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.IO; // Alias Console to MockConsole so we don't accidentally use Console @@ -619,16 +620,22 @@ public class MainLoopTests ); } - [Fact] - public async Task InvokeLeakTest () + [Theory] + [InlineData (typeof (FakeDriver))] + //[InlineData (typeof (NetDriver))] // BUGBUG: NetDriver never exits in this test + + //[InlineData (typeof (ANSIDriver))] + //[InlineData (typeof (WindowsDriver))] // BUGBUG: NetDriver never exits in this test + //[InlineData (typeof (CursesDriver))] // BUGBUG: CursesDriver never exits in this test + public async Task InvokeLeakTest (Type driverType) { - Application.Init (); + Application.Init (driverName: driverType.Name); Random r = new (); TextField tf = new (); var top = new Toplevel (); top.Add (tf); - const int numPasses = 5; + const int numPasses = 2; const int numIncrements = 500; const int pollMs = 2500; @@ -658,7 +665,8 @@ public class MainLoopTests int pfour ) { - Application.Init (); + // TODO: Expand this test to test all drivers + Application.Init (new FakeDriver()); total = 0; btn = null; diff --git a/UnitTests/Application/SynchronizatonContextTests.cs b/UnitTests/Application/SynchronizatonContextTests.cs index b5a34976f..f0dd036d3 100644 --- a/UnitTests/Application/SynchronizatonContextTests.cs +++ b/UnitTests/Application/SynchronizatonContextTests.cs @@ -18,10 +18,14 @@ public class SyncrhonizationContextTests Application.Shutdown (); } - [Fact] - public void SynchronizationContext_Post () + [Theory] + [InlineData (typeof (FakeDriver))] + //[InlineData (typeof (NetDriver))] + [InlineData (typeof (WindowsDriver))] + //[InlineData (typeof (CursesDriver))] + public void SynchronizationContext_Post (Type driverType) { - Application.Init (); + Application.Init (driverName: driverType.Name); SynchronizationContext context = SynchronizationContext.Current; var success = false; diff --git a/UnitTests/Configuration/ConfigurationMangerTests.cs b/UnitTests/Configuration/ConfigurationMangerTests.cs index 553df407d..b1b7f2150 100644 --- a/UnitTests/Configuration/ConfigurationMangerTests.cs +++ b/UnitTests/Configuration/ConfigurationMangerTests.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Text.Json; +using Xunit.Abstractions; using static Terminal.Gui.ConfigurationManager; #pragma warning disable IDE1006 @@ -7,6 +8,13 @@ namespace Terminal.Gui.ConfigurationTests; public class ConfigurationManagerTests { + private readonly ITestOutputHelper _output; + + public ConfigurationManagerTests (ITestOutputHelper output) + { + _output = output; + } + public static readonly JsonSerializerOptions _jsonOptions = new () { Converters = { new AttributeJsonConverter (), new ColorJsonConverter () } @@ -402,6 +410,7 @@ public class ConfigurationManagerTests // Application is a static class PropertyInfo pi = typeof (Application).GetProperty ("QuitKey"); Assert.Equal (pi, Settings ["Application.QuitKey"].PropertyInfo); + // FrameView is not a static class and DefaultBorderStyle is Scope.Scheme pi = typeof (FrameView).GetProperty ("DefaultBorderStyle"); diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 20c855315..af6560799 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -23,7 +23,7 @@ public class ScenarioTests : TestsAllViews .Where (type => type.IsClass && !type.IsAbstract && type.IsSubclassOf (typeof (Scenario))) .Select (type => new object [] { type }); - private readonly object _timeoutLock = new object (); + private object _timeoutLock; /// /// This runs through all Scenarios defined in UI Catalog, calling Init, Setup, and Run. @@ -33,41 +33,27 @@ public class ScenarioTests : TestsAllViews [MemberData (nameof (AllScenarioTypes))] public void All_Scenarios_Quit_And_Init_Shutdown_Properly (Type scenarioType) { + Assert.Null (_timeoutLock); + _timeoutLock = new object (); + // If a previous test failed, this will ensure that the Application is in a clean state Application.ResetState (true); _output.WriteLine ($"Running Scenario '{scenarioType}'"); Scenario scenario = (Scenario)Activator.CreateInstance (scenarioType); - uint abortTime = 500; + uint abortTime = 1500; bool initialized = false; bool shutdown = false; object timeout = null; - void OnApplicationOnInitializedChanged (object s, StateEventArgs a) - { - if (a.NewValue) - { - lock (_timeoutLock) - { - timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback); - } - - Application.Iteration += OnApplicationOnIteration; - initialized = true; - } - else - { - Application.Iteration -= OnApplicationOnIteration; - shutdown = true; - } - } - Application.InitializedChanged += OnApplicationOnInitializedChanged; + Application.ForceDriver = "FakeDriver"; scenario.Main (); scenario.Dispose (); scenario = null; + Application.ForceDriver = string.Empty; Application.InitializedChanged -= OnApplicationOnInitializedChanged; @@ -75,7 +61,6 @@ public class ScenarioTests : TestsAllViews { if (timeout is { }) { - Application.RemoveTimeout (timeout); timeout = null; } } @@ -87,8 +72,40 @@ public class ScenarioTests : TestsAllViews #if DEBUG_IDISPOSABLE Assert.Empty (Responder.Instances); #endif + + lock (_timeoutLock) + { + _timeoutLock = null; + } + return; + + void OnApplicationOnInitializedChanged (object s, StateEventArgs a) + { + if (a.NewValue) + { + Assert.Equal (Key.Q.WithCtrl, Application.QuitKey); + + Application.Iteration += OnApplicationOnIteration; + initialized = true; + lock (_timeoutLock) + { + timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback); + } + _output.WriteLine ($"Initialized '{Application.Driver}'"); + //Dictionary> bindings = Application.GetKeyBindings (); + //Assert.NotEmpty (bindings); + //_output.WriteLine ($"bindings: {string.Join (",", bindings.Keys)}"); + //Assert.True (bindings.ContainsKey (Application.QuitKey)); + } + else + { + Application.Iteration -= OnApplicationOnIteration; + shutdown = true; + } + } + // If the scenario doesn't close within 500ms, this will force it to quit bool ForceCloseCallback () { @@ -96,14 +113,13 @@ public class ScenarioTests : TestsAllViews { if (timeout is { }) { - Application.RemoveTimeout (timeout); timeout = null; } } - Application.ResetState (true); Assert.Fail ( $"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit."); + Application.ResetState (true); return false; } @@ -112,6 +128,7 @@ public class ScenarioTests : TestsAllViews if (Application._initialized) { // Press QuitKey + //_output.WriteLine ($"Forcing Quit with {Application.QuitKey}"); Application.OnKeyDown (Application.QuitKey); } } diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index d4d9c9cd0..03f0dcba0 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -258,6 +258,93 @@ public class ButtonTests (ITestOutputHelper output) Assert.True (clicked); } + [Theory] + [InlineData (false, 0)] + [InlineData (true, 1)] + public void Space_Fires_Accept (bool focused, int expected) + { + View superView = new View () + { + CanFocus = true, + }; + + Button button = new (); + + button.CanFocus = focused; + + int acceptInvoked = 0; + button.Accept += (s, e) => acceptInvoked++; + + superView.Add (button); + button.SetFocus (); + Assert.Equal (focused, button.HasFocus); + + superView.NewKeyDownEvent (Key.Space); + + Assert.Equal (expected, acceptInvoked); + + superView.Dispose (); + } + + [Theory] + [InlineData (false, 0)] + [InlineData (true, 1)] + public void Enter_Fires_Accept (bool focused, int expected) + { + View superView = new View () + { + CanFocus = true, + }; + + Button button = new (); + + button.CanFocus = focused; + + int acceptInvoked = 0; + button.Accept += (s, e) => acceptInvoked++; + + superView.Add (button); + button.SetFocus (); + Assert.Equal (focused, button.HasFocus); + + superView.NewKeyDownEvent (Key.Enter); + + Assert.Equal (expected, acceptInvoked); + + superView.Dispose (); + } + + [Theory] + [InlineData (false, 1)] + [InlineData (true, 1)] + public void HotKey_Fires_Accept (bool focused, int expected) + { + View superView = new View () + { + CanFocus = true, + }; + + Button button = new () + { + HotKey = Key.A + }; + + button.CanFocus = focused; + + int acceptInvoked = 0; + button.Accept += (s, e) => acceptInvoked++; + + superView.Add (button); + button.SetFocus (); + Assert.Equal (focused, button.HasFocus); + + superView.NewKeyDownEvent (Key.A); + + Assert.Equal (expected, acceptInvoked); + + superView.Dispose (); + } + /// /// This test demonstrates how to change the activation key for Button as described in the README.md keyboard /// handling section @@ -279,7 +366,9 @@ public class ButtonTests (ITestOutputHelper output) top.Add (btn); Application.Begin (top); - // default keybinding is Space which results in keypress + Assert.True (btn.HasFocus); + + // default keybinding is Space which results in Command.Accept (when focused) Application.OnKeyDown (new ((KeyCode)' ')); Assert.Equal (1, pressed); @@ -292,8 +381,7 @@ public class ButtonTests (ITestOutputHelper output) Assert.Equal (1, pressed); // Set a new binding of b for the click (Accept) event - btn.KeyBindings.Add (Key.B, Command.HotKey); - btn.KeyBindings.Add (Key.B, Command.Accept); + btn.KeyBindings.Add (Key.B, Command.HotKey); // b will now trigger the Accept command (when focused or not) // now pressing B should call the button click event Application.OnKeyDown (Key.B); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index cce1f781f..f1a378cbf 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -627,42 +627,40 @@ public class ToplevelTests (ITestOutputHelper output) Assert.Equal (win1, Application.Current); Assert.Equal (win1, Application.OverlappedChildren [0]); win1.Running = true; - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.QuitKey)); + Assert.True (Application.OnKeyDown (Application.QuitKey)); Assert.False (isRunning); Assert.False (win1.Running); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.True ( - Application.OverlappedChildren [0].NewKeyDownEvent (Key.Z.WithCtrl) + Application.OnKeyDown (Key.Z.WithCtrl) ); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.F5)); // refresh + Assert.True (Application.OnKeyDown (Key.F5)); // refresh - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab)); + Assert.True (Application.OnKeyDown (Key.Tab)); Assert.True (win1.IsCurrentTop); Assert.Equal (tvW1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab)); + Assert.True (Application.OnKeyDown (Key.Tab)); Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text); Assert.True ( - Application.OverlappedChildren [0] - .NewKeyDownEvent (Key.Tab.WithShift) + Application.OnKeyDown (Key.Tab.WithShift) ); Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text); Assert.True ( - Application.OverlappedChildren [0] - .NewKeyDownEvent (Key.Tab.WithCtrl) + Application.OnKeyDown (Key.Tab.WithCtrl) ); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf2W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab)); + Assert.True (Application.OnKeyDown (Key.Tab)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight)); + Assert.True (Application.OnKeyDown (Key.CursorRight)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown)); + Assert.True (Application.OnKeyDown (Key.CursorDown)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tvW1, win1.MostFocused); #if UNIX_KEY_BINDINGS @@ -676,13 +674,13 @@ public class ToplevelTests (ITestOutputHelper output) ); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tvW1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft)); + Assert.True (Application.OnKeyDown (Key.CursorLeft)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorUp)); + Assert.True (Application.OnKeyDown (Key.CursorUp)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf2W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab)); + Assert.True (Application.OnKeyDown (Key.Tab)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); @@ -701,23 +699,23 @@ public class ToplevelTests (ITestOutputHelper output) ); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateForwardKey)); + Assert.True (Application.OnKeyDown (Application.AlternateForwardKey)); Assert.Equal (win2, Application.OverlappedChildren [0]); Assert.Equal (tf2W2, win2.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateBackwardKey)); + Assert.True (Application.OnKeyDown (Application.AlternateBackwardKey)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown)); + Assert.True (Application.OnKeyDown (Key.CursorDown)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tvW1, win1.MostFocused); #if UNIX_KEY_BINDINGS Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.B.WithCtrl))); #else - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft)); + Assert.True (Application.OnKeyDown (Key.CursorLeft)); #endif Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf1W1, win1.MostFocused); - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown)); + Assert.True (Application.OnKeyDown (Key.CursorDown)); Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tvW1, win1.MostFocused); Assert.Equal (Point.Empty, tvW1.CursorPosition); @@ -732,7 +730,7 @@ public class ToplevelTests (ITestOutputHelper output) #if UNIX_KEY_BINDINGS Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.F.WithCtrl))); #else - Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight)); + Assert.True (Application.OnKeyDown (Key.CursorRight)); #endif Assert.Equal (win1, Application.OverlappedChildren [0]); Assert.Equal (tf2W1, win1.MostFocused);