Browse Source

MASSIVE - Almost completely decoupled Application from View etc...

Tig 3 weeks ago
parent
commit
899fd76
90 changed files with 987 additions and 728 deletions
  1. 1 1
      Examples/ReactiveExample/TerminalScheduler.cs
  2. 1 1
      Examples/UICatalog/Scenarios/AnimationScenario/AnimationScenario.cs
  3. 56 52
      Examples/UICatalog/Scenarios/ContextMenus.cs
  4. 1 1
      Examples/UICatalog/Scenarios/Menus.cs
  5. 1 1
      Examples/UICatalog/Scenarios/Navigation.cs
  6. 1 1
      Examples/UICatalog/Scenarios/Notepad.cs
  7. 1 1
      Examples/UICatalog/Scenarios/Progress.cs
  8. 1 1
      Examples/UICatalog/Scenarios/TableEditor.cs
  9. 1 1
      Examples/UICatalog/Scenarios/TreeViewFileSystem.cs
  10. 5 5
      Examples/UICatalog/Scenarios/ViewExperiments.cs
  11. 5 1
      Terminal.Gui/App/Application.Run.cs
  12. 2 53
      Terminal.Gui/App/Application.cs
  13. 1 1
      Terminal.Gui/App/ApplicationImpl.Driver.cs
  14. 3 2
      Terminal.Gui/App/ApplicationImpl.Lifecycle.cs
  15. 25 2
      Terminal.Gui/App/ApplicationImpl.Run.cs
  16. 89 3
      Terminal.Gui/App/ApplicationImpl.cs
  17. 31 11
      Terminal.Gui/App/ApplicationPopover.cs
  18. 24 0
      Terminal.Gui/App/IApplication.cs
  19. 17 11
      Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs
  20. 8 1
      Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs
  21. 2 1
      Terminal.Gui/App/MainLoop/IMainLoopCoordinator.cs
  22. 19 18
      Terminal.Gui/App/MainLoop/MainLoopCoordinator.cs
  23. 7 7
      Terminal.Gui/App/MainLoop/MainLoopSyncContext.cs
  24. 2 2
      Terminal.Gui/App/Mouse/IMouse.cs
  25. 12 9
      Terminal.Gui/App/Mouse/MouseImpl.cs
  26. 11 1
      Terminal.Gui/App/PopoverBaseImpl.cs
  27. 3 3
      Terminal.Gui/App/Toplevel/ToplevelTransitionManager.cs
  28. 1 1
      Terminal.Gui/Drivers/FakeDriver/FakeInputProcessor.cs
  29. 3 3
      Terminal.Gui/Drivers/WindowsDriver/WindowsOutput.cs
  30. 11 16
      Terminal.Gui/Text/TextFormatter.cs
  31. 1 1
      Terminal.Gui/ViewBase/Adornment/ShadowView.cs
  32. 3 3
      Terminal.Gui/ViewBase/IDesignable.cs
  33. 1 1
      Terminal.Gui/ViewBase/View.Hierarchy.cs
  34. 33 23
      Terminal.Gui/ViewBase/View.Layout.cs
  35. 9 9
      Terminal.Gui/ViewBase/View.Mouse.cs
  36. 13 4
      Terminal.Gui/ViewBase/View.cs
  37. 17 17
      Terminal.Gui/Views/Autocomplete/AppendAutocomplete.cs
  38. 3 3
      Terminal.Gui/Views/Autocomplete/PopupAutocomplete.cs
  39. 8 7
      Terminal.Gui/Views/Bar.cs
  40. 3 3
      Terminal.Gui/Views/CharMap/CharMap.cs
  41. 4 4
      Terminal.Gui/Views/FileDialogs/FileDialog.cs
  42. 4 0
      Terminal.Gui/Views/Menu/MenuBarItemv2.cs
  43. 25 16
      Terminal.Gui/Views/Menu/MenuBarv2.cs
  44. 2 1
      Terminal.Gui/Views/Menu/MenuItemv2.cs
  45. 20 12
      Terminal.Gui/Views/Menu/PopoverMenu.cs
  46. 2 2
      Terminal.Gui/Views/Menuv1/MenuBar.cs
  47. 21 8
      Terminal.Gui/Views/Shortcut.cs
  48. 2 2
      Terminal.Gui/Views/Slider/Slider.cs
  49. 5 5
      Terminal.Gui/Views/SpinnerView/SpinnerView.cs
  50. 9 7
      Terminal.Gui/Views/StatusBar.cs
  51. 10 16
      Terminal.Gui/Views/TextInput/TextField.cs
  52. 14 11
      Terminal.Gui/Views/TextInput/TextView.cs
  53. 2 2
      Terminal.Gui/Views/Toplevel.cs
  54. 3 3
      Tests/IntegrationTests/FluentTests/FileDialogFluentTests.cs
  55. 14 14
      Tests/IntegrationTests/FluentTests/GuiTestContextKeyEventTests.cs
  56. 1 1
      Tests/IntegrationTests/FluentTests/GuiTestContextMouseEventTests.cs
  57. 67 54
      Tests/IntegrationTests/FluentTests/MenuBarv2Tests.cs
  58. 1 1
      Tests/IntegrationTests/FluentTests/NavigationTests.cs
  59. 102 61
      Tests/IntegrationTests/FluentTests/PopverMenuTests.cs
  60. 2 2
      Tests/IntegrationTests/FluentTests/TreeViewFluentTests.cs
  61. 8 2
      Tests/TerminalGuiFluentTesting/GuiTestContext.ContextMenu.cs
  62. 4 4
      Tests/TerminalGuiFluentTesting/GuiTestContext.Input.cs
  63. 5 5
      Tests/TerminalGuiFluentTesting/GuiTestContext.ViewBase.cs
  64. 32 23
      Tests/TerminalGuiFluentTesting/GuiTestContext.cs
  65. 1 3
      Tests/UnitTests/Application/Application.NavigationTests.cs
  66. 2 2
      Tests/UnitTests/Application/ApplicationImplTests.cs
  67. 26 28
      Tests/UnitTests/Application/ApplicationPopoverTests.cs
  68. 3 5
      Tests/UnitTests/Application/ApplicationTests.cs
  69. 11 19
      Tests/UnitTests/Application/CursorTests.cs
  70. 1 1
      Tests/UnitTests/Application/MainLoopCoordinatorTests.cs
  71. 19 19
      Tests/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs
  72. 2 2
      Tests/UnitTests/View/Adornment/AdornmentSubViewTests.cs
  73. 2 1
      Tests/UnitTests/View/Adornment/ShadowStyleTests.cs
  74. 4 2
      Tests/UnitTests/View/Draw/ClipTests.cs
  75. 22 22
      Tests/UnitTests/View/Layout/GetViewsUnderLocationTests.cs
  76. 1 1
      Tests/UnitTests/View/Layout/Pos.CombineTests.cs
  77. 0 3
      Tests/UnitTests/View/Navigation/NavigationTests.cs
  78. 0 1
      Tests/UnitTests/Views/CheckBoxTests.cs
  79. 0 2
      Tests/UnitTests/Views/ColorPickerTests.cs
  80. 0 1
      Tests/UnitTests/Views/ComboBoxTests.cs
  81. 13 21
      Tests/UnitTests/Views/HexViewTests.cs
  82. 24 10
      Tests/UnitTests/Views/LabelTests.cs
  83. 28 32
      Tests/UnitTests/Views/MenuBarTests.cs
  84. 9 4
      Tests/UnitTests/Views/ShortcutTests.cs
  85. 1 1
      Tests/UnitTests/Views/TableViewTests.cs
  86. 10 0
      Tests/UnitTestsParallelizable/Application/ApplicationPopoverTests.cs
  87. 2 2
      Tests/UnitTestsParallelizable/Application/PopoverBaseImplTests.cs
  88. 1 1
      Tests/UnitTestsParallelizable/TestSetup.cs
  89. 2 2
      Tests/UnitTestsParallelizable/View/Layout/GetViewsUnderLocationTests.cs
  90. 8 5
      Tests/UnitTestsParallelizable/Views/ShortcutTests.cs

+ 1 - 1
Examples/ReactiveExample/TerminalScheduler.cs

@@ -22,7 +22,7 @@ public class TerminalScheduler : LocalScheduler
             var cancellation = new CancellationDisposable ();
 
             Application.Invoke (
-                                () =>
+                                (_) =>
                                 {
                                     if (!cancellation.Token.IsCancellationRequested)
                                     {

+ 1 - 1
Examples/UICatalog/Scenarios/AnimationScenario/AnimationScenario.cs

@@ -92,7 +92,7 @@ public class AnimationScenario : Scenario
                       {
                           // When updating from a Thread/Task always use Invoke
                           Application.Invoke (
-                                              () =>
+                                              (_) =>
                                               {
                                                   _imageView.NextFrame ();
                                                   _imageView.SetNeedsDraw ();

+ 56 - 52
Examples/UICatalog/Scenarios/ContextMenus.cs

@@ -1,5 +1,7 @@
-using System.Globalization;
+#nullable enable
+using System.Globalization;
 using JetBrains.Annotations;
+// ReSharper disable AccessToDisposedClosure
 
 namespace UICatalog.Scenarios;
 
@@ -7,78 +9,85 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Menus")]
 public class ContextMenus : Scenario
 {
-    [CanBeNull]
-    private PopoverMenu _winContextMenu;
-    private TextField _tfTopLeft, _tfTopRight, _tfMiddle, _tfBottomLeft, _tfBottomRight;
-    private readonly List<CultureInfo> _cultureInfos = Application.SupportedCultures;
+    private PopoverMenu? _winContextMenu;
+    private TextField? _tfTopLeft, _tfTopRight, _tfMiddle, _tfBottomLeft, _tfBottomRight;
+    private readonly List<CultureInfo>? _cultureInfos = Application.SupportedCultures;
     private readonly Key _winContextMenuKey = Key.Space.WithCtrl;
 
+    private Window? _appWindow;
+
     public override void Main ()
     {
         // Init
         Application.Init ();
 
         // Setup - Create a top-level application window and configure it.
-        Window appWindow = new ()
+        _appWindow = new ()
         {
             Title = GetQuitKeyAndName (),
             Arrangement = ViewArrangement.Fixed,
             SchemeName = "Toplevel"
         };
 
-        var text = "Context Menu";
-        var width = 20;
+        _appWindow.Initialized += AppWindowOnInitialized;
 
-        CreateWinContextMenu ();
+        // Run - Start the application.
+        Application.Run (_appWindow);
+        _appWindow.Dispose ();
+        _appWindow.KeyDown -= OnAppWindowOnKeyDown;
+        _appWindow.MouseClick -= OnAppWindowOnMouseClick;
+        _winContextMenu?.Dispose ();
 
-        var label = new Label
-        {
-            X = Pos.Center (), Y = 1, Text = $"Press '{_winContextMenuKey}' to open the Window context menu."
-        };
-        appWindow.Add (label);
+        // Shutdown - Calling Application.Shutdown is required.
+        Application.Shutdown ();
+
+        return;
 
-        label = new ()
+        void AppWindowOnInitialized (object? sender, EventArgs e)
         {
-            X = Pos.Center (),
-            Y = Pos.Bottom (label),
-            Text = $"Press '{PopoverMenu.DefaultKey}' to open the TextField context menu."
-        };
-        appWindow.Add (label);
 
-        _tfTopLeft = new () { Id = "_tfTopLeft", Width = width, Text = text };
-        appWindow.Add (_tfTopLeft);
+            var text = "Context Menu";
+            var width = 20;
+
+            CreateWinContextMenu ();
 
-        _tfTopRight = new () { Id = "_tfTopRight", X = Pos.AnchorEnd (width), Width = width, Text = text };
-        appWindow.Add (_tfTopRight);
+            var label = new Label
+            {
+                X = Pos.Center (), Y = 1, Text = $"Press '{_winContextMenuKey}' to open the Window context menu."
+            };
+            _appWindow.Add (label);
 
-        _tfMiddle = new () { Id = "_tfMiddle", X = Pos.Center (), Y = Pos.Center (), Width = width, Text = text };
-        appWindow.Add (_tfMiddle);
+            label = new ()
+            {
+                X = Pos.Center (),
+                Y = Pos.Bottom (label),
+                Text = $"Press '{PopoverMenu.DefaultKey}' to open the TextField context menu."
+            };
+            _appWindow.Add (label);
 
-        _tfBottomLeft = new () { Id = "_tfBottomLeft", Y = Pos.AnchorEnd (1), Width = width, Text = text };
-        appWindow.Add (_tfBottomLeft);
+            _tfTopLeft = new () { Id = "_tfTopLeft", Width = width, Text = text };
+            _appWindow.Add (_tfTopLeft);
 
-        _tfBottomRight = new () { Id = "_tfBottomRight", X = Pos.AnchorEnd (width), Y = Pos.AnchorEnd (1), Width = width, Text = text };
-        appWindow.Add (_tfBottomRight);
+            _tfTopRight = new () { Id = "_tfTopRight", X = Pos.AnchorEnd (width), Width = width, Text = text };
+            _appWindow.Add (_tfTopRight);
 
-        appWindow.KeyDown += OnAppWindowOnKeyDown;
-        appWindow.MouseClick += OnAppWindowOnMouseClick;
+            _tfMiddle = new () { Id = "_tfMiddle", X = Pos.Center (), Y = Pos.Center (), Width = width, Text = text };
+            _appWindow.Add (_tfMiddle);
 
-        CultureInfo originalCulture = Thread.CurrentThread.CurrentUICulture;
-        appWindow.Closed += (s, e) => { Thread.CurrentThread.CurrentUICulture = originalCulture; };
+            _tfBottomLeft = new () { Id = "_tfBottomLeft", Y = Pos.AnchorEnd (1), Width = width, Text = text };
+            _appWindow.Add (_tfBottomLeft);
 
-        // Run - Start the application.
-        Application.Run (appWindow);
-        appWindow.Dispose ();
-        appWindow.KeyDown -= OnAppWindowOnKeyDown;
-        appWindow.MouseClick -= OnAppWindowOnMouseClick;
-        _winContextMenu?.Dispose ();
+            _tfBottomRight = new () { Id = "_tfBottomRight", X = Pos.AnchorEnd (width), Y = Pos.AnchorEnd (1), Width = width, Text = text };
+            _appWindow.Add (_tfBottomRight);
 
-        // Shutdown - Calling Application.Shutdown is required.
-        Application.Shutdown ();
+            _appWindow.KeyDown += OnAppWindowOnKeyDown;
+            _appWindow.MouseClick += OnAppWindowOnMouseClick;
 
-        return;
+            CultureInfo originalCulture = Thread.CurrentThread.CurrentUICulture;
+            _appWindow.Closed += (s, e) => { Thread.CurrentThread.CurrentUICulture = originalCulture; };
+        }
 
-        void OnAppWindowOnMouseClick (object s, MouseEventArgs e)
+        void OnAppWindowOnMouseClick (object? s, MouseEventArgs e)
         {
             if (e.Flags == MouseFlags.Button3Clicked)
             {
@@ -88,7 +97,7 @@ public class ContextMenus : Scenario
             }
         }
 
-        void OnAppWindowOnKeyDown (object s, Key e)
+        void OnAppWindowOnKeyDown (object? s, Key e)
         {
             if (e == _winContextMenuKey)
             {
@@ -101,12 +110,6 @@ public class ContextMenus : Scenario
 
     private void CreateWinContextMenu ()
     {
-        if (_winContextMenu is { })
-        {
-            _winContextMenu.Dispose ();
-            _winContextMenu = null;
-        }
-
         _winContextMenu = new (
                                [
                                    new MenuItemv2
@@ -171,6 +174,7 @@ public class ContextMenus : Scenario
         {
             Key = _winContextMenuKey
         };
+        Application.Popover?.Register (_winContextMenu);
     }
 
     private Menuv2 GetSupportedCultureMenu ()
@@ -178,7 +182,7 @@ public class ContextMenus : Scenario
         List<MenuItemv2> supportedCultures = [];
         int index = -1;
 
-        foreach (CultureInfo c in _cultureInfos)
+        foreach (CultureInfo c in _cultureInfos!)
         {
             MenuItemv2 culture = new ();
 

+ 1 - 1
Examples/UICatalog/Scenarios/Menus.cs

@@ -121,7 +121,7 @@ public class Menus : Scenario
                         Command.Cancel,
                         ctx =>
                         {
-                            if (Application.Popover?.GetActivePopover () as PopoverMenu is { Visible: true } visiblePopover)
+                            if (App?.Popover?.GetActivePopover () as PopoverMenu is { Visible: true } visiblePopover)
                             {
                                 visiblePopover.Visible = false;
                             }

+ 1 - 1
Examples/UICatalog/Scenarios/Navigation.cs

@@ -219,7 +219,7 @@ public class Navigation : Scenario
 
             progressBar.Fraction += 0.01f;
 
-            Application.Invoke (() => { });
+            Application.Invoke ((_) => { });
         }
 
         void ColorPicker_ColorChanged (object sender, ResultEventArgs<Color> e)

+ 1 - 1
Examples/UICatalog/Scenarios/Notepad.cs

@@ -294,7 +294,7 @@ public class Notepad : Scenario
 
             // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
             // and the context menu is disposed when it is closed.
-            Application.Popover?.Register (contextMenu);
+            tv.App!.Popover?.Register (contextMenu);
             contextMenu?.MakeVisible (e.MouseEvent.ScreenPosition);
 
             e.MouseEvent.Handled = true;

+ 1 - 1
Examples/UICatalog/Scenarios/Progress.cs

@@ -43,7 +43,7 @@ public class Progress : Scenario
                                                                       {
                                                                           // Note the check for Mainloop being valid. System.Timers can run after they are Disposed.
                                                                           // This code must be defensive for that. 
-                                                                          Application.Invoke (() => systemTimerDemo.Pulse ());
+                                                                          Application.Invoke ((_) => systemTimerDemo.Pulse ());
                                                                       },
                                                                       null,
                                                                       0,

+ 1 - 1
Examples/UICatalog/Scenarios/TableEditor.cs

@@ -1363,7 +1363,7 @@ public class TableEditor : Scenario
 
         // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
         // and the context menu is disposed when it is closed.
-        Application.Popover?.Register (contextMenu);
+        e.View?.App!.Popover?.Register (contextMenu);
         contextMenu?.MakeVisible (new (e.ScreenPosition.X + 1, e.ScreenPosition.Y + 1));
     }
 

+ 1 - 1
Examples/UICatalog/Scenarios/TreeViewFileSystem.cs

@@ -418,7 +418,7 @@ public class TreeViewFileSystem : Scenario
 
         // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
         // and the context menu is disposed when it is closed.
-        Application.Popover?.Register (contextMenu);
+        _detailsFrame.App?.Popover?.Register (contextMenu);
 
         Application.Invoke (() => contextMenu?.MakeVisible (screenPoint));
     }

+ 5 - 5
Examples/UICatalog/Scenarios/ViewExperiments.cs

@@ -75,15 +75,15 @@ public class ViewExperiments : Scenario
             Y = Pos.Center (),
             Title = $"_Close",
         };
-        //popoverButton.Accepting += (sender, e) => Application.Popover!.Visible = false;
+        //popoverButton.Accepting += (sender, e) => App?.Popover!.Visible = false;
         popoverView.Add (popoverButton);
 
         button.Accepting += ButtonAccepting;
 
         void ButtonAccepting (object sender, CommandEventArgs e)
         {
-            //Application.Popover = popoverView;
-            //Application.Popover!.Visible = true;
+            //App?.Popover = popoverView;
+            //App?.Popover!.Visible = true;
         }
 
         testFrame.MouseClick += TestFrameOnMouseClick;
@@ -94,8 +94,8 @@ public class ViewExperiments : Scenario
             {
                 popoverView.X = e.ScreenPosition.X;
                 popoverView.Y = e.ScreenPosition.Y;
-                //Application.Popover = popoverView;
-                //Application.Popover!.Visible = true;
+                //App?.Popover = popoverView;
+                //App?.Popover!.Visible = true;
             }
         }
 

+ 5 - 1
Terminal.Gui/App/Application.Run.cs

@@ -49,7 +49,11 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     /// <inheritdoc cref="IApplication.TimedEvents"/>
     /// 
     public static ITimedEvents? TimedEvents => ApplicationImpl.Instance?.TimedEvents;
-    /// <inheritdoc cref="IApplication.Invoke"/>
+
+    /// <inheritdoc cref="IApplication.Invoke(Action{IApplication})"/>
+    public static void Invoke (Action<IApplication> action) => ApplicationImpl.Instance.Invoke (action);
+
+    /// <inheritdoc cref="IApplication.Invoke(Action)"/>
     public static void Invoke (Action action) => ApplicationImpl.Instance.Invoke (action);
 
     /// <inheritdoc cref="IApplication.LayoutAndDraw"/>

+ 2 - 53
Terminal.Gui/App/Application.cs

@@ -56,65 +56,14 @@ public static partial class Application
     ///     Gets a string representation of the Application as rendered by <see cref="Driver"/>.
     /// </summary>
     /// <returns>A string representation of the Application </returns>
-    public new static string ToString ()
-    {
-        IDriver? driver = Driver;
-
-        if (driver is null)
-        {
-            return string.Empty;
-        }
-
-        return ToString (driver);
-    }
+    public new static string ToString () => ApplicationImpl.Instance.ToString ();
 
     /// <summary>
     ///     Gets a string representation of the Application rendered by the provided <see cref="IDriver"/>.
     /// </summary>
     /// <param name="driver">The driver to use to render the contents.</param>
     /// <returns>A string representation of the Application </returns>
-    public static string ToString (IDriver? driver)
-    {
-        if (driver is null)
-        {
-            return string.Empty;
-        }
-
-        var sb = new StringBuilder ();
-
-        Cell [,] contents = driver?.Contents!;
-
-        for (var r = 0; r < driver!.Rows; r++)
-        {
-            for (var c = 0; c < driver.Cols; c++)
-            {
-                Rune rune = contents [r, c].Rune;
-
-                if (rune.DecodeSurrogatePair (out char []? sp))
-                {
-                    sb.Append (sp);
-                }
-                else
-                {
-                    sb.Append ((char)rune.Value);
-                }
-
-                if (rune.GetColumns () > 1)
-                {
-                    c++;
-                }
-
-                // See Issue #2616
-                //foreach (var combMark in contents [r, c].CombiningMarks) {
-                //	sb.Append ((char)combMark.Value);
-                //}
-            }
-
-            sb.AppendLine ();
-        }
-
-        return sb.ToString ();
-    }
+    public static string ToString (IDriver? driver) => ApplicationImpl.Instance.ToString (driver);
 
     /// <summary>Gets all cultures supported by the application without the invariant language.</summary>
     public static List<CultureInfo>? SupportedCultures { get; private set; } = GetSupportedCultures ();

+ 1 - 1
Terminal.Gui/App/ApplicationImpl.Driver.cs

@@ -79,7 +79,7 @@ public partial class ApplicationImpl
 
         Logging.Trace ($"Created Subcomponents: {Coordinator}");
 
-        Coordinator.StartInputTaskAsync ().Wait ();
+        Coordinator.StartInputTaskAsync (this).Wait ();
 
         if (Driver == null)
         {

+ 3 - 2
Terminal.Gui/App/ApplicationImpl.Lifecycle.cs

@@ -36,8 +36,8 @@ public partial class ApplicationImpl
        // Debug.Assert (Navigation is null);
        // Navigation = new ();
 
-        Debug.Assert (Popover is null);
-        Popover = new ();
+        //Debug.Assert (Popover is null);
+        //Popover = new ();
 
         // Preserve existing keyboard settings if they exist
         bool hasExistingKeyboard = _keyboard is { };
@@ -169,6 +169,7 @@ public partial class ApplicationImpl
             popover.Visible = false;
         }
 
+        // Any popovers added to Popover have their lifetime controlled by Popover
         Popover?.Dispose ();
         Popover = null;
 

+ 25 - 2
Terminal.Gui/App/ApplicationImpl.Run.cs

@@ -323,13 +323,36 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     public bool RemoveTimeout (object token) { return _timedEvents.Remove (token); }
 
+    /// <inheritdoc/>
+    public void Invoke (Action<IApplication>? action)
+    {
+        // If we are already on the main UI thread
+        if (Current is { Running: true } && MainThreadId == Thread.CurrentThread.ManagedThreadId)
+        {
+            action?.Invoke (this);
+
+            return;
+        }
+
+        _timedEvents.Add (
+                          TimeSpan.Zero,
+                          () =>
+                          {
+                              action?.Invoke (this);
+
+                              return false;
+                          }
+                         );
+    }
+
+
     /// <inheritdoc/>
     public void Invoke (Action action)
     {
         // If we are already on the main UI thread
         if (Current is { Running: true } && MainThreadId == Thread.CurrentThread.ManagedThreadId)
         {
-            action ();
+            action?.Invoke ();
 
             return;
         }
@@ -338,7 +361,7 @@ public partial class ApplicationImpl
                           TimeSpan.Zero,
                           () =>
                           {
-                              action ();
+                              action?.Invoke ();
 
                               return false;
                           }

+ 89 - 3
Terminal.Gui/App/ApplicationImpl.cs

@@ -56,7 +56,7 @@ public partial class ApplicationImpl : IApplication
         {
             if (_mouse is null)
             {
-                _mouse = new MouseImpl { Application = this };
+                _mouse = new MouseImpl { App = this };
             }
 
             return _mouse;
@@ -87,8 +87,22 @@ public partial class ApplicationImpl : IApplication
 
     #region View Management
 
+    private ApplicationPopover? _popover;
+
     /// <inheritdoc/>
-    public ApplicationPopover? Popover { get; set; }
+    public ApplicationPopover? Popover
+    {
+        get
+        {
+            if (_popover is null)
+            {
+                _popover = new () { App = this };
+            }
+
+            return _popover;
+        }
+        set => _popover = value;
+    }
 
     private ApplicationNavigation? _navigation;
 
@@ -107,8 +121,22 @@ public partial class ApplicationImpl : IApplication
         set => _navigation = value ?? throw new ArgumentNullException (nameof (value));
     }
 
+    private Toplevel? _current;
+
     /// <inheritdoc/>
-    public Toplevel? Current { get; set; }
+    public Toplevel? Current
+    {
+        get => _current;
+        set
+        {
+            _current = value;
+
+            if (_current is { })
+            {
+                _current.App = this;
+            }
+        }
+    }
 
     // BUGBUG: Technically, this is not the full lst of sessions. There be dragons here, e.g. see how Toplevel.Id is used. What
 
@@ -119,4 +147,62 @@ public partial class ApplicationImpl : IApplication
     public Toplevel? CachedSessionTokenToplevel { get; set; }
 
     #endregion View Management
+
+    /// <inheritdoc/>
+    public new string ToString ()
+    {
+        IDriver? driver = Driver;
+
+        if (driver is null)
+        {
+            return string.Empty;
+        }
+
+        return ToString (driver);
+    }
+
+    /// <inheritdoc/>
+    public string ToString (IDriver? driver)
+    {
+        if (driver is null)
+        {
+            return string.Empty;
+        }
+
+        var sb = new StringBuilder ();
+
+        Cell [,] contents = driver?.Contents!;
+
+        for (var r = 0; r < driver!.Rows; r++)
+        {
+            for (var c = 0; c < driver.Cols; c++)
+            {
+                Rune rune = contents [r, c].Rune;
+
+                if (rune.DecodeSurrogatePair (out char []? sp))
+                {
+                    sb.Append (sp);
+                }
+                else
+                {
+                    sb.Append ((char)rune.Value);
+                }
+
+                if (rune.GetColumns () > 1)
+                {
+                    c++;
+                }
+
+                // See Issue #2616
+                //foreach (var combMark in contents [r, c].CombiningMarks) {
+                //	sb.Append ((char)combMark.Value);
+                //}
+            }
+
+            sb.AppendLine ();
+        }
+
+        return sb.ToString ();
+    }
+
 }

+ 31 - 11
Terminal.Gui/App/ApplicationPopover.cs

@@ -4,8 +4,8 @@ using System.Diagnostics;
 namespace Terminal.Gui.App;
 
 /// <summary>
-///     Helper class for support of <see cref="IPopover"/> views for <see cref="Application"/>. Held by
-///     <see cref="Application.Popover"/>
+///     Helper class for support of <see cref="IPopover"/> views for <see cref="IApplication"/>. Held by
+///     <see cref="IApplication.Popover"/>
 /// </summary>
 public sealed class ApplicationPopover : IDisposable
 {
@@ -14,6 +14,11 @@ public sealed class ApplicationPopover : IDisposable
     /// </summary>
     public ApplicationPopover () { }
 
+    /// <summary>
+    ///     The <see cref="IApplication"/> instance used by this instance.
+    /// </summary>
+    public IApplication? App { get; set; }
+
     private readonly List<IPopover> _popovers = [];
 
     /// <summary>
@@ -34,10 +39,15 @@ public sealed class ApplicationPopover : IDisposable
     /// <returns><paramref name="popover"/>, after it has been registered.</returns>
     public IPopover? Register (IPopover? popover)
     {
-        if (popover is { } && !_popovers.Contains (popover))
+        if (popover is { } && !IsRegistered (popover))
         {
             // When created, set IPopover.Toplevel to the current Application.Current
-            popover.Current ??= Application.Current;
+            popover.Current ??= App?.Current;
+
+            if (popover is View popoverView)
+            {
+                popoverView.App = App;
+            }
 
             _popovers.Add (popover);
         }
@@ -45,6 +55,13 @@ public sealed class ApplicationPopover : IDisposable
         return popover;
     }
 
+    /// <summary>
+    ///     Indicates whether a popover has been registered or not.
+    /// </summary>
+    /// <param name="popover"></param>
+    /// <returns></returns>
+    public bool IsRegistered (IPopover? popover) => popover is { } && _popovers.Contains (popover);
+
     /// <summary>
     ///     De-registers <paramref name="popover"/> with the application. Use this to remove the popover and it's
     ///     keyboard bindings from the application.
@@ -58,7 +75,7 @@ public sealed class ApplicationPopover : IDisposable
     /// <returns></returns>
     public bool DeRegister (IPopover? popover)
     {
-        if (popover is null || !_popovers.Contains (popover))
+        if (popover is null || !IsRegistered (popover))
         {
             return false;
         }
@@ -99,9 +116,14 @@ public sealed class ApplicationPopover : IDisposable
     /// <param name="popover"></param>
     public void Show (IPopover? popover)
     {
+        if (!IsRegistered (popover))
+        {
+            throw new InvalidOperationException (@"Popovers must be registered before being shown.");
+        }
         // If there's an existing popover, hide it.
         if (_activePopover is View popoverView)
         {
+            popoverView.App = App;
             popoverView.Visible = false;
             _activePopover = null;
         }
@@ -119,9 +141,6 @@ public sealed class ApplicationPopover : IDisposable
                 throw new InvalidOperationException ("Popovers must have a key binding for Command.Quit.");
             }
 
-
-            Register (popover);
-
             if (!newPopover.IsInitialized)
             {
                 newPopover.BeginInit ();
@@ -147,7 +166,7 @@ public sealed class ApplicationPopover : IDisposable
         {
             _activePopover = null;
             popoverView.Visible = false;
-            Application.Current?.SetNeedsDraw ();
+            popoverView.App?.Current?.SetNeedsDraw ();
         }
     }
 
@@ -176,7 +195,7 @@ public sealed class ApplicationPopover : IDisposable
     internal bool DispatchKeyDown (Key key)
     {
         // Do active first - Active gets all key down events.
-        var activePopover = GetActivePopover () as View;
+        View? activePopover = GetActivePopover () as View;
 
         if (activePopover is { Visible: true })
         {
@@ -196,13 +215,14 @@ public sealed class ApplicationPopover : IDisposable
         {
             if (popover == activePopover
                 || popover is not View popoverView
-                || (popover.Current is { } && popover.Current != Application.Current))
+                || (popover.Current is { } && popover.Current != App?.Current))
             {
                 continue;
             }
 
             // hotKeyHandled = popoverView.InvokeCommandsBoundToHotKey (key);
             //Logging.Debug ($"Inactive - Calling NewKeyDownEvent ({key}) on {popoverView.Title}");
+            popoverView.App ??= App;
             hotKeyHandled = popoverView.NewKeyDownEvent (key);
 
             if (hotKeyHandled is true)

+ 24 - 0
Terminal.Gui/App/IApplication.cs

@@ -265,6 +265,17 @@ public interface IApplication
     /// </remarks>
     public event EventHandler<IterationEventArgs>? Iteration;
 
+    /// <summary>Runs <paramref name="action"/> on the main UI loop thread.</summary>
+    /// <param name="action">The action to be invoked on the main processing thread.</param>
+    /// <remarks>
+    ///     <para>
+    ///         If called from the main thread, the action is executed immediately. Otherwise, it is queued via
+    ///         <see cref="AddTimeout"/> with <see cref="TimeSpan.Zero"/> and will be executed on the next main loop
+    ///         iteration.
+    ///     </para>
+    /// </remarks>
+    void Invoke (Action<IApplication>? action);
+
     /// <summary>Runs <paramref name="action"/> on the main UI loop thread.</summary>
     /// <param name="action">The action to be invoked on the main processing thread.</param>
     /// <remarks>
@@ -538,4 +549,17 @@ public interface IApplication
     ITimedEvents? TimedEvents { get; }
 
     #endregion Timeouts
+
+    /// <summary>
+    ///     Gets a string representation of the Application as rendered by <see cref="Driver"/>.
+    /// </summary>
+    /// <returns>A string representation of the Application </returns>
+    public string ToString ();
+
+    /// <summary>
+    ///     Gets a string representation of the Application rendered by the provided <see cref="IDriver"/>.
+    /// </summary>
+    /// <param name="driver">The driver to use to render the contents.</param>
+    /// <returns>A string representation of the Application </returns>
+    public string ToString (IDriver? driver);
 }

+ 17 - 11
Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs

@@ -27,6 +27,9 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
     private AnsiRequestScheduler? _ansiRequestScheduler;
     private ISizeMonitor? _sizeMonitor;
 
+    /// <inheritdoc/>
+    public IApplication? App { get; private set; }
+
     /// <inheritdoc/>
     public ITimedEvents TimedEvents
     {
@@ -79,7 +82,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
     }
 
     /// <summary>
-    ///     Handles raising events and setting required draw status etc when <see cref="Application.Current"/> changes
+    ///     Handles raising events and setting required draw status etc when <see cref="IApplication.Current"/> changes
     /// </summary>
     public IToplevelTransitionManager ToplevelTransitionManager = new ToplevelTransitionManager ();
 
@@ -91,14 +94,17 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
     /// <param name="inputProcessor"></param>
     /// <param name="consoleOutput"></param>
     /// <param name="componentFactory"></param>
+    /// <param name="app"></param>
     public void Initialize (
         ITimedEvents timedEvents,
         ConcurrentQueue<TInputRecord> inputBuffer,
         IInputProcessor inputProcessor,
         IOutput consoleOutput,
-        IComponentFactory<TInputRecord> componentFactory
+        IComponentFactory<TInputRecord> componentFactory,
+        IApplication? app
     )
     {
+        App = app;
         InputQueue = inputBuffer;
         Output = consoleOutput;
         InputProcessor = inputProcessor;
@@ -113,10 +119,10 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
     /// <inheritdoc/>
     public void Iteration ()
     {
-        Application.RaiseIteration ();
+        App?.RaiseIteration ();
 
         DateTime dt = DateTime.Now;
-        int timeAllowed = 1000 / Math.Max(1,(int)Application.MaximumIterationsPerSecond);
+        int timeAllowed = 1000 / Math.Max (1, (int)Application.MaximumIterationsPerSecond);
 
         IterationImpl ();
 
@@ -139,11 +145,11 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
         ToplevelTransitionManager.RaiseReadyEventIfNeeded ();
         ToplevelTransitionManager.HandleTopMaybeChanging ();
 
-        if (Application.Current != null)
+        if (App?.Current != null)
         {
-            bool needsDrawOrLayout = AnySubViewsNeedDrawn (Application.Popover?.GetActivePopover () as View)
-                                     || AnySubViewsNeedDrawn (Application.Current)
-                                     || (Application.Mouse.MouseGrabView != null && AnySubViewsNeedDrawn (Application.Mouse.MouseGrabView));
+            bool needsDrawOrLayout = AnySubViewsNeedDrawn (App?.Popover?.GetActivePopover () as View)
+                                     || AnySubViewsNeedDrawn (App?.Current)
+                                     || (App?.Mouse.MouseGrabView != null && AnySubViewsNeedDrawn (App?.Mouse.MouseGrabView));
 
             bool sizeChanged = SizeMonitor.Poll ();
 
@@ -151,7 +157,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
             {
                 Logging.Redraws.Add (1);
 
-                Application.LayoutAndDraw (true);
+                App?.LayoutAndDraw (true);
 
                 Output.Write (OutputBuffer);
 
@@ -170,7 +176,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
 
     private void SetCursor ()
     {
-        View? mostFocused = Application.Current!.MostFocused;
+        View? mostFocused = App?.Current!.MostFocused;
 
         if (mostFocused == null)
         {
@@ -202,7 +208,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
 
         if (v.NeedsDraw || v.NeedsLayout)
         {
-           // Logging.Trace ($"{v.GetType ().Name} triggered redraw (NeedsDraw={v.NeedsDraw} NeedsLayout={v.NeedsLayout}) ");
+            // Logging.Trace ($"{v.GetType ().Name} triggered redraw (NeedsDraw={v.NeedsDraw} NeedsLayout={v.NeedsLayout}) ");
 
             return true;
         }

+ 8 - 1
Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs

@@ -17,6 +17,11 @@ namespace Terminal.Gui.App;
 /// <typeparam name="TInputRecord">Type of raw input events processed by the loop, e.g. <see cref="ConsoleKeyInfo"/> for cross-platform .NET driver</typeparam>
 public interface IApplicationMainLoop<TInputRecord> : IDisposable where TInputRecord : struct
 {
+    /// <summary>
+    ///     The Application this loop is associated with.
+    /// </summary>
+    public IApplication? App { get; }
+
     /// <summary>
     ///     Gets the <see cref="ITimedEvents"/> implementation that manages user-defined timeouts and periodic events.
     /// </summary>
@@ -72,6 +77,7 @@ public interface IApplicationMainLoop<TInputRecord> : IDisposable where TInputRe
     ///     The factory for creating driver-specific components. Used here to create the <see cref="ISizeMonitor"/>
     ///     that tracks terminal size changes.
     /// </param>
+    /// <param name="app"></param>
     /// <remarks>
     ///     <para>
     ///         This method is called by <see cref="MainLoopCoordinator{TInputRecord}"/> during application startup
@@ -97,7 +103,8 @@ public interface IApplicationMainLoop<TInputRecord> : IDisposable where TInputRe
         ConcurrentQueue<TInputRecord> inputQueue,
         IInputProcessor inputProcessor,
         IOutput output,
-        IComponentFactory<TInputRecord> componentFactory
+        IComponentFactory<TInputRecord> componentFactory,
+        IApplication? app
     );
 
     /// <summary>

+ 2 - 1
Terminal.Gui/App/MainLoop/IMainLoopCoordinator.cs

@@ -16,6 +16,7 @@ public interface IMainLoopCoordinator
     /// <summary>
     ///     Initializes all required subcomponents and starts the input thread.
     /// </summary>
+    /// <param name="app"></param>
     /// <remarks>
     ///     This method:
     ///     <list type="number">
@@ -25,7 +26,7 @@ public interface IMainLoopCoordinator
     ///     </list>
     /// </remarks>
     /// <returns>A task that completes when initialization is done</returns>
-    public Task StartInputTaskAsync ();
+    public Task StartInputTaskAsync (IApplication? app);
 
     /// <summary>
     ///     Stops the input thread and performs cleanup.

+ 19 - 18
Terminal.Gui/App/MainLoop/MainLoopCoordinator.cs

@@ -1,5 +1,4 @@
-#nullable disable
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
 
 namespace Terminal.Gui.App;
 
@@ -47,24 +46,25 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
     private readonly ITimedEvents _timedEvents;
 
     private readonly SemaphoreSlim _startupSemaphore = new (0, 1);
-    private IInput<TInputRecord> _input;
-    private Task _inputTask;
-    private IOutput _output;
-    private DriverImpl _driver;
+    private IInput<TInputRecord>? _input;
+    private Task? _inputTask;
+    private IOutput? _output;
+    private DriverImpl? _driver;
 
     private bool _stopCalled;
 
     /// <summary>
     ///     Starts the input loop thread in separate task (returning immediately).
     /// </summary>
-    public async Task StartInputTaskAsync ()
+    /// <param name="app">The <see cref="IApplication"/> instance that is running the input loop.</param>
+    public async Task StartInputTaskAsync (IApplication? app)
     {
         Logging.Trace ("Booting... ()");
 
-        _inputTask = Task.Run (RunInput);
+        _inputTask = Task.Run (() => RunInput (app));
 
         // Main loop is now booted on same thread as rest of users application
-        BootMainLoop ();
+        BootMainLoop (app);
 
         // Wait asynchronously for the semaphore or task failure.
         Task waitForSemaphore = _startupSemaphore.WaitAsync ();
@@ -108,13 +108,13 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
         _stopCalled = true;
 
         _runCancellationTokenSource.Cancel ();
-        _output.Dispose ();
+        _output?.Dispose ();
 
         // Wait for input infinite loop to exit
-        _inputTask.Wait ();
+        _inputTask?.Wait ();
     }
 
-    private void BootMainLoop ()
+    private void BootMainLoop (IApplication? app)
     {
         //Logging.Trace ($"_inputProcessor: {_inputProcessor}, _output: {_output}, _componentFactory: {_componentFactory}");
 
@@ -122,13 +122,13 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
         {
             // Instance must be constructed on the thread in which it is used.
             _output = _componentFactory.CreateOutput ();
-            _loop.Initialize (_timedEvents, _inputQueue, _inputProcessor, _output, _componentFactory);
+            _loop.Initialize (_timedEvents, _inputQueue, _inputProcessor, _output, _componentFactory, app);
 
-            BuildDriverIfPossible ();
+            BuildDriverIfPossible (app);
         }
     }
 
-    private void BuildDriverIfPossible ()
+    private void BuildDriverIfPossible (IApplication? app)
     {
 
         if (_input != null && _output != null)
@@ -140,7 +140,7 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
                            _loop.AnsiRequestScheduler,
                            _loop.SizeMonitor);
 
-            Application.Driver = _driver;
+            app!.Driver = _driver;
 
             _startupSemaphore.Release ();
             Logging.Trace ($"Driver: _input: {_input}, _output: {_output}");
@@ -150,7 +150,8 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
     /// <summary>
     ///     INTERNAL: Runs the IInput read loop on a new thread called the "Input Thread".
     /// </summary>
-    private void RunInput ()
+    /// <param name="app"></param>
+    private void RunInput (IApplication? app)
     {
         try
         {
@@ -166,7 +167,7 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
                     impl.InputImpl = _input;
                 }
 
-                BuildDriverIfPossible ();
+                BuildDriverIfPossible (app);
             }
 
             try

+ 7 - 7
Terminal.Gui/App/MainLoop/MainLoopSyncContext.cs

@@ -26,13 +26,13 @@ internal sealed class MainLoopSyncContext : SynchronizationContext
         {
             var wasExecuted = false;
 
-            Application.Invoke (
-                                () =>
-                                {
-                                    d (state);
-                                    wasExecuted = true;
-                                }
-                               );
+            ApplicationImpl.Instance.Invoke (
+                                             () =>
+                                             {
+                                                 d (state);
+                                                 wasExecuted = true;
+                                             }
+                                            );
 
             while (!wasExecuted)
             {

+ 2 - 2
Terminal.Gui/App/Mouse/IMouse.cs

@@ -5,7 +5,7 @@ namespace Terminal.Gui.App;
 /// <summary>
 ///     Defines a contract for mouse event handling and state management in a Terminal.Gui application.
 ///     <para>
-///         This interface allows for decoupling of mouse-related functionality from the static <see cref="Application"/> class,
+///         This interface allows for decoupling of mouse-related functionality from the static <see cref="App"/> class,
 ///         enabling better testability and parallel test execution.
 ///     </para>
 /// </summary>
@@ -15,7 +15,7 @@ public interface IMouse : IMouseGrabHandler
     /// Sets the application instance that this mouse handler is associated with.
     /// This provides access to application state without coupling to static Application class.
     /// </summary>
-    IApplication? Application { get; set; }
+    IApplication? App { get; set; }
 
     /// <summary>
     ///     Gets or sets the last known position of the mouse.

+ 12 - 9
Terminal.Gui/App/Mouse/MouseImpl.cs

@@ -5,7 +5,7 @@ namespace Terminal.Gui.App;
 /// <summary>
 ///     INTERNAL: Implements <see cref="IMouse"/> to manage mouse event handling and state.
 ///     <para>
-///         This class holds all mouse-related state that was previously in the static <see cref="Application"/> class,
+///         This class holds all mouse-related state that was previously in the static <see cref="App"/> class,
 ///         enabling better testability and parallel test execution.
 ///     </para>
 /// </summary>
@@ -17,7 +17,7 @@ internal class MouseImpl : IMouse
     public MouseImpl () { }
 
     /// <inheritdoc/>
-    public IApplication? Application { get; set; }
+    public IApplication? App { get; set; }
 
     /// <inheritdoc/>
     public Point? LastMousePosition { get; set; }
@@ -55,7 +55,7 @@ internal class MouseImpl : IMouse
     public void RaiseMouseEvent (MouseEventArgs mouseEvent)
     {
         //Debug.Assert (App.Application.MainThreadId == Thread.CurrentThread.ManagedThreadId);
-        if (Application?.Initialized is true)
+        if (App?.Initialized is true)
         {
             // LastMousePosition is only set if the application is initialized.
             LastMousePosition = mouseEvent.ScreenPosition;
@@ -70,9 +70,9 @@ internal class MouseImpl : IMouse
         //Debug.Assert (mouseEvent.Position == mouseEvent.ScreenPosition);
         mouseEvent.Position = mouseEvent.ScreenPosition;
 
-        List<View?> currentViewsUnderMouse = View.GetViewsUnderLocation (mouseEvent.ScreenPosition, ViewportSettingsFlags.TransparentMouse);
+        List<View?>? currentViewsUnderMouse = App?.Current?.GetViewsUnderLocation (mouseEvent.ScreenPosition, ViewportSettingsFlags.TransparentMouse);
 
-        View? deepestViewUnderMouse = currentViewsUnderMouse.LastOrDefault ();
+        View? deepestViewUnderMouse = currentViewsUnderMouse?.LastOrDefault ();
 
         if (deepestViewUnderMouse is { })
         {
@@ -94,7 +94,7 @@ internal class MouseImpl : IMouse
 
         // Dismiss the Popover if the user presses mouse outside of it
         if (mouseEvent.IsPressed
-            && Application?.Popover?.GetActivePopover () as View is { Visible: true } visiblePopover
+            && App?.Popover?.GetActivePopover () as View is { Visible: true } visiblePopover
             && View.IsInHierarchy (visiblePopover, deepestViewUnderMouse, includeAdornments: true) is false)
         {
             ApplicationPopover.HideWithQuitCommand (visiblePopover);
@@ -117,9 +117,9 @@ internal class MouseImpl : IMouse
             return;
         }
 
-        // if the mouse is outside the Application.Current or Application.Popover hierarchy, we don't want to
+        // if the mouse is outside the Application.Current or Popover hierarchy, we don't want to
         // send the mouse event to the deepest view under the mouse.
-        if (!View.IsInHierarchy (Application?.Current, deepestViewUnderMouse, true) && !View.IsInHierarchy (Application?.Popover?.GetActivePopover () as View, deepestViewUnderMouse, true))
+        if (!View.IsInHierarchy (App?.Current, deepestViewUnderMouse, true) && !View.IsInHierarchy (App?.Popover?.GetActivePopover () as View, deepestViewUnderMouse, true))
         {
             return;
         }
@@ -159,7 +159,10 @@ internal class MouseImpl : IMouse
             return;
         }
 
-        RaiseMouseEnterLeaveEvents (viewMouseEvent.ScreenPosition, currentViewsUnderMouse);
+        if (currentViewsUnderMouse is { })
+        {
+            RaiseMouseEnterLeaveEvents (viewMouseEvent.ScreenPosition, currentViewsUnderMouse);
+        }
 
         while (deepestViewUnderMouse.NewMouseEvent (viewMouseEvent) is not true && MouseGrabView is not { })
         {

+ 11 - 1
Terminal.Gui/App/PopoverBaseImpl.cs

@@ -73,8 +73,18 @@ public abstract class PopoverBaseImpl : View, IPopover
         }
     }
 
+    private Toplevel? _current;
+
     /// <inheritdoc/>
-    public Toplevel? Current { get; set; }
+    public Toplevel? Current
+    {
+        get => _current;
+        set
+        {
+            _current = value;
+            App ??= _current?.App;
+        }
+    }
 
     /// <summary>
     ///     Called when the <see cref="View.Visible"/> property is changing.

+ 3 - 3
Terminal.Gui/App/Toplevel/ToplevelTransitionManager.cs

@@ -12,7 +12,7 @@ public class ToplevelTransitionManager : IToplevelTransitionManager
     /// <inheritdoc/>
     public void RaiseReadyEventIfNeeded ()
     {
-        Toplevel? top = Application.Current;
+        Toplevel? top = ApplicationImpl.Instance.Current;
 
         if (top != null && !_readiedTopLevels.Contains (top))
         {
@@ -27,13 +27,13 @@ public class ToplevelTransitionManager : IToplevelTransitionManager
     /// <inheritdoc/>
     public void HandleTopMaybeChanging ()
     {
-        Toplevel? newTop = Application.Current;
+        Toplevel? newTop = ApplicationImpl.Instance.Current;
 
         if (_lastTop != null && _lastTop != newTop && newTop != null)
         {
             newTop.SetNeedsDraw ();
         }
 
-        _lastTop = Application.Current;
+        _lastTop = ApplicationImpl.Instance.Current;
     }
 }

+ 1 - 1
Terminal.Gui/Drivers/FakeDriver/FakeInputProcessor.cs

@@ -37,7 +37,7 @@ public class FakeInputProcessor : InputProcessorImpl<ConsoleKeyInfo>
         if (Application.MainThreadId is { })
         {
             // Application is running - use Invoke to defer to next iteration
-            Application.Invoke (() => RaiseMouseEvent (mouseEvent));
+            ApplicationImpl.Instance.Invoke ((_) => RaiseMouseEvent (mouseEvent));
         }
         else
         {

+ 3 - 3
Terminal.Gui/Drivers/WindowsDriver/WindowsOutput.cs

@@ -147,7 +147,7 @@ internal partial class WindowsOutput : OutputBase, IOutput
             }
 
             // Force 16 colors if not in virtual terminal mode.
-            Application.Force16Colors = true;
+            ApplicationImpl.Instance.Force16Colors = true;
 
         }
 
@@ -262,7 +262,7 @@ internal partial class WindowsOutput : OutputBase, IOutput
 
     public override void Write (IOutputBuffer outputBuffer)
     {
-        _force16Colors = Application.Driver!.Force16Colors;
+        _force16Colors = ApplicationImpl.Instance.Driver!.Force16Colors;
         _everythingStringBuilder.Clear ();
 
         // for 16 color mode we will write to a backing buffer then flip it to the active one at the end to avoid jitter.
@@ -344,7 +344,7 @@ internal partial class WindowsOutput : OutputBase, IOutput
     /// <inheritdoc/>
     protected override void AppendOrWriteAttribute (StringBuilder output, Attribute attr, TextStyle redrawTextStyle)
     {
-        bool force16Colors = Application.Force16Colors;
+        bool force16Colors = ApplicationImpl.Instance.Force16Colors;
 
         if (force16Colors)
         {

+ 11 - 16
Terminal.Gui/Text/TextFormatter.cs

@@ -10,7 +10,7 @@ namespace Terminal.Gui.Text;
 public class TextFormatter
 {
     // Utilized in CRLF related helper methods for faster newline char index search.
-    private static readonly SearchValues<char> NewlineSearchValues = SearchValues.Create(['\r', '\n']);
+    private static readonly SearchValues<char> NewlineSearchValues = SearchValues.Create (['\r', '\n']);
 
     private Key _hotKey = new ();
     private int _hotKeyPos = -1;
@@ -73,11 +73,6 @@ public class TextFormatter
             return;
         }
 
-        if (driver is null)
-        {
-            driver = Application.Driver;
-        }
-
         driver?.SetAttribute (normalColor);
 
         List<string> linesFormatted = GetLines ();
@@ -1200,8 +1195,8 @@ public class TextFormatter
             return str;
         }
 
-        StringBuilder stringBuilder = new();
-        ReadOnlySpan<char> firstSegment = remaining[..firstNewlineCharIndex];
+        StringBuilder stringBuilder = new ();
+        ReadOnlySpan<char> firstSegment = remaining [..firstNewlineCharIndex];
         stringBuilder.Append (firstSegment);
 
         // The first newline is not yet skipped because the "keepNewLine" condition has not been evaluated.
@@ -1216,7 +1211,7 @@ public class TextFormatter
                 break;
             }
 
-            ReadOnlySpan<char> segment = remaining[..newlineCharIndex];
+            ReadOnlySpan<char> segment = remaining [..newlineCharIndex];
             stringBuilder.Append (segment);
 
             int stride = segment.Length;
@@ -1268,8 +1263,8 @@ public class TextFormatter
             return str;
         }
 
-        StringBuilder stringBuilder = new();
-        ReadOnlySpan<char> firstSegment = remaining[..firstNewlineCharIndex];
+        StringBuilder stringBuilder = new ();
+        ReadOnlySpan<char> firstSegment = remaining [..firstNewlineCharIndex];
         stringBuilder.Append (firstSegment);
 
         // The first newline is not yet skipped because the newline type has not been evaluated.
@@ -1284,7 +1279,7 @@ public class TextFormatter
                 break;
             }
 
-            ReadOnlySpan<char> segment = remaining[..newlineCharIndex];
+            ReadOnlySpan<char> segment = remaining [..newlineCharIndex];
             stringBuilder.Append (segment);
 
             int stride = segment.Length;
@@ -2446,12 +2441,12 @@ public class TextFormatter
         }
 
         const int maxStackallocCharBufferSize = 512; // ~1 kB
-        char[]? rentedBufferArray = null;
+        char []? rentedBufferArray = null;
         try
         {
             Span<char> buffer = text.Length <= maxStackallocCharBufferSize
-                ? stackalloc char[text.Length]
-                : (rentedBufferArray = ArrayPool<char>.Shared.Rent(text.Length));
+                ? stackalloc char [text.Length]
+                : (rentedBufferArray = ArrayPool<char>.Shared.Rent (text.Length));
 
             int i = 0;
             var remainingBuffer = buffer;
@@ -2469,7 +2464,7 @@ public class TextFormatter
 
             ReadOnlySpan<char> newText = buffer [..^remainingBuffer.Length];
             // If the resulting string would be the same as original then just return the original.
-            if (newText.Equals(text, StringComparison.Ordinal))
+            if (newText.Equals (text, StringComparison.Ordinal))
             {
                 return text;
             }

+ 1 - 1
Terminal.Gui/ViewBase/Adornment/ShadowView.cs

@@ -170,7 +170,7 @@ internal class ShadowView : View
         // use the Normal attribute from the View under the shadow.
         if (newAttribute.Background == Color.DarkGray)
         {
-            List<View?> currentViewsUnderMouse = View.GetViewsUnderLocation (location, ViewportSettingsFlags.Transparent);
+            List<View?> currentViewsUnderMouse = GetViewsUnderLocation (location, ViewportSettingsFlags.Transparent);
             View? underView = currentViewsUnderMouse!.LastOrDefault ();
             attr = underView?.GetAttributeForRole (VisualRole.Normal) ?? Attribute.Default;
 

+ 3 - 3
Terminal.Gui/ViewBase/IDesignable.cs

@@ -9,10 +9,10 @@ public interface IDesignable
     ///     Causes the View to enable design-time mode. This typically means that the view will load demo data and
     ///     be configured to allow for design-time manipulation.
     /// </summary>
-    /// <param name="context">Optional arbitrary, View-specific, context.</param>
-    /// <typeparam name="TContext">A non-null type for <paramref name="context"/>.</typeparam>
+    /// <param name="targetView"></param>
+    /// <typeparam name="TContext">A non-null type for <paramref name="targetView"/>.</typeparam>
     /// <returns><see langword="true"/> if the view successfully loaded demo data.</returns>
-    public bool EnableForDesign<TContext> (ref TContext context) where TContext : notnull => EnableForDesign ();
+    public bool EnableForDesign<TContext> (ref TContext targetView) where TContext : notnull => EnableForDesign ();
 
     /// <summary>
     ///     Causes the View to enable design-time mode. This typically means that the view will load demo data and

+ 1 - 1
Terminal.Gui/ViewBase/View.Hierarchy.cs

@@ -367,7 +367,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
     /// <returns>The superview view.</returns>
     internal View? GetTopSuperView (View? view = null, View? superview = null)
     {
-        View? top = superview ?? Application.Current;
+        View? top = superview ?? App?.Current;
 
         for (View? v = view?.SuperView ?? this?.SuperView; v != null; v = v.SuperView)
         {

+ 33 - 23
Terminal.Gui/ViewBase/View.Layout.cs

@@ -437,10 +437,10 @@ public partial class View // Layout APIs
 
     private void NeedsClearScreenNextIteration ()
     {
-        if (Application.Current is { } && Application.Current == this && Application.SessionStack.Count == 1)
+        if (App is { Current: { } } && App.Current == this && App.SessionStack.Count == 1)
         {
             // If this is the only TopLevel, we need to redraw the screen
-            Application.ClearScreenNextIteration = true;
+            App.ClearScreenNextIteration = true;
         }
     }
 
@@ -531,7 +531,7 @@ public partial class View // Layout APIs
 
     /// <summary>
     ///     Performs layout of the view and its subviews using the content size of either the <see cref="SuperView"/> or
-    ///     <see cref="Application.Screen"/>.
+    ///     <see cref="IApplication.Screen"/>.
     /// </summary>
     /// <remarks>
     ///     <para>
@@ -544,7 +544,7 @@ public partial class View // Layout APIs
     ///     </para>
     /// </remarks>
     /// <returns><see langword="false"/>If the view could not be laid out (typically because dependency was not ready). </returns>
-    public bool Layout () { return Layout (GetContainerSize ()); }
+    public bool Layout () => Layout (GetContainerSize ());
 
     /// <summary>
     ///     Sets the position and size of this view, relative to the SuperView's ContentSize (nominally the same as
@@ -1113,11 +1113,12 @@ public partial class View // Layout APIs
     {
         // TODO: Get rid of refs to Top
         Size superViewContentSize = SuperView?.GetContentSize ()
-                                    ?? (Application.Current is { } && Application.Current != this && Application.Current.IsInitialized
-                                            ? Application.Current.GetContentSize ()
-                                            : Application.Screen.Size);
+                                    ?? (App?.Current is { } && App?.Current != this && App!.Current.IsInitialized
+                                            ? App.Current.GetContentSize ()
+                                            : App?.Screen.Size ?? new (2048, 2048));
 
         return superViewContentSize;
+
     }
 
     // BUGBUG: This method interferes with Dialog/MessageBox default min/max size.
@@ -1129,7 +1130,7 @@ public partial class View // Layout APIs
     /// </summary>
     /// <remarks>
     ///     If <paramref name="viewToMove"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
-    ///     <see cref="Application.Current"/> the position will be bound by  <see cref="Application.Screen"/>.
+    ///     <see cref="IApplication.Current"/> the position will be bound by  <see cref="IApplication.Screen"/>.
     /// </remarks>
     /// <param name="viewToMove">The View that is to be moved.</param>
     /// <param name="targetX">The target x location.</param>
@@ -1137,7 +1138,7 @@ public partial class View // Layout APIs
     /// <param name="nx">The new x location that will ensure <paramref name="viewToMove"/> will be fully visible.</param>
     /// <param name="ny">The new y location that will ensure <paramref name="viewToMove"/> will be fully visible.</param>
     /// <returns>
-    ///     Either <see cref="Application.Current"/> (if <paramref name="viewToMove"/> does not have a Super View) or
+    ///     Either <see cref="IApplication.Current"/> (if <paramref name="viewToMove"/> does not have a Super View) or
     ///     <paramref name="viewToMove"/>'s SuperView. This can be used to ensure LayoutSubViews is called on the correct View.
     /// </returns>
     internal static View? GetLocationEnsuringFullVisibility (
@@ -1151,10 +1152,12 @@ public partial class View // Layout APIs
         int maxDimension;
         View? superView;
 
-        if (viewToMove?.SuperView is null || viewToMove == Application.Current || viewToMove?.SuperView == Application.Current)
+        IApplication? app = viewToMove.App;
+
+        if (viewToMove?.SuperView is null || viewToMove == app?.Current || viewToMove?.SuperView == app?.Current)
         {
-            maxDimension = Application.Screen.Width;
-            superView = Application.Current;
+            maxDimension = app?.Screen.Width ?? 0;
+            superView = app?.Current;
         }
         else
         {
@@ -1187,9 +1190,9 @@ public partial class View // Layout APIs
         var menuVisible = false;
         var statusVisible = false;
 
-        if (viewToMove?.SuperView is null || viewToMove == Application.Current || viewToMove?.SuperView == Application.Current)
+        if (viewToMove?.SuperView is null || viewToMove == app?.Current || viewToMove?.SuperView == app?.Current)
         {
-            menuVisible = Application.Current?.MenuBar?.Visible == true;
+            menuVisible = app?.Current?.MenuBar?.Visible == true;
         }
         else
         {
@@ -1206,7 +1209,7 @@ public partial class View // Layout APIs
             }
         }
 
-        if (viewToMove?.SuperView is null || viewToMove == Application.Current || viewToMove?.SuperView == Application.Current)
+        if (viewToMove?.SuperView is null || viewToMove == app?.Current || viewToMove?.SuperView == app?.Current)
         {
             maxDimension = menuVisible ? 1 : 0;
         }
@@ -1217,9 +1220,16 @@ public partial class View // Layout APIs
 
         ny = Math.Max (targetY, maxDimension);
 
-        if (viewToMove?.SuperView is null || viewToMove == Application.Current || viewToMove?.SuperView == Application.Current)
+        if (viewToMove?.SuperView is null || viewToMove == app?.Current || viewToMove?.SuperView == app?.Current)
         {
-            maxDimension = statusVisible ? Application.Screen.Height - 1 : Application.Screen.Height;
+            if (app is { })
+            {
+                maxDimension = statusVisible ? app.Screen.Height - 1 : app.Screen.Height;
+            }
+            else
+            {
+                maxDimension = 0;
+            }
         }
         else
         {
@@ -1266,10 +1276,10 @@ public partial class View // Layout APIs
     ///     <see cref="ViewportSettingsFlags.TransparentMouse"/>
     ///     flags set in their ViewportSettings.
     /// </param>
-    public static List<View?> GetViewsUnderLocation (in Point screenLocation, ViewportSettingsFlags excludeViewportSettingsFlags)
+    public List<View?> GetViewsUnderLocation (in Point screenLocation, ViewportSettingsFlags excludeViewportSettingsFlags)
     {
         // PopoverHost - If visible, start with it instead of Top
-        if (Application.Popover?.GetActivePopover () is View { Visible: true } visiblePopover)
+        if (App?.Popover?.GetActivePopover () is View { Visible: true } visiblePopover)
         {
             // BUGBUG: We do not traverse all visible toplevels if there's an active popover. This may be a bug.
             List<View?> result = [];
@@ -1285,9 +1295,9 @@ public partial class View // Layout APIs
         var checkedTop = false;
 
         // Traverse all visible toplevels, topmost first (reverse stack order)
-        if (Application.SessionStack.Count > 0)
+        if (App?.SessionStack.Count > 0)
         {
-            foreach (Toplevel toplevel in Application.SessionStack)
+            foreach (Toplevel toplevel in App.SessionStack)
             {
                 if (toplevel.Visible && toplevel.Contains (screenLocation))
                 {
@@ -1300,7 +1310,7 @@ public partial class View // Layout APIs
                     }
                 }
 
-                if (toplevel == Application.Current)
+                if (toplevel == App.Current)
                 {
                     checkedTop = true;
                 }
@@ -1308,7 +1318,7 @@ public partial class View // Layout APIs
         }
 
         // Fallback: If TopLevels is empty or Top is not in TopLevels, check Top directly (for test compatibility)
-        if (!checkedTop && Application.Current is { Visible: true } top)
+        if (!checkedTop && App?.Current is { Visible: true } top)
         {
             // For root toplevels, allow hit-testing even if location is outside bounds (for drag/move)
             List<View?> result = GetViewsUnderLocation (top, screenLocation, excludeViewportSettingsFlags);

+ 9 - 9
Terminal.Gui/ViewBase/View.Mouse.cs

@@ -15,7 +15,7 @@ public partial class View // Mouse APIs
 
     private void SetupMouse ()
     {
-        MouseHeldDown = new MouseHeldDown (this, Application.TimedEvents,Application.Mouse);
+        MouseHeldDown = new MouseHeldDown (this, App?.TimedEvents, App?.Mouse);
         MouseBindings = new ();
 
         // TODO: Should the default really work with any button or just button1?
@@ -53,7 +53,7 @@ public partial class View // Mouse APIs
     #region MouseEnterLeave
 
     /// <summary>
-    ///     INTERNAL Called by <see cref="Application.RaiseMouseEvent"/> when the mouse moves over the View's
+    ///     INTERNAL Called by <see cref="IMouse.RaiseMouseEvent"/> when the mouse moves over the View's
     ///     <see cref="Frame"/>.
     ///     <see cref="MouseLeave"/> will
     ///     be raised when the mouse is no longer over the <see cref="Frame"/>. If another View occludes this View, the
@@ -150,7 +150,7 @@ public partial class View // Mouse APIs
     public event EventHandler<CancelEventArgs>? MouseEnter;
 
     /// <summary>
-    ///     INTERNAL Called by <see cref="Application.RaiseMouseEvent"/> when the mouse leaves <see cref="Frame"/>, or is
+    ///     INTERNAL Called by <see cref="IMouse.RaiseMouseEvent"/> when the mouse leaves <see cref="Frame"/>, or is
     ///     occluded
     ///     by another non-SubView.
     /// </summary>
@@ -227,7 +227,7 @@ public partial class View // Mouse APIs
     public bool WantMousePositionReports { get; set; }
 
     /// <summary>
-    ///     Processes a new <see cref="MouseEvent"/>. This method is called by <see cref="Application.RaiseMouseEvent"/> when a
+    ///     Processes a new <see cref="MouseEvent"/>. This method is called by <see cref="IMouse.RaiseMouseEvent"/> when a
     ///     mouse
     ///     event occurs.
     /// </summary>
@@ -374,7 +374,7 @@ public partial class View // Mouse APIs
 
         if (mouseEvent.IsReleased)
         {
-            if (Application.Mouse.MouseGrabView == this)
+            if (App?.Mouse.MouseGrabView == this)
             {
                 //Logging.Debug ($"{Id} - {MouseState}");
                 MouseState &= ~MouseState.Pressed;
@@ -406,9 +406,9 @@ public partial class View // Mouse APIs
         if (mouseEvent.IsPressed)
         {
             // The first time we get pressed event, grab the mouse and set focus
-            if (Application.Mouse.MouseGrabView != this)
+            if (App?.Mouse.MouseGrabView != this)
             {
-                Application.Mouse.GrabMouse (this);
+                App?.Mouse.GrabMouse (this);
 
                 if (!HasFocus && CanFocus)
                 {
@@ -540,10 +540,10 @@ public partial class View // Mouse APIs
     {
         mouseEvent.Handled = false;
 
-        if (Application.Mouse.MouseGrabView == this && mouseEvent.IsSingleClicked)
+        if (App?.Mouse.MouseGrabView == this && mouseEvent.IsSingleClicked)
         {
             // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
 
             // TODO: Prove we need to unset MouseState.Pressed and MouseState.PressedOutside here
             // TODO: There may be perf gains if we don't unset these flags here

+ 13 - 4
Terminal.Gui/ViewBase/View.cs

@@ -112,8 +112,14 @@ public partial class View : IDisposable, ISupportInitializeNotification
 
     /// <summary>
     ///     Gets the <see cref="IApplication"/> instance this view is running in. If this view is at the top of the view
-    ///     hierarchy, returns <see langword="null"/>
+    ///     hierarchy, returns <see langword="null"/>.
     /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If not explicitly set on an instance, this property will retrieve the value from the view at the top
+    ///         of the View hierarchy (the top-most SuperView).
+    ///     </para>
+    /// </remarks>
     public IApplication? App
     {
         get => GetApp ();
@@ -124,8 +130,11 @@ public partial class View : IDisposable, ISupportInitializeNotification
     ///     Gets the <see cref="IApplication"/> instance this view is running in. Used internally to allow overrides by
     ///     <see cref="Adornment"/>.
     /// </summary>
-    /// <returns>If this view is at the top of the view hierarchy, returns <see langword="null"/>.</returns>
-    protected virtual IApplication? GetApp () => _app ?? SuperView?.App;
+    /// <returns>
+    ///     If this view is at the top of the view hierarchy, and <see cref="App"/> was not explicitly set,
+    ///     returns <see langword="null"/>.
+    /// </returns>
+    protected virtual IApplication? GetApp () => _app ?? SuperView?.App ?? null;
 
     private IDriver? _driver;
 
@@ -145,7 +154,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
     ///     <see cref="Adornment"/>.
     /// </summary>
     /// <returns>If this view is at the top of the view hierarchy, returns <see langword="null"/>.</returns>
-    protected virtual IDriver? GetDriver () => _driver ?? App?.Driver ?? SuperView?.Driver ?? Application.Driver;
+    protected virtual IDriver? GetDriver () => _driver ?? App?.Driver ?? SuperView?.Driver ?? ApplicationImpl.Instance.Driver;
 
     /// <summary>
     ///     Gets the screen buffer contents. This is a convenience property for Views that need direct access to the

+ 17 - 17
Terminal.Gui/Views/Autocomplete/AppendAutocomplete.cs

@@ -9,12 +9,12 @@ namespace Terminal.Gui.Views;
 public class AppendAutocomplete : AutocompleteBase
 {
     private bool _suspendSuggestions;
-    private TextField textField;
+    private TextField _textField;
 
     /// <summary>Creates a new instance of the <see cref="AppendAutocomplete"/> class.</summary>
     public AppendAutocomplete (TextField textField)
     {
-        this.textField = textField;
+        _textField = textField;
         base.SelectionKey = KeyCode.Tab;
 
         Scheme = new Scheme
@@ -36,15 +36,15 @@ public class AppendAutocomplete : AutocompleteBase
     /// <inheritdoc/>
     public override View HostControl
     {
-        get => textField;
-        set => textField = (TextField)value;
+        get => _textField;
+        set => _textField = (TextField)value;
     }
 
     /// <inheritdoc/>
     public override void ClearSuggestions ()
     {
         base.ClearSuggestions ();
-        textField.SetNeedsDraw ();
+        _textField.SetNeedsDraw ();
     }
 
     /// <inheritdoc/>
@@ -108,19 +108,19 @@ public class AppendAutocomplete : AutocompleteBase
         }
 
         // draw it like it's selected, even though it's not
-        textField.SetAttribute (
+        _textField.SetAttribute (
                                new Attribute (
                                               Scheme.Normal.Foreground,
-                                              textField.GetAttributeForRole(VisualRole.Focus).Background,
+                                              _textField.GetAttributeForRole(VisualRole.Focus).Background,
                                               Scheme.Normal.Style
                                              )
                               );
-        textField.Move (textField.Text.Length, 0);
+        _textField.Move (_textField.Text.Length, 0);
 
         Suggestion suggestion = Suggestions.ElementAt (SelectedIdx);
         string fragment = suggestion.Replacement.Substring (suggestion.Remove);
 
-        int spaceAvailable = textField.Viewport.Width - textField.Text.GetColumns ();
+        int spaceAvailable = _textField.Viewport.Width - _textField.Text.GetColumns ();
         int spaceRequired = fragment.EnumerateRunes ().Sum (c => c.GetColumns ());
 
         if (spaceAvailable < spaceRequired)
@@ -131,7 +131,7 @@ public class AppendAutocomplete : AutocompleteBase
                                   );
         }
 
-        Application.Driver?.AddStr (fragment);
+        _textField.Driver?.AddStr (fragment);
     }
 
     /// <summary>
@@ -144,12 +144,12 @@ public class AppendAutocomplete : AutocompleteBase
         if (MakingSuggestion ())
         {
             Suggestion insert = Suggestions.ElementAt (SelectedIdx);
-            string newText = textField.Text;
+            string newText = _textField.Text;
             newText = newText.Substring (0, newText.Length - insert.Remove);
             newText += insert.Replacement;
-            textField.Text = newText;
+            _textField.Text = newText;
 
-            textField.MoveEnd ();
+            _textField.MoveEnd ();
 
             ClearSuggestions ();
 
@@ -168,8 +168,8 @@ public class AppendAutocomplete : AutocompleteBase
             newText += Path.DirectorySeparatorChar;
         }
 
-        textField.Text = newText;
-        textField.MoveEnd ();
+        _textField.Text = newText;
+        _textField.MoveEnd ();
     }
 
     private bool CycleSuggestion (int direction)
@@ -186,7 +186,7 @@ public class AppendAutocomplete : AutocompleteBase
             SelectedIdx = Suggestions.Count () - 1;
         }
 
-        textField.SetNeedsDraw ();
+        _textField.SetNeedsDraw ();
 
         return true;
     }
@@ -196,5 +196,5 @@ public class AppendAutocomplete : AutocompleteBase
     ///     to see auto-complete (i.e. focused and cursor in right place).
     /// </summary>
     /// <returns></returns>
-    private bool MakingSuggestion () { return Suggestions.Any () && SelectedIdx != -1 && textField.HasFocus && textField.CursorIsAtEnd (); }
+    private bool MakingSuggestion () { return Suggestions.Any () && SelectedIdx != -1 && _textField.HasFocus && _textField.CursorIsAtEnd (); }
 }

+ 3 - 3
Terminal.Gui/Views/Autocomplete/PopupAutocomplete.cs

@@ -124,7 +124,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase
             {
                 Visible = true;
                 HostControl?.SetNeedsDraw ();
-                Application.Mouse.UngrabMouse ();
+                HostControl?.App?.Mouse.UngrabMouse ();
 
                 return false;
             }
@@ -136,7 +136,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase
                 _closed = false;
             }
 
-            HostControl?.SetNeedsDraw ();
+            HostControl.SetNeedsDraw ();
 
             return false;
         }
@@ -405,7 +405,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase
 
             string text = TextFormatter.ClipOrPad (toRender [i].Title, width);
 
-            Application.Driver?.AddStr (text);
+            _popup.App?.Driver?.AddStr (text);
         }
     }
 

+ 8 - 7
Terminal.Gui/Views/Bar.cs

@@ -31,13 +31,14 @@ public class Bar : View, IOrientation, IDesignable
         // Initialized += Bar_Initialized;
         MouseEvent += OnMouseEvent;
 
+        if (shortcuts is null)
+        {
+            return;
+        }
 
-        if (shortcuts is { })
+        foreach (View shortcut in shortcuts)
         {
-            foreach (View shortcut in shortcuts)
-            {
-                Add (shortcut);
-            }
+            base.Add (shortcut);
         }
     }
 
@@ -105,7 +106,7 @@ public class Bar : View, IOrientation, IDesignable
     public void OnOrientationChanged (Orientation newOrientation)
     {
         // BUGBUG: this should not be SuperView.GetContentSize
-        LayoutBarItems (SuperView?.GetContentSize () ?? Application.Screen.Size);
+        LayoutBarItems (SuperView?.GetContentSize () ?? App?.Screen.Size ?? Size.Empty);
     }
     #endregion
 
@@ -243,7 +244,7 @@ public class Bar : View, IOrientation, IDesignable
                             barItem.X = 0;
                             scBarItem.MinimumKeyTextSize = minKeyWidth;
                             scBarItem.Width = scBarItem.GetWidthDimAuto ();
-                            barItem.Layout (Application.Screen.Size);
+                            barItem.Layout (App?.Screen.Size ?? Size.Empty);
                             maxBarItemWidth = Math.Max (maxBarItemWidth, barItem.Frame.Width);
                         }
 

+ 3 - 3
Terminal.Gui/Views/CharMap/CharMap.cs

@@ -383,12 +383,12 @@ public class CharMap : View, IDesignable
                                    try
                                    {
                                        decResponse = await client.GetCodepointDec (SelectedCodePoint).ConfigureAwait (false);
-                                       Application.Invoke (() => waitIndicator.RequestStop ());
+                                       Application.Invoke ((_) => waitIndicator.RequestStop ());
                                    }
                                    catch (HttpRequestException e)
                                    {
                                        getCodePointError = errorLabel.Text = e.Message;
-                                       Application.Invoke (() => waitIndicator.RequestStop ());
+                                       Application.Invoke ((_) => waitIndicator.RequestStop ());
                                    }
                                };
         Application.Run (waitIndicator);
@@ -971,7 +971,7 @@ public class CharMap : View, IDesignable
 
         // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
         // and the context menu is disposed when it is closed.
-        Application.Popover?.Register (contextMenu);
+        App!.Popover?.Register (contextMenu);
 
         contextMenu?.MakeVisible (ViewportToScreen (GetCursor (SelectedCodePoint)));
 

+ 4 - 4
Terminal.Gui/Views/FileDialogs/FileDialog.cs

@@ -1232,7 +1232,7 @@ public class FileDialog : Dialog, IDesignable
 
         // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
         // and the context menu is disposed when it is closed.
-        Application.Popover?.Register (contextMenu);
+        App!.Popover?.Register (contextMenu);
 
         contextMenu?.MakeVisible (e.ScreenPosition);
     }
@@ -1260,7 +1260,7 @@ public class FileDialog : Dialog, IDesignable
 
         // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
         // and the context menu is disposed when it is closed.
-        Application.Popover?.Register (contextMenu);
+        App!.Popover?.Register (contextMenu);
 
         contextMenu?.MakeVisible (e.ScreenPosition);
     }
@@ -1611,7 +1611,7 @@ public class FileDialog : Dialog, IDesignable
                     UpdateChildrenToFound ();
                 }
 
-                Application.Invoke (() => { Parent._spinnerView.Visible = false; });
+                Application.Invoke ((_) => { Parent._spinnerView.Visible = false; });
             }
         }
 
@@ -1623,7 +1623,7 @@ public class FileDialog : Dialog, IDesignable
             }
 
             Application.Invoke (
-                                () =>
+                                (_) =>
                                 {
                                     Parent._tbPath.Autocomplete.GenerateSuggestions (
                                                                                      new AutocompleteFilepathContext (

+ 4 - 0
Terminal.Gui/Views/Menu/MenuBarItemv2.cs

@@ -1,5 +1,7 @@
 
 
+using System.Diagnostics;
+
 namespace Terminal.Gui.Views;
 
 /// <summary>
@@ -112,6 +114,8 @@ public class MenuBarItemv2 : MenuItemv2
 
             if (_popoverMenu is { })
             {
+                _popoverMenu.App = App;
+
                 PopoverMenuOpen = _popoverMenu.Visible;
                 _popoverMenu.VisibleChanged += OnPopoverVisibleChanged;
                 _popoverMenu.Accepted += OnPopoverMenuOnAccepted;

+ 25 - 16
Terminal.Gui/Views/Menu/MenuBarv2.cs

@@ -321,7 +321,7 @@ public class MenuBarv2 : Menuv2, IDesignable
         // TODO: This needs to be done whenever a menuitem in any MenuBarItem changes
         foreach (MenuBarItemv2? mbi in SubViews.Select (s => s as MenuBarItemv2))
         {
-            Application.Popover?.Register (mbi?.PopoverMenu);
+            App?.Popover?.Register (mbi?.PopoverMenu);
         }
     }
 
@@ -396,11 +396,11 @@ public class MenuBarv2 : Menuv2, IDesignable
         }
 
         // If the active Application Popover is part of this MenuBar, hide it.
-        if (Application.Popover?.GetActivePopover () is PopoverMenu popoverMenu
+        if (App?.Popover?.GetActivePopover () is PopoverMenu popoverMenu
             && popoverMenu.Root?.SuperMenuItem?.SuperView == this)
         {
-            // Logging.Debug ($"{Title} - Calling Application.Popover?.Hide ({popoverMenu.Title})");
-            Application.Popover.Hide (popoverMenu);
+            // Logging.Debug ($"{Title} - Calling App?.Popover?.Hide ({popoverMenu.Title})");
+            App?.Popover.Hide (popoverMenu);
         }
 
         if (menuBarItem is null)
@@ -420,7 +420,11 @@ public class MenuBarv2 : Menuv2, IDesignable
         }
 
         // Logging.Debug ($"{Title} - \"{menuBarItem.PopoverMenu?.Title}\".MakeVisible");
-        menuBarItem.PopoverMenu?.MakeVisible (new Point (menuBarItem.FrameToScreen ().X, menuBarItem.FrameToScreen ().Bottom));
+        if (menuBarItem.PopoverMenu is { })
+        {
+            menuBarItem.PopoverMenu.App ??= App;
+            menuBarItem.PopoverMenu.MakeVisible (new Point (menuBarItem.FrameToScreen ().X, menuBarItem.FrameToScreen ().Bottom));
+        }
 
         menuBarItem.Accepting += OnMenuItemAccepted;
 
@@ -501,11 +505,16 @@ public class MenuBarv2 : Menuv2, IDesignable
     }
 
     /// <inheritdoc/>
-    public bool EnableForDesign<TContext> (ref TContext context) where TContext : notnull
+    public bool EnableForDesign<TContext> (ref TContext targetView) where TContext : notnull
     {
         // Note: This menu is used by unit tests. If you modify it, you'll likely have to update
         // unit tests.
 
+        if (targetView is View target)
+        {
+            App ??= target.App;
+        }
+
         Id = "DemoBar";
 
         var bordersCb = new CheckBox
@@ -552,10 +561,10 @@ public class MenuBarv2 : Menuv2, IDesignable
              new MenuBarItemv2 (
                                 "_File",
                                 [
-                                    new MenuItemv2 (context as View, Command.New),
-                                    new MenuItemv2 (context as View, Command.Open),
-                                    new MenuItemv2 (context as View, Command.Save),
-                                    new MenuItemv2 (context as View, Command.SaveAs),
+                                    new MenuItemv2 (targetView as View, Command.New),
+                                    new MenuItemv2 (targetView as View, Command.Open),
+                                    new MenuItemv2 (targetView as View, Command.Save),
+                                    new MenuItemv2 (targetView as View, Command.SaveAs),
                                     new Line (),
                                     new MenuItemv2
                                     {
@@ -576,7 +585,7 @@ public class MenuBarv2 : Menuv2, IDesignable
                                                                Key = Key.W.WithCtrl,
                                                                CommandView = enableOverwriteCb,
                                                                Command = Command.EnableOverwrite,
-                                                               TargetView = context as View
+                                                               TargetView = targetView as View
                                                            },
                                                            new ()
                                                            {
@@ -622,7 +631,7 @@ public class MenuBarv2 : Menuv2, IDesignable
                                     new Line (),
                                     new MenuItemv2
                                     {
-                                        TargetView = context as View,
+                                        TargetView = targetView as View,
                                         Key = Application.QuitKey,
                                         Command = Command.Quit
                                     }
@@ -634,11 +643,11 @@ public class MenuBarv2 : Menuv2, IDesignable
              new MenuBarItemv2 (
                                 "_Edit",
                                 [
-                                    new MenuItemv2 (context as View, Command.Cut),
-                                    new MenuItemv2 (context as View, Command.Copy),
-                                    new MenuItemv2 (context as View, Command.Paste),
+                                    new MenuItemv2 (targetView as View, Command.Cut),
+                                    new MenuItemv2 (targetView as View, Command.Copy),
+                                    new MenuItemv2 (targetView as View, Command.Paste),
                                     new Line (),
-                                    new MenuItemv2 (context as View, Command.SelectAll),
+                                    new MenuItemv2 (targetView as View, Command.SelectAll),
                                     new Line (),
                                     new MenuItemv2
                                     {

+ 2 - 1
Terminal.Gui/Views/Menu/MenuItemv2.cs

@@ -135,7 +135,7 @@ public class MenuItemv2 : Shortcut
             {
                 // Is this an Application-bound command?
                 // Logging.Debug ($"{Title} - Application.InvokeCommandsBoundToKey ({Key})...");
-                ret = Application.InvokeCommandsBoundToKey (Key);
+                ret = App?.Keyboard.InvokeCommandsBoundToKey (Key);
             }
         }
 
@@ -185,6 +185,7 @@ public class MenuItemv2 : Shortcut
 
             if (_subMenu is { })
             {
+                SubMenu!.App ??= App;
                 SubMenu!.Visible = false;
                 // TODO: This is a temporary hack - add a flag or something instead
                 KeyView.Text = $"{Glyphs.RightArrow}";

+ 20 - 12
Terminal.Gui/Views/Menu/PopoverMenu.cs

@@ -9,7 +9,7 @@ namespace Terminal.Gui.Views;
 /// </summary>
 /// <remarks>
 ///     <para>
-///         To use as a context menu, register the popover menu with <see cref="Application.Popover"/> and call
+///         To use as a context menu, register the popover menu with <see cref="IApplication.Popover"/> and call
 ///         <see cref="MakeVisible"/>.
 ///     </para>
 /// </remarks>
@@ -176,7 +176,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
         UpdateKeyBindings ();
         SetPosition (idealScreenPosition);
-        Application.Popover?.Show (this);
+        App!.Popover?.Show (this);
     }
 
     /// <summary>
@@ -188,7 +188,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     /// <param name="idealScreenPosition">If <see langword="null"/>, the current mouse position will be used.</param>
     public void SetPosition (Point? idealScreenPosition = null)
     {
-        idealScreenPosition ??= Application.GetLastMousePosition ();
+        idealScreenPosition ??= App?.Mouse.GetLastMousePosition ();
 
         if (idealScreenPosition is null || Root is null)
         {
@@ -199,6 +199,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
         if (!Root.IsInitialized)
         {
+            Root.App ??= App;
             Root.BeginInit ();
             Root.EndInit ();
             Root.Layout ();
@@ -223,7 +224,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
         else
         {
             HideAndRemoveSubMenu (_root);
-            Application.Popover?.Hide (this);
+            App?.Popover?.Hide (this);
         }
     }
 
@@ -246,6 +247,11 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
             _root = value;
 
+            if (_root is { })
+            {
+                _root.App = App;
+            }
+
             // TODO: This needs to be done whenever any MenuItem in the menu tree changes to support dynamic menus
             // TODO: And it needs to clear the old bindings first
             UpdateKeyBindings ();
@@ -255,6 +261,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
             foreach (Menuv2 menu in allMenus)
             {
+                menu.App = App;
                 menu.Visible = false;
                 menu.Accepting += MenuOnAccepting;
                 menu.Accepted += MenuAccepted;
@@ -279,7 +286,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
             else
             {
                 // No TargetView implies Application HotKey
-                key = Application.KeyBindings.GetFirstFromCommands (menuItem.Command);
+                key = App?.Keyboard.KeyBindings.GetFirstFromCommands (menuItem.Command);
             }
 
             if (key is not { IsValid: true })
@@ -439,6 +446,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
             if (!menu!.IsInitialized)
             {
+                menu.App ??= App;
                 menu.BeginInit ();
                 menu.EndInit ();
             }
@@ -626,27 +634,27 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
-    public bool EnableForDesign<TContext> (ref TContext context) where TContext : notnull
+    public bool EnableForDesign<TContext> (ref TContext targetView) where TContext : notnull
     {
         // Note: This menu is used by unit tests. If you modify it, you'll likely have to update
         // unit tests.
 
         Root = new (
                     [
-                        new MenuItemv2 (context as View, Command.Cut),
-                        new MenuItemv2 (context as View, Command.Copy),
-                        new MenuItemv2 (context as View, Command.Paste),
+                        new MenuItemv2 (targetView as View, Command.Cut),
+                        new MenuItemv2 (targetView as View, Command.Copy),
+                        new MenuItemv2 (targetView as View, Command.Paste),
                         new Line (),
-                        new MenuItemv2 (context as View, Command.SelectAll),
+                        new MenuItemv2 (targetView as View, Command.SelectAll),
                         new Line (),
-                        new MenuItemv2 (context as View, Command.Quit)
+                        new MenuItemv2 (targetView as View, Command.Quit)
                     ])
         {
             Title = "Popover Demo Root"
         };
 
         // NOTE: This is a workaround for the fact that the PopoverMenu is not visible in the designer
-        // NOTE: without being activated via Application.Popover. But we want it to be visible.
+        // NOTE: without being activated via App?.Popover. But we want it to be visible.
         // NOTE: If you use PopoverView.EnableForDesign for real Popover scenarios, change back to false
         // NOTE: after calling EnableForDesign.
         //Visible = true;

+ 2 - 2
Terminal.Gui/Views/Menuv1/MenuBar.cs

@@ -1679,9 +1679,9 @@ public class MenuBar : View, IDesignable
 
 
     /// <inheritdoc />
-    public bool EnableForDesign<TContext> (ref TContext context) where TContext : notnull
+    public bool EnableForDesign<TContext> (ref TContext targetView) where TContext : notnull
     {
-        if (context is not Func<string, bool> actionFn)
+        if (targetView is not Func<string, bool> actionFn)
         {
             actionFn = (_) => true;
         }

+ 21 - 8
Terminal.Gui/Views/Shortcut.cs

@@ -1,5 +1,6 @@
 
 using System.ComponentModel;
+using System.Diagnostics;
 
 namespace Terminal.Gui.Views;
 
@@ -101,6 +102,15 @@ public class Shortcut : View, IOrientation, IDesignable
         ShowHide ();
     }
 
+    /// <inheritdoc />
+    public override void EndInit ()
+    {
+        base.EndInit ();
+        App ??= SuperView?.App;
+        Debug.Assert (App is { });
+        UpdateKeyBindings (Key.Empty);
+    }
+
     // Helper to set Width consistently
     internal Dim GetWidthDimAuto ()
     {
@@ -168,14 +178,15 @@ public class Shortcut : View, IOrientation, IDesignable
     private void ForceCalculateNaturalWidth ()
     {
         // Get the natural size of each subview
-        CommandView.SetRelativeLayout (Application.Screen.Size);
-        HelpView.SetRelativeLayout (Application.Screen.Size);
-        KeyView.SetRelativeLayout (Application.Screen.Size);
+        Size screenSize = App?.Screen.Size ?? new (2048, 2048);
+        CommandView.SetRelativeLayout (screenSize);
+        HelpView.SetRelativeLayout (screenSize);
+        KeyView.SetRelativeLayout (screenSize);
 
         _minimumNaturalWidth = PosAlign.CalculateMinDimension (0, SubViews, Dimension.Width);
 
         // Reset our relative layout
-        SetRelativeLayout (SuperView?.GetContentSize () ?? Application.Screen.Size);
+        SetRelativeLayout (SuperView?.GetContentSize () ?? screenSize);
     }
 
     // TODO: Enable setting of the margin thickness
@@ -615,6 +626,8 @@ public class Shortcut : View, IOrientation, IDesignable
         get => _bindKeyToApplication;
         set
         {
+            App ??= SuperView?.App;
+
             if (value == _bindKeyToApplication)
             {
                 return;
@@ -622,7 +635,7 @@ public class Shortcut : View, IOrientation, IDesignable
 
             if (_bindKeyToApplication)
             {
-                Application.KeyBindings.Remove (Key);
+                App?.Keyboard.KeyBindings.Remove (Key);
             }
             else
             {
@@ -709,11 +722,11 @@ public class Shortcut : View, IOrientation, IDesignable
         {
             if (oldKey != Key.Empty)
             {
-                Application.KeyBindings.Remove (oldKey);
+                App?.Keyboard.KeyBindings.Remove (oldKey);
             }
 
-            Application.KeyBindings.Remove (Key);
-            Application.KeyBindings.Add (Key, this, Command.HotKey);
+            App?.Keyboard.KeyBindings.Remove (Key);
+            App?.Keyboard.KeyBindings.Add (Key, this, Command.HotKey);
         }
         else
         {

+ 2 - 2
Terminal.Gui/Views/Slider/Slider.cs

@@ -1312,7 +1312,7 @@ public class Slider<T> : View, IOrientation
             {
                 _dragPosition = mouseEvent.Position;
                 _moveRenderPosition = ClampMovePosition ((Point)_dragPosition);
-                Application.Mouse.GrabMouse (this);
+                App?.Mouse.GrabMouse (this);
             }
 
             SetNeedsDraw ();
@@ -1358,7 +1358,7 @@ public class Slider<T> : View, IOrientation
             || mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
         {
             // End Drag
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
             _dragPosition = null;
             _moveRenderPosition = null;
 

+ 5 - 5
Terminal.Gui/Views/SpinnerView/SpinnerView.cs

@@ -114,7 +114,7 @@ public class SpinnerView : View, IDesignable
     ///     Advances the animation frame and notifies main loop that repainting needs to happen. Repeated calls are
     ///     ignored based on <see cref="SpinDelay"/>.
     /// </summary>
-    /// <remarks>Ensure this method is called on the main UI thread e.g. via <see cref="Application.Invoke"/></remarks>
+    /// <remarks>Ensure this method is called on the main UI thread e.g. via <see cref="IApplication.Invoke(Action)"/></remarks>
     public void AdvanceAnimation (bool setNeedsDraw = true)
     {
         if (DateTime.Now - _lastRender > TimeSpan.FromMilliseconds (SpinDelay))
@@ -202,16 +202,16 @@ public class SpinnerView : View, IDesignable
     private void AddAutoSpinTimeout ()
     {
         // Only add timeout if we are initialized and not already spinning
-        if (_timeout is { } || !Application.Initialized)
+        if (App is { } && (_timeout is { } || !App.Initialized))
         {
             return;
         }
 
-        _timeout = Application.AddTimeout (
+        _timeout = App?.AddTimeout (
                                            TimeSpan.FromMilliseconds (SpinDelay),
                                            () =>
                                            {
-                                               Application.Invoke (() => AdvanceAnimation ());
+                                               App.Invoke ((_) => AdvanceAnimation ());
 
                                                return true;
                                            }
@@ -266,7 +266,7 @@ public class SpinnerView : View, IDesignable
     {
         if (_timeout is { })
         {
-            Application.RemoveTimeout (_timeout);
+            App?.RemoveTimeout (_timeout);
             _timeout = null;
         }
     }

+ 9 - 7
Terminal.Gui/Views/StatusBar.cs

@@ -134,12 +134,14 @@ public class StatusBar : Bar, IDesignable
         button1.Accepting += OnButtonClicked;
         Add (button1);
 
-        shortcut.Accepting += (s, e) =>
-                           {
-                               button1.Visible = !button1.Visible;
-                               button1.Enabled = button1.Visible;
-                               e.Handled = false;
-                           };
+#pragma warning disable TGUI001
+        shortcut.Accepting += (_, e) =>
+                              {
+                                  button1.Visible = !button1.Visible;
+                                  button1.Enabled = button1.Visible;
+                                  e.Handled = false;
+                              };
+#pragma warning restore TGUI001
 
         Add (new Label
         {
@@ -152,7 +154,7 @@ public class StatusBar : Bar, IDesignable
         {
             Text = "Or me!",
         };
-        button2.Accepting += (s, e) => Application.RequestStop ();
+        button2.Accepting += (s, e) => App?.RequestStop ();
 
         Add (button2);
 

+ 10 - 16
Terminal.Gui/Views/TextInput/TextField.cs

@@ -419,9 +419,6 @@ public class TextField : View, IDesignable
         KeyBindings.Remove (Key.Space);
 
         _currentCulture = Thread.CurrentThread.CurrentUICulture;
-
-        CreateContextMenu ();
-        KeyBindings.Add (ContextMenu.Key, Command.Context);
     }
 
     /// <summary>
@@ -865,16 +862,16 @@ public class TextField : View, IDesignable
             _isButtonReleased = false;
             PrepareSelection (x);
 
-            if (Application.Mouse.MouseGrabView is null)
+            if (App?.Mouse.MouseGrabView is null)
             {
-                Application.Mouse.GrabMouse (this);
+                App?.Mouse.GrabMouse (this);
             }
         }
         else if (ev.Flags == MouseFlags.Button1Released)
         {
             _isButtonReleased = true;
             _isButtonPressed = false;
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
         }
         else if (ev.Flags == MouseFlags.Button1DoubleClicked)
         {
@@ -1017,13 +1014,10 @@ public class TextField : View, IDesignable
     /// <inheritdoc/>
     protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View view)
     {
-        if (Application.Mouse.MouseGrabView is { } && Application.Mouse.MouseGrabView == this)
+        if (App?.Mouse.MouseGrabView is { } && App?.Mouse.MouseGrabView == this)
         {
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
         }
-
-        //if (SelectedLength != 0 && !(Application.Mouse.MouseGrabView is MenuBar))
-        //	ClearAllSelection ();
     }
 
     /// <inheritdoc/>
@@ -1255,6 +1249,7 @@ public class TextField : View, IDesignable
         menu.KeyChanged += ContextMenu_KeyChanged;
 
         ContextMenu = menu;
+        App?.Popover.Register (ContextMenu);
     }
 
     private void ContextMenu_KeyChanged (object sender, KeyChangedEventArgs e) { KeyBindings.Replace (e.OldKey.KeyCode, e.NewKey.KeyCode); }
@@ -1768,11 +1763,6 @@ public class TextField : View, IDesignable
         if (!Equals (_currentCulture, Thread.CurrentThread.CurrentUICulture))
         {
             _currentCulture = Thread.CurrentThread.CurrentUICulture;
-
-            if (ContextMenu is { })
-            {
-                CreateContextMenu ();
-            }
         }
 
         if (keyboard)
@@ -1815,6 +1805,10 @@ public class TextField : View, IDesignable
             Autocomplete.HostControl = this;
             Autocomplete.PopupInsideContainer = false;
         }
+
+        CreateContextMenu ();
+        KeyBindings.Add (ContextMenu?.Key, Command.Context);
+
     }
 
     private void DisposeContextMenu ()

+ 14 - 11
Terminal.Gui/Views/TextInput/TextView.cs

@@ -113,7 +113,7 @@ public class TextView : View, IDesignable
         Used = true;
 
         // By default, disable hotkeys (in case someone sets Title)
-        HotKeySpecifier = new ('\xffff');
+        base.HotKeySpecifier = new ('\xffff');
 
         _model.LinesLoaded += Model_LinesLoaded!;
         _historyText.ChangeText += HistoryText_ChangeText!;
@@ -626,9 +626,6 @@ public class TextView : View, IDesignable
 #endif
 
         _currentCulture = Thread.CurrentThread.CurrentUICulture;
-
-        ContextMenu = CreateContextMenu ();
-        KeyBindings.Add (ContextMenu.Key, Command.Context);
     }
 
     // BUGBUG: AllowsReturn is mis-named. It should be EnterKeyAccepts.
@@ -1673,15 +1670,15 @@ public class TextView : View, IDesignable
             _lastWasKill = false;
             _columnTrack = CurrentColumn;
 
-            if (Application.Mouse.MouseGrabView is null)
+            if (App?.Mouse.MouseGrabView is null)
             {
-                Application.Mouse.GrabMouse (this);
+                App?.Mouse.GrabMouse (this);
             }
         }
         else if (ev.Flags.HasFlag (MouseFlags.Button1Released))
         {
             _isButtonReleased = true;
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
         }
         else if (ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
         {
@@ -1883,9 +1880,9 @@ public class TextView : View, IDesignable
     /// <inheritdoc/>
     protected override void OnHasFocusChanged (bool newHasFocus, View? previousFocusedView, View? view)
     {
-        if (Application.Mouse.MouseGrabView is { } && Application.Mouse.MouseGrabView == this)
+        if (App?.Mouse.MouseGrabView is { } && App?.Mouse.MouseGrabView == this)
         {
-            Application.Mouse.UngrabMouse ();
+            App?.Mouse.UngrabMouse ();
         }
     }
 
@@ -2024,12 +2021,12 @@ public class TextView : View, IDesignable
     {
         ProcessAutocomplete ();
 
-        if (!CanFocus || !Enabled || Application.Driver is null)
+        if (!CanFocus || !Enabled || Driver is null)
         {
             return null;
         }
 
-        if (Application.Mouse.MouseGrabView == this && IsSelecting)
+        if (App?.Mouse.MouseGrabView == this && IsSelecting)
         {
             // BUGBUG: customized rect aren't supported now because the Redraw isn't using the Intersect method.
             //var minRow = Math.Min (Math.Max (Math.Min (selectionStartRow, currentRow) - topRow, 0), Viewport.Height);
@@ -4575,6 +4572,7 @@ public class TextView : View, IDesignable
         {
             mousePosition = ViewportToScreen (new Point (CursorPosition.X, CursorPosition.Y));
         }
+
         ContextMenu?.MakeVisible (mousePosition);
     }
 
@@ -4650,6 +4648,11 @@ public class TextView : View, IDesignable
             Autocomplete.HostControl = this;
         }
 
+
+        ContextMenu = CreateContextMenu ();
+        App?.Popover?.Register (ContextMenu);
+        KeyBindings.Add (ContextMenu.Key, Command.Context);
+
         OnContentsChanged ();
     }
 

+ 2 - 2
Terminal.Gui/Views/Toplevel.cs

@@ -152,7 +152,7 @@ public partial class Toplevel : View
     /// </summary>
     public virtual void RequestStop ()
     {
-        Application.RequestStop (Application.Current);
+        App?.RequestStop (App?.Current);
     }
 
     /// <summary>
@@ -244,7 +244,7 @@ public partial class Toplevel : View
         }
 
         // BUGBUG: The && true is a temp hack
-        if ((superView != top || top?.SuperView is { } || (top != Application.Current && top!.Modal) || (top == Application.Current && top?.SuperView is null))
+        if ((superView != top || top?.SuperView is { } || (top != App?.Current && top!.Modal) || (top == App?.Current && top?.SuperView is null))
             && (top!.Frame.X + top.Frame.Width > maxWidth || ny > top.Frame.Y))
 
         {

+ 3 - 3
Tests/IntegrationTests/FluentTests/FileDialogFluentTests.cs

@@ -191,7 +191,7 @@ public class FileDialogFluentTests
         SaveDialog? sd = null;
         MockFileSystem? fs = null;
         using var c = With.A (() => NewSaveDialog (out sd, out fs, modal: false), 100, 20, d)
-                          .Then (() => sd!.Style.PreserveFilenameOnDirectoryChanges = true)
+                          .Then ((_) => sd!.Style.PreserveFilenameOnDirectoryChanges = true)
                           .ScreenShot ("Save dialog", _out)
                           .AssertTrue (sd!.Canceled)
                           .Focus<TextField> (_ => true)
@@ -230,7 +230,7 @@ public class FileDialogFluentTests
         SaveDialog? sd = null;
         MockFileSystem? fs = null;
         using var c = With.A (() => NewSaveDialog (out sd, out fs, modal: false), 100, 20, d)
-                          .Then (() => sd!.Style.PreserveFilenameOnDirectoryChanges = false)
+                          .Then ((_) => sd!.Style.PreserveFilenameOnDirectoryChanges = false)
                           .ScreenShot ("Save dialog", _out)
                           .AssertTrue (sd!.Canceled)
                           .Focus<TextField> (_ => true)
@@ -267,7 +267,7 @@ public class FileDialogFluentTests
         SaveDialog? sd = null;
         MockFileSystem? fs = null;
         using var c = With.A (() => NewSaveDialog (out sd, out fs, modal: false), 100, 20, d)
-                          .Then (() => sd!.Style.PreserveFilenameOnDirectoryChanges = preserve)
+                          .Then ((_) => sd!.Style.PreserveFilenameOnDirectoryChanges = preserve)
                           .ScreenShot ("Save dialog", _out)
                           .AssertTrue (sd!.Canceled)
                           .Focus<TextField> (_ => true)

+ 14 - 14
Tests/IntegrationTests/FluentTests/GuiTestContextKeyEventTests.cs

@@ -19,7 +19,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
         Assert.True (Application.Current!.Running);
 
         Toplevel top = Application.Current;
-        context.Then (() => Application.RaiseKeyDownEvent (Application.QuitKey));
+        context.Then ((_) => Application.RaiseKeyDownEvent (Application.QuitKey));
         Assert.False (top!.Running);
     }
 
@@ -46,7 +46,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .ResizeConsole (50, 20)
                                            .EnqueueKeyEvent (Key.A);
 
@@ -62,7 +62,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (textField)
                                            .Focus (textField)
-                                           .Then (() => textField.CursorPosition = textField.Text.Length)
+                                           .Then ((_) => textField.CursorPosition = textField.Text.Length)
                                            .EnqueueKeyEvent (Key.Backspace)
                                            .EnqueueKeyEvent (Key.Backspace);
 
@@ -81,14 +81,14 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (textField)
                                            .Add (button)
-                                           .Then (() => textField.SetFocus ())
+                                           .Then ((_) => textField.SetFocus ())
                                            .EnqueueKeyEvent (Key.T.WithShift)
                                            .EnqueueKeyEvent (Key.E)
                                            .EnqueueKeyEvent (Key.S)
                                            .EnqueueKeyEvent (Key.T)
                                            .AssertEqual ("Test", textField.Text)
                                            .EnqueueKeyEvent (Key.Tab)
-                                           .Then (() => Assert.True (button.HasFocus))
+                                           .Then ((_) => Assert.True (button.HasFocus))
                                            .EnqueueKeyEvent (Key.Enter)
                                            .AssertEqual (1, clickedCount);
     }
@@ -110,7 +110,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .EnqueueKeyEvent (Key.A);
 
         Assert.True (keyReceived, "Key was not received by the view");
@@ -128,7 +128,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .EnqueueKeyEvent (Key.F1)
                                            .EnqueueKeyEvent (Key.F5)
                                            .EnqueueKeyEvent (Key.F12);
@@ -150,7 +150,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .EnqueueKeyEvent (Key.A)
                                            .EnqueueKeyEvent (Key.B)
                                            .EnqueueKeyEvent (Key.C);
@@ -171,7 +171,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view1)
                                            .Add (view2)
-                                           .Then (() => view1.SetFocus ())
+                                           .Then ((_) => view1.SetFocus ())
                                            .AssertTrue (view1.HasFocus)
                                            .AssertFalse (view2.HasFocus)
                                            .EnqueueKeyEvent (Key.Tab)
@@ -190,7 +190,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (textField)
-                                           .Then (() => textField.SetFocus ())
+                                           .Then ((_) => textField.SetFocus ())
                                            .EnqueueKeyEvent (Key.D1)
                                            .EnqueueKeyEvent (Key.D2)
                                            .EnqueueKeyEvent (Key.D3)
@@ -210,7 +210,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ());
+                                           .Then ((_) => view.SetFocus ());
 
         // Send 10 keys rapidly
         for (var i = 0; i < 10; i++)
@@ -237,7 +237,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .EnqueueKeyEvent (Key.Enter)
                                            .EnqueueKeyEvent (Key.Tab)
                                            .EnqueueKeyEvent (Key.CursorUp)
@@ -266,7 +266,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (listView)
-                                           .Then (() => listView.SetFocus ())
+                                           .Then ((_) => listView.SetFocus ())
                                            .AssertEqual (0, listView.SelectedItem)
                                            .EnqueueKeyEvent (Key.CursorDown)
                                            .AssertEqual (1, listView.SelectedItem)
@@ -293,7 +293,7 @@ public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)
-                                           .Then (() => view.SetFocus ())
+                                           .Then ((_) => view.SetFocus ())
                                            .EnqueueKeyEvent (Key.A.WithCtrl);
 
         Assert.True (keyReceived);

+ 1 - 1
Tests/IntegrationTests/FluentTests/GuiTestContextMouseEventTests.cs

@@ -152,7 +152,7 @@ public class GuiTestContextMouseEventTests (ITestOutputHelper outputHelper)
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view1)
                                            .Add (view2)
-                                           .Then (() => view1.SetFocus ())
+                                           .Then ((_) => view1.SetFocus ())
                                            .AssertTrue (view1.HasFocus)
                                            .LeftClick (25, 7) // Click on view2
                                            .AssertFalse (view1.HasFocus)

+ 67 - 54
Tests/IntegrationTests/FluentTests/MenuBarv2Tests.cs

@@ -24,7 +24,7 @@ public class MenuBarv2Tests
     public void Initializes_WithNoItems (TestDriver d)
     {
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 // Create a menu bar with no items
                                                 var menuBar = new MenuBarv2 ();
@@ -42,7 +42,7 @@ public class MenuBarv2Tests
         MenuBarItemv2 [] menuItems = [];
 
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 // Create items for the menu bar
                                                 menuItems =
@@ -79,7 +79,7 @@ public class MenuBarv2Tests
     public void AddsItems_WithMenusProperty (TestDriver d)
     {
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var menuBar = new MenuBarv2 ();
 
@@ -100,7 +100,7 @@ public class MenuBarv2Tests
     public void ChangesKey_RaisesEvent (TestDriver d)
     {
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var menuBar = new MenuBarv2 ();
 
@@ -137,12 +137,13 @@ public class MenuBarv2Tests
     public void DefaultKey_Activates (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        Toplevel? top = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((app) =>
                                             {
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                top = app.Current!;
 
                                                 top.Add (
                                                          new View ()
@@ -155,13 +156,13 @@ public class MenuBarv2Tests
                                                 Application.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertIsNotType<MenuItemv2> (top?.App?.Navigation!.GetFocused ())
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
                                      .WaitIteration ()
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
-                                     .AssertEqual ("_New file", Application.Navigation!.GetFocused ()!.Title)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertEqual ("_New file", top?.App?.Navigation!.GetFocused ()!.Title)
+                                     .AssertTrue (top?.App?.Popover?.GetActivePopover () is PopoverMenu)
                                      .AssertTrue (menuBar?.IsOpen ());
     }
 
@@ -173,10 +174,10 @@ public class MenuBarv2Tests
         MenuBarv2? menuBar = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((app) =>
                                             {
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
 
                                                 top.Add (
                                                          new View ()
@@ -186,7 +187,7 @@ public class MenuBarv2Tests
 
                                                          });
                                                 menuBar.EnableForDesign (ref top);
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
                                      .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
@@ -203,9 +204,11 @@ public class MenuBarv2Tests
     [ClassData (typeof (TestDrivers))]
     public void ShowHidePopovers (TestDriver d)
     {
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 // Create a menu bar with items that have submenus
                                                 var fileMenuItem = new MenuBarItemv2 (
                                                                                       "_File",
@@ -214,7 +217,7 @@ public class MenuBarv2Tests
                                                                                           new MenuItemv2 ("_Save", string.Empty, null)
                                                                                       ]);
 
-                                                var menuBar = new MenuBarv2 ([fileMenuItem]);
+                                                var menuBar = new MenuBarv2 ([fileMenuItem]) { App = app };
 
                                                 // Initially, no menu should be open
                                                 Assert.False (menuBar.IsOpen ());
@@ -259,7 +262,7 @@ public class MenuBarv2Tests
     public void EnableForDesign_CreatesMenuItems (TestDriver d)
     {
         using GuiTestContext c = With.A<Window> (80, 25, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var menuBar = new MenuBarv2 ();
                                                 Application.Current!.Add (menuBar);
@@ -291,24 +294,26 @@ public class MenuBarv2Tests
     public void Navigation_Left_Right_Wraps (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        IApplication? app = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
                                                 menuBar.EnableForDesign (ref top);
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
                                      .AssertTrue (menuBar?.IsOpen ())
                                      .AssertEqual ("_New file", Application.Navigation?.GetFocused ()!.Title)
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
                                      .EnqueueKeyEvent (Key.CursorRight)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
                                      .ScreenShot ("After right arrow", _out)
                                      .AssertEqual ("Cu_t", Application.Navigation?.GetFocused ()!.Title)
                                      .EnqueueKeyEvent (Key.CursorRight)
@@ -329,12 +334,14 @@ public class MenuBarv2Tests
     public void MenuBarItem_With_QuitKey_Open_QuitKey_Restores_Focus_Correctly (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        IApplication? app = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
 
                                                 top.Add (
                                                          new View ()
@@ -344,19 +351,19 @@ public class MenuBarv2Tests
 
                                                          });
                                                 menuBar.EnableForDesign (ref top);
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertIsNotType<MenuItemv2> (app!.Navigation!.GetFocused ())
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
-                                     .AssertEqual ("_New file", Application.Navigation!.GetFocused ()!.Title)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertEqual ("_New file", app.Navigation!.GetFocused ()!.Title)
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
                                      .AssertTrue (menuBar?.IsOpen ())
-                                     .AssertEqual ("_New file", Application.Navigation?.GetFocused ()!.Title)
+                                     .AssertEqual ("_New file", app?.Navigation?.GetFocused ()!.Title)
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
                                      .EnqueueKeyEvent (Application.QuitKey)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ());
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertIsNotType<MenuItemv2> (app!.Navigation!.GetFocused ());
     }
 
     [Theory]
@@ -364,6 +371,7 @@ public class MenuBarv2Tests
     public void MenuBarItem_Without_QuitKey_Open_QuitKey_Restores_Focus_Correctly (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        IApplication? app = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
                                      .Add (
@@ -373,26 +381,27 @@ public class MenuBarv2Tests
                                                Id = "focusableView",
 
                                            })
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel? toplevel = Application.Current;
+                                                Toplevel? toplevel = app.Current;
                                                 menuBar.EnableForDesign (ref toplevel!);
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertIsNotType<MenuItemv2> (app?.Navigation!.GetFocused ())
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
                                      .EnqueueKeyEvent (Key.CursorRight)
-                                     .AssertEqual ("Cu_t", Application.Navigation!.GetFocused ()!.Title)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertEqual ("Cu_t", app?.Navigation!.GetFocused ()!.Title)
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
                                      .AssertTrue (menuBar?.IsOpen ())
-                                     .AssertEqual ("Cu_t", Application.Navigation?.GetFocused ()!.Title)
+                                     .AssertEqual ("Cu_t", app?.Navigation?.GetFocused ()!.Title)
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
                                      .EnqueueKeyEvent (Application.QuitKey)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation?.GetFocused ());
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertIsNotType<MenuItemv2> (app?.Navigation?.GetFocused ());
     }
 
     [Theory]
@@ -400,12 +409,14 @@ public class MenuBarv2Tests
     public void MenuBarItem_With_QuitKey_Open_QuitKey_Does_Not_Quit_App (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        IApplication? app = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
 
                                                 top.Add (
                                                          new View ()
@@ -415,18 +426,18 @@ public class MenuBarv2Tests
 
                                                          });
                                                 menuBar.EnableForDesign (ref top);
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertIsNotType<MenuItemv2> (app!.Navigation!.GetFocused ())
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
-                                     .AssertEqual ("_New file", Application.Navigation!.GetFocused ()!.Title)
+                                     .AssertEqual ("_New file", app.Navigation!.GetFocused ()!.Title)
                                      .AssertTrue (Application.Current!.Running)
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
                                      .EnqueueKeyEvent (Application.QuitKey)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertTrue (Application.Current!.Running);
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app!.Current!.Running);
     }
 
     [Theory]
@@ -434,12 +445,14 @@ public class MenuBarv2Tests
     public void MenuBarItem_Without_QuitKey_Open_QuitKey_Does_Not_Quit_MenuBar_SuperView (TestDriver d)
     {
         MenuBarv2? menuBar = null;
+        IApplication? app = null;
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
+                                                app = a;
                                                 menuBar = new MenuBarv2 ();
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
 
                                                 top.Add (
                                                          new View ()
@@ -456,17 +469,17 @@ public class MenuBarv2Tests
                                                     item.Key = Key.Empty;
                                                 }
 
-                                                Application.Current!.Add (menuBar);
+                                                app.Current!.Add (menuBar);
                                             })
                                      .WaitIteration ()
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertIsNotType<MenuItemv2> (app?.Navigation!.GetFocused ())
                                      .ScreenShot ("MenuBar initial state", _out)
                                      .EnqueueKeyEvent (MenuBarv2.DefaultKey)
-                                     .AssertEqual ("_New file", Application.Navigation!.GetFocused ()!.Title)
+                                     .AssertEqual ("_New file", app?.Navigation!.GetFocused ()!.Title)
                                      .ScreenShot ($"After {MenuBarv2.DefaultKey}", _out)
                                      .EnqueueKeyEvent (Application.QuitKey)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertTrue (Application.Current!.Running);
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app?.Current!.Running);
     }
 
     [Theory]
@@ -489,7 +502,7 @@ public class MenuBarv2Tests
                             };
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var menuBar = new MenuBarv2 ();
                                                 Toplevel top = Application.Current!;
@@ -523,7 +536,7 @@ public class MenuBarv2Tests
                             };
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var menuBar = new MenuBarv2 ();
                                                 Toplevel top = Application.Current!;

+ 1 - 1
Tests/IntegrationTests/FluentTests/NavigationTests.cs

@@ -21,7 +21,7 @@ public class NavigationTests (ITestOutputHelper outputHelper)
         var v6 = new View { Id = "v6", CanFocus = true };
 
         using GuiTestContext c = With.A<Window> (50, 20, d, _out)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 var w1 = new Window { Id = "w1" };
                                                 w1.Add (v1, v2);

+ 102 - 61
Tests/IntegrationTests/FluentTests/PopverMenuTests.cs

@@ -23,7 +23,7 @@ public class PopoverMenuTests
     public void EnableForDesign_CreatesMenuItems (TestDriver d)
     {
         using GuiTestContext c = With.A<Window> (80, 25, d)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 PopoverMenu popoverMenu = new ();
                                                 Application.Current!.Add (popoverMenu);
@@ -54,13 +54,18 @@ public class PopoverMenuTests
     {
         lock (o)
         {
+            IApplication? app = null;
             using GuiTestContext c = With.A<Window> (50, 20, d)
-                                         .Then (() =>
+                                         .Then ((a) =>
                                                 {
-                                                    PopoverMenu popoverMenu = new ();
+                                                    app = a;
+                                                    PopoverMenu popoverMenu = new ()
+                                                    {
+                                                        App = app
+                                                    };
 
                                                     // Call EnableForDesign
-                                                    Toplevel top = Application.Current!;
+                                                    Toplevel top = app.Current!;
                                                     popoverMenu.EnableForDesign (ref top);
 
                                                     var view = new View
@@ -71,22 +76,22 @@ public class PopoverMenuTests
                                                         Id = "focusableView",
                                                         Text = "View"
                                                     };
-                                                    Application.Current!.Add (view);
+                                                    app.Current!.Add (view);
 
                                                     // EnableForDesign sets to true; undo that
                                                     popoverMenu.Visible = false;
 
-                                                    Application.Popover!.Register (popoverMenu);
+                                                    app?.Popover!.Register (popoverMenu);
 
                                                     view.SetFocus ();
                                                 })
-                                         .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                         .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                         .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                         .AssertIsNotType<MenuItemv2> (app?.Navigation!.GetFocused ())
                                          .ScreenShot ("PopoverMenu initial state", _out)
-                                         .Then (() => Application.Popover!.Show (Application.Popover.Popovers.First ()))
+                                         .Then ((_) => app?.Popover!.Show (app?.Popover.Popovers.First ()))
                                          .ScreenShot ("After Show", _out)
-                                         .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                         .AssertEqual ("Cu_t", Application.Navigation!.GetFocused ()!.Title);
+                                         .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                         .AssertEqual ("Cu_t", app?.Navigation!.GetFocused ()!.Title);
         }
     }
 
@@ -94,13 +99,18 @@ public class PopoverMenuTests
     [ClassData (typeof (TestDrivers))]
     public void QuitKey_Hides (TestDriver d)
     {
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
 
                                                 // Call EnableForDesign
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
                                                 bool result = popoverMenu.EnableForDesign (ref top);
 
                                                 var view = new View
@@ -111,38 +121,43 @@ public class PopoverMenuTests
                                                     Id = "focusableView",
                                                     Text = "View"
                                                 };
-                                                Application.Current!.Add (view);
+                                                app.Current!.Add (view);
 
                                                 // EnableForDesign sets to true; undo that
                                                 popoverMenu.Visible = false;
 
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
 
                                                 view.SetFocus ();
                                             })
                                      .ScreenShot ("PopoverMenu initial state", _out)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .Then (() => Application.Popover!.Show (Application.Popover.Popovers.First ()))
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .Then ((_) => app?.Popover!.Show (app?.Popover.Popovers.First ()))
                                      .ScreenShot ("After Show", _out)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
                                      .EnqueueKeyEvent (Application.QuitKey)
                                      .ScreenShot ($"After {Application.QuitKey}", _out)
-                                     .AssertFalse (Application.Popover!.Popovers.Cast<PopoverMenu> ().FirstOrDefault ()!.Visible)
-                                     .AssertNull (Application.Popover!.GetActivePopover ())
-                                     .AssertTrue (Application.Current!.Running);
+                                     .AssertFalse (app?.Popover!.Popovers.Cast<PopoverMenu> ().FirstOrDefault ()!.Visible)
+                                     .AssertNull (app?.Popover!.GetActivePopover ())
+                                     .AssertTrue (app?.Current!.Running);
     }
 
     [Theory]
     [ClassData (typeof (TestDrivers))]
     public void QuitKey_Restores_Focus_Correctly (TestDriver d)
     {
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
 
                                                 // Call EnableForDesign
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
                                                 bool result = popoverMenu.EnableForDesign (ref top);
 
                                                 var view = new View
@@ -153,39 +168,45 @@ public class PopoverMenuTests
                                                     Id = "focusableView",
                                                     Text = "View"
                                                 };
-                                                Application.Current!.Add (view);
+                                                app.Current!.Add (view);
 
                                                 // EnableForDesign sets to true; undo that
                                                 popoverMenu.Visible = false;
 
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
 
                                                 view.SetFocus ();
                                             })
                                      .ScreenShot ("PopoverMenu initial state", _out)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
-                                     .Then (() => Application.Popover!.Show (Application.Popover.Popovers.First ()))
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertIsNotType<MenuItemv2> (app?.Navigation!.GetFocused ())
+                                     .Then ((_) => app?.Popover!.Show (app?.Popover.Popovers.First ()))
                                      .ScreenShot ("After Show", _out)
-                                     .AssertTrue (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertIsType<MenuItemv2> (Application.Navigation!.GetFocused ())
+                                     .AssertTrue (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertIsType<MenuItemv2> (app?.Navigation!.GetFocused ())
                                      .EnqueueKeyEvent (Application.QuitKey)
                                      .ScreenShot ($"After {Application.QuitKey}", _out)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ());
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertIsNotType<MenuItemv2> (app?.Navigation!.GetFocused ());
     }
 
     [Theory]
     [ClassData (typeof (TestDrivers))]
     public void MenuBarItem_With_QuitKey_Open_QuitKey_Does_Not_Quit_App (TestDriver d)
     {
+        IApplication? app = null;
+
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
 
                                                 // Call EnableForDesign
-                                                Toplevel top = Application.Current!;
+                                                Toplevel top = app.Current!;
                                                 bool result = popoverMenu.EnableForDesign (ref top);
 
                                                 var view = new View
@@ -201,20 +222,20 @@ public class PopoverMenuTests
                                                 // EnableForDesign sets to true; undo that
                                                 popoverMenu.Visible = false;
 
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
 
                                                 view.SetFocus ();
                                             })
                                      .AssertIsNotType<MenuItemv2> (Application.Navigation!.GetFocused ())
                                      .ScreenShot ("PopoverMenu initial state", _out)
-                                     .Then (() => Application.Popover!.Show (Application.Popover.Popovers.First ()))
+                                     .Then ((_) => app?.Popover!.Show (app?.Popover.Popovers.First ()))
                                      .ScreenShot ("PopoverMenu after Show", _out)
-                                     .AssertEqual ("Cu_t", Application.Navigation!.GetFocused ()!.Title)
-                                     .AssertTrue (Application.Current!.Running)
+                                     .AssertEqual ("Cu_t", app?.Navigation!.GetFocused ()!.Title)
+                                     .AssertTrue (app?.Current!.Running)
                                      .EnqueueKeyEvent (Application.QuitKey)
                                      .ScreenShot ($"After {Application.QuitKey}", _out)
-                                     .AssertFalse (Application.Popover?.GetActivePopover () is PopoverMenu)
-                                     .AssertTrue (Application.Current!.Running);
+                                     .AssertFalse (app?.Popover?.GetActivePopover () is PopoverMenu)
+                                     .AssertTrue (app?.Current!.Running);
     }
 
     [Theory]
@@ -237,13 +258,18 @@ public class PopoverMenuTests
                                 }
                             };
 
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
-                                                Toplevel top = Application.Current!;
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
+                                                Toplevel top = app.Current!;
                                                 popoverMenu.EnableForDesign (ref top);
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
                                             })
                                      .Add (testView)
                                      .Focus (testView)
@@ -271,13 +297,19 @@ public class PopoverMenuTests
                                 }
                             };
 
+        IApplication? app = null;
+
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
-                                                Toplevel top = Application.Current!;
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
+                                                Toplevel top = app.Current!;
                                                 popoverMenu.EnableForDesign (ref top);
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
                                             })
                                      .Add (testView)
                                      .Focus (testView)
@@ -305,13 +337,18 @@ public class PopoverMenuTests
                                 }
                             };
 
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (50, 20, d)
-                                     .Then (() =>
+                                     .Then ((a) =>
                                             {
-                                                PopoverMenu popoverMenu = new ();
-                                                Toplevel top = Application.Current!;
+                                                app = a;
+                                                PopoverMenu popoverMenu = new ()
+                                                {
+                                                    App = app
+                                                };
+                                                Toplevel top = app.Current!;
                                                 popoverMenu.EnableForDesign (ref top);
-                                                Application.Popover!.Register (popoverMenu);
+                                                app?.Popover!.Register (popoverMenu);
                                             })
                                      .Add (testView)
                                      .EnqueueKeyEvent (Application.QuitKey)
@@ -326,24 +363,25 @@ public class PopoverMenuTests
 
         MenuItemv2 [] menuItems = [new ("_New File", string.Empty, () => { clicked = true; })];
 
+        IApplication? app = null;
         using GuiTestContext c = With.A<Window> (40, 10, d, _out)
-                                     .WithContextMenu (new (menuItems))
+                                     .Then ((a) => app = a)
+                                     .WithContextMenu (new (menuItems) { App = app })
                                      .ScreenShot ("Before open menu", _out)
 
                                      // Click in main area inside border
                                      .RightClick (1, 1)
-                                     .Then (() =>
+                                     .Then ((_) =>
                                             {
                                                 // Test depends on menu having a border
-                                                IPopover? popover = Application.Popover!.GetActivePopover ();
+                                                IPopover? popover = app?.Popover!.GetActivePopover ();
                                                 Assert.NotNull (popover);
                                                 var popoverMenu = popover as PopoverMenu;
                                                 popoverMenu!.Root!.BorderStyle = LineStyle.Single;
                                             })
                                      .ScreenShot ("After open menu", _out)
                                      .LeftClick (2, 2)
-            ;
-        Assert.True (clicked);
+                                     .AssertTrue(clicked);
     }
 
     [Theory]
@@ -374,8 +412,11 @@ public class PopoverMenuTests
             new ("Six", "", null)
         ];
 
+        IApplication? app = null;
+
         using GuiTestContext c = With.A<Window> (40, 10, d)
-                                     .WithContextMenu (new (menuItems))
+                                     .Then ((a) => app = a)
+                                     .WithContextMenu (new (menuItems) { App = app })
                                      .ScreenShot ("Before open menu", _out)
 
                                      // Click in main area inside border

+ 2 - 2
Tests/IntegrationTests/FluentTests/TreeViewFluentTests.cs

@@ -55,7 +55,7 @@ public class TreeViewFluentTests
                                  })
                 .AssertIsAssignableFrom <ITreeNode>(tv.SelectedObject)
                 .Then (
-                       () =>
+                       (_) =>
                        {
                            // Re order
                            root.Children = [bike, car, lorry];
@@ -150,7 +150,7 @@ public class TreeViewFluentTests
                                      Assert.Equal (mrE, tv.GetObjectOnRow (8));
                                  })
                 .Then (
-                       () =>
+                       (_) =>
                        {
                            // Re order
                            root.Children = [bike, car, lorry];

+ 8 - 2
Tests/TerminalGuiFluentTesting/GuiTestContext.ContextMenu.cs

@@ -1,3 +1,5 @@
+using System.Diagnostics;
+
 #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
 
 namespace TerminalGuiFluentTesting;
@@ -12,13 +14,17 @@ public partial class GuiTestContext
     /// <returns></returns>
     public GuiTestContext WithContextMenu (PopoverMenu? contextMenu)
     {
-        LastView.MouseEvent += (s, e) =>
+        if (contextMenu?.App is null)
+        {
+            Fail (@"PopoverMenu's must have their App property set.");
+        }
+        LastView.MouseEvent += (_, e) =>
                                {
                                    if (e.Flags.HasFlag (MouseFlags.Button3Clicked))
                                    {
                                        // Registering with the PopoverManager will ensure that the context menu is closed when the view is no longer focused
                                        // and the context menu is disposed when it is closed.
-                                       Application.Popover?.Register (contextMenu);
+                                       App.Popover?.Register (contextMenu);
                                        contextMenu?.MakeVisible (e.ScreenPosition);
                                    }
                                };

+ 4 - 4
Tests/TerminalGuiFluentTesting/GuiTestContext.Input.cs

@@ -58,13 +58,13 @@ public partial class GuiTestContext
     private GuiTestContext EnqueueMouseEvent (MouseEventArgs mouseEvent)
     {
             // Enqueue the mouse event
-        WaitIteration (() =>
+        WaitIteration ((app) =>
         {
-            if (Application.Driver is { })
+            if (app.Driver is { })
             {
                 mouseEvent.Position = mouseEvent.ScreenPosition;
 
-                Application.Driver.InputProcessor.EnqueueMouseEvent (mouseEvent);
+                app.Driver.InputProcessor.EnqueueMouseEvent (mouseEvent);
             }
             else
             {
@@ -81,7 +81,7 @@ public partial class GuiTestContext
     {
         var screen = Point.Empty;
 
-        GuiTestContext ctx = WaitIteration (() =>
+        GuiTestContext ctx = WaitIteration ((_) =>
                                             {
                                                 TView v = Find (evaluator);
                                                 screen = v.ViewportToScreen (new Point (0, 0));

+ 5 - 5
Tests/TerminalGuiFluentTesting/GuiTestContext.ViewBase.cs

@@ -12,9 +12,9 @@ public partial class GuiTestContext
     /// <returns></returns>
     public GuiTestContext Add (View v)
     {
-        WaitIteration (() =>
+        WaitIteration ((app) =>
                        {
-                           Toplevel top = Application.Current ?? throw new ("Top was null so could not add view");
+                           Toplevel top = app.Current ?? throw new ("Top was null so could not add view");
                            top.Add (v);
                            top.Layout ();
                            _lastView = v;
@@ -28,15 +28,15 @@ public partial class GuiTestContext
     /// <summary>
     ///     The last view added (e.g. with <see cref="Add"/>) or the root/current top.
     /// </summary>
-    public View LastView => _lastView ?? Application.Current ?? throw new ("Could not determine which view to add to");
+    public View LastView => _lastView ?? App.Current ?? throw new ("Could not determine which view to add to");
 
     private T Find<T> (Func<T, bool> evaluator) where T : View
     {
-        Toplevel? t = Application.Current;
+        Toplevel? t = App.Current;
 
         if (t == null)
         {
-            Fail ("Application.Current was null when attempting to find view");
+            Fail ("App.Current was null when attempting to find view");
         }
 
         T? f = FindRecursive (t!, evaluator);

+ 32 - 23
Tests/TerminalGuiFluentTesting/GuiTestContext.cs

@@ -31,6 +31,12 @@ public partial class GuiTestContext : IDisposable
     private IOutput? _output;
     private SizeMonitorImpl? _sizeMonitor;
     private ApplicationImpl? _applicationImpl;
+
+    /// <summary>
+    ///     The IApplication instance that was created.
+    /// </summary>
+    public IApplication App => _applicationImpl!;
+
     private TestDriver _driverType;
 
     // ===== Application State Preservation (for restoration) =====
@@ -277,7 +283,7 @@ public partial class GuiTestContext : IDisposable
     /// </summary>
     /// <param name="doAction"></param>
     /// <returns></returns>
-    public GuiTestContext Then (Action doAction)
+    public GuiTestContext Then (Action<IApplication> doAction)
     {
         try
         {
@@ -301,7 +307,7 @@ public partial class GuiTestContext : IDisposable
     /// </summary>
     /// <param name="action"></param>
     /// <returns></returns>
-    public GuiTestContext WaitIteration (Action? action = null)
+    public GuiTestContext WaitIteration (Action<IApplication>? action = null)
     {
         // If application has already exited don't wait!
         if (Finished || _runCancellationTokenSource.Token.IsCancellationRequested || _fakeInput.ExternalCancellationTokenSource!.Token.IsCancellationRequested)
@@ -317,25 +323,28 @@ public partial class GuiTestContext : IDisposable
         }
 
         Logging.Trace ($"WaitIteration started");
-        action ??= () => { };
-        CancellationTokenSource ctsActionCompleted = new ();
-
-        Application.Invoke (() =>
+        if (action is null)
         {
-            try
-            {
-                action ();
+            action = (app) => { };
+        }
+        CancellationTokenSource ctsActionCompleted = new ();
 
-                //Logging.Trace ("Action completed");
-                ctsActionCompleted.Cancel ();
-            }
-            catch (Exception e)
-            {
-                Logging.Warning ($"Action failed with exception: {e}");
-                _backgroundException = e;
-                _fakeInput.ExternalCancellationTokenSource?.Cancel ();
-            }
-        });
+        Application.Invoke (app =>
+                            {
+                                try
+                                {
+                                    action (app);
+
+                                    //Logging.Trace ("Action completed");
+                                    ctsActionCompleted.Cancel ();
+                                }
+                                catch (Exception e)
+                                {
+                                    Logging.Warning ($"Action failed with exception: {e}");
+                                    _backgroundException = e;
+                                    _fakeInput.ExternalCancellationTokenSource?.Cancel ();
+                                }
+                            });
 
         // Blocks until either the token or the hardStopToken is cancelled.
         // With linked tokens, we only need to wait on _runCancellationTokenSource and ctsLocal
@@ -383,15 +392,15 @@ public partial class GuiTestContext : IDisposable
     /// <param name="width">new Width for the console.</param>
     /// <param name="height">new Height for the console.</param>
     /// <returns></returns>
-    public GuiTestContext ResizeConsole (int width, int height) { return WaitIteration (() => { Application.Driver!.SetScreenSize (width, height); }); }
+    public GuiTestContext ResizeConsole (int width, int height) { return WaitIteration ((app) => { app.Driver!.SetScreenSize (width, height); }); }
 
     public GuiTestContext ScreenShot (string title, TextWriter? writer)
     {
         //Logging.Trace ($"{title}");
-        return WaitIteration (() =>
+        return WaitIteration ((app) =>
                               {
                                   writer?.WriteLine (title + ":");
-                                  var text = Application.ToString ();
+                                  var text = app.ToString ();
 
                                   writer?.WriteLine (text);
                               });
@@ -424,7 +433,7 @@ public partial class GuiTestContext : IDisposable
             return this;
         }
 
-        WaitIteration (() => { Application.RequestStop (); });
+        WaitIteration ((app) => { app.RequestStop (); });
 
         // Wait for the application to stop, but give it a 1-second timeout
         const int WAIT_TIMEOUT_MS = 1000;

+ 1 - 3
Tests/UnitTests/Application/Application.NavigationTests.cs

@@ -61,9 +61,7 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
     {
         var raised = false;
 
-        Application.Navigation = new ();
-
-        Application.Navigation.FocusedChanged += ApplicationNavigationOnFocusedChanged;
+        Application.Navigation!.FocusedChanged += ApplicationNavigationOnFocusedChanged;
 
         Application.Navigation.SetFocused (new () { CanFocus = true, HasFocus = true });
 

+ 2 - 2
Tests/UnitTests/Application/ApplicationImplTests.cs

@@ -625,7 +625,7 @@ public class ApplicationImplTests
         // Before Init, all fields should be null/default
         Assert.Null (v2.Driver);
         Assert.False (v2.Initialized);
-        Assert.Null (v2.Popover);
+        //Assert.Null (v2.Popover);
         //Assert.Null (v2.Navigation);
         Assert.Null (v2.Current);
         Assert.Empty (v2.SessionStack);
@@ -653,7 +653,7 @@ public class ApplicationImplTests
 
         Assert.Null (v2.Driver);
         Assert.False (v2.Initialized);
-        Assert.Null (v2.Popover);
+        //Assert.Null (v2.Popover);
         //Assert.Null (v2.Navigation);
         Assert.Null (v2.Current);
         Assert.Empty (v2.SessionStack);

+ 26 - 28
Tests/UnitTests/Application/ApplicationPopoverTests.cs

@@ -9,7 +9,6 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
             Application.Init (null, "fake");
 
             // Act
@@ -27,7 +26,7 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
+
             Application.Init (null, "fake");
 
             // Act
@@ -36,7 +35,6 @@ public class ApplicationPopoverTests
             Application.Shutdown ();
 
             // Test
-            Assert.Null (Application.Popover);
         }
         finally
         {
@@ -52,12 +50,11 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
             Application.Init (null, "fake");
             Assert.NotNull (Application.Popover);
             Application.StopAfterFirstIteration = true;
 
-            top = new Toplevel ();
+            top = new ();
             SessionToken rs = Application.Begin (top);
 
             // Act
@@ -81,15 +78,15 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
             Application.Init (null, "fake");
             Application.StopAfterFirstIteration = true;
 
-            top = new Toplevel ();
+            top = new ();
             SessionToken rs = Application.Begin (top);
 
             PopoverTestClass? popover = new ();
 
+            Application.Popover?.Register (popover);
             Application.Popover?.Show (popover);
             Assert.True (popover.Visible);
 
@@ -116,7 +113,7 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
+
             Application.Init (null, "fake");
 
             PopoverTestClass? popover = new ();
@@ -140,7 +137,7 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
+
             Application.Init (null, "fake");
 
             PopoverTestClass? popover = new ();
@@ -169,11 +166,11 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
+
             Application.Init (null, "fake");
 
             PopoverTestClass? popover = new ();
-
+            Application.Popover?.Register (popover);
             Application.Popover?.Show (popover);
             Application.Popover?.DeRegister (popover);
 
@@ -198,9 +195,9 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
+
             Application.Init (null, "fake");
-            Application.Current = new Toplevel ();
+            Application.Current = new ();
             PopoverTestClass? popover = new ();
 
             // Act
@@ -221,23 +218,23 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
             Application.Init (null, "fake");
-            Application.Current = new Toplevel () { Id = "initialTop" };
-            PopoverTestClass? popover = new ();
-            int keyDownEvents = 0;
+            Application.Current = new() { Id = "initialTop" };
+            PopoverTestClass? popover = new () { };
+            var keyDownEvents = 0;
+
             popover.KeyDown += (s, e) =>
-            {
-                keyDownEvents++;
-                e.Handled = true;
-            }; // Ensure it handles the key
+                               {
+                                   keyDownEvents++;
+                                   e.Handled = true;
+                               }; // Ensure it handles the key
 
             Application.Popover?.Register (popover);
 
             // Act
             Application.RaiseKeyDownEvent (Key.A); // Goes to initialTop
 
-            Application.Current = new Toplevel () { Id = "secondaryTop" };
+            Application.Current = new() { Id = "secondaryTop" };
             Application.RaiseKeyDownEvent (Key.A); // Goes to secondaryTop
 
             // Test
@@ -268,8 +265,8 @@ public class ApplicationPopoverTests
         try
         {
             // Arrange
-            Assert.Null (Application.Popover);
             Application.Init (null, "fake");
+
             Application.Current = new ()
             {
                 Frame = new (0, 0, 10, 10),
@@ -282,7 +279,7 @@ public class ApplicationPopoverTests
                 X = 1,
                 Y = 1,
                 Width = 2,
-                Height = 2,
+                Height = 2
             };
 
             Application.Current.Add (view);
@@ -293,7 +290,7 @@ public class ApplicationPopoverTests
                 X = 5,
                 Y = 5,
                 Width = 3,
-                Height = 3,
+                Height = 3
             }; // at 5,5 to 8,8 (screen)
 
             View? popoverSubView = new ()
@@ -302,14 +299,15 @@ public class ApplicationPopoverTests
                 X = 1,
                 Y = 1,
                 Width = 1,
-                Height = 1,
+                Height = 1
             };
 
             popover.Add (popoverSubView);
+            Application.Popover?.Register (popover);
 
             Application.Popover?.Show (popover);
 
-            List<View?> found = View.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
+            List<View?> found = view.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
 
             string [] foundIds = found.Select (v => v!.Id).ToArray ();
 
@@ -361,4 +359,4 @@ public class ApplicationPopoverTests
             DisposedCount++;
         }
     }
-}
+}

+ 3 - 5
Tests/UnitTests/Application/ApplicationTests.cs

@@ -313,8 +313,6 @@ public class ApplicationTests
         // Mouse
         Application.LastMousePosition = new Point (1, 1);
 
-        Application.Navigation = new ();
-
         Application.ResetState ();
         CheckReset ();
 
@@ -361,7 +359,7 @@ public class ApplicationTests
            // Assert.Null (Application.Navigation);
 
             // Popover
-            Assert.Null (Application.Popover);
+            //Assert.Null (Application.Popover);
 
             // Events - Can't check
             //Assert.Null (GetEventSubscribers (typeof (Application), "InitializedChanged"));
@@ -509,7 +507,7 @@ public class ApplicationTests
         SessionToken rs = Application.Begin (top);
 
         var actionCalled = 0;
-        Application.Invoke (() => { actionCalled++; });
+        Application.Invoke ((_) => { actionCalled++; });
         Application.TimedEvents!.RunTimers ();
         Assert.Equal (1, actionCalled);
         top.Dispose ();
@@ -968,7 +966,7 @@ public class ApplicationTests
                            (t, _) =>
                            {
                                // no longer loading
-                               Application.Invoke (() => { Application.RequestStop (); });
+                               Application.Invoke ((app) => { app.RequestStop (); });
                            },
                            TaskScheduler.FromCurrentSynchronizationContext ());
         Application.Run<TestToplevel> ();

+ 11 - 19
Tests/UnitTests/Application/CursorTests.cs

@@ -1,5 +1,4 @@
-using UnitTests;
-using Xunit.Abstractions;
+using Xunit.Abstractions;
 
 namespace UnitTests.ApplicationTests;
 
@@ -7,22 +6,20 @@ public class CursorTests
 {
     private readonly ITestOutputHelper _output;
 
-    public CursorTests (ITestOutputHelper output)
-    {
-        _output = output;
-    }
+    public CursorTests (ITestOutputHelper output) { _output = output; }
 
     private class TestView : View
     {
         public Point? TestLocation { get; set; }
 
-        /// <inheritdoc />
+        /// <inheritdoc/>
         public override Point? PositionCursor ()
         {
             if (TestLocation.HasValue && HasFocus)
             {
                 Driver?.SetCursorVisibility (CursorVisibility.Default);
             }
+
             return TestLocation;
         }
     }
@@ -31,7 +28,6 @@ public class CursorTests
     [AutoInitShutdown]
     public void PositionCursor_No_Focus_Returns_False ()
     {
-        Application.Navigation = new ();
         Application.Navigation.SetFocused (null);
 
         Assert.False (Application.PositionCursor ());
@@ -40,7 +36,7 @@ public class CursorTests
         {
             CanFocus = false,
             Width = 1,
-            Height = 1,
+            Height = 1
         };
         view.TestLocation = new Point (0, 0);
         Assert.False (Application.PositionCursor ());
@@ -50,12 +46,11 @@ public class CursorTests
     [AutoInitShutdown]
     public void PositionCursor_No_Position_Returns_False ()
     {
-        Application.Navigation = new ();
         TestView view = new ()
         {
             CanFocus = false,
             Width = 1,
-            Height = 1,
+            Height = 1
         };
 
         view.CanFocus = true;
@@ -67,11 +62,10 @@ public class CursorTests
     [AutoInitShutdown]
     public void PositionCursor_No_IntersectSuperView_Returns_False ()
     {
-        Application.Navigation = new ();
         View superView = new ()
         {
             Width = 1,
-            Height = 1,
+            Height = 1
         };
 
         TestView view = new ()
@@ -80,7 +74,7 @@ public class CursorTests
             X = 1,
             Y = 1,
             Width = 1,
-            Height = 1,
+            Height = 1
         };
         superView.Add (view);
 
@@ -94,11 +88,10 @@ public class CursorTests
     [AutoInitShutdown]
     public void PositionCursor_Position_OutSide_SuperView_Returns_False ()
     {
-        Application.Navigation = new ();
         View superView = new ()
         {
             Width = 1,
-            Height = 1,
+            Height = 1
         };
 
         TestView view = new ()
@@ -107,7 +100,7 @@ public class CursorTests
             X = 0,
             Y = 0,
             Width = 2,
-            Height = 2,
+            Height = 2
         };
         superView.Add (view);
 
@@ -138,12 +131,11 @@ public class CursorTests
     [AutoInitShutdown]
     public void PositionCursor_Defaults_Invisible ()
     {
-        Application.Navigation = new ();
         View view = new ()
         {
             CanFocus = true,
             Width = 1,
-            Height = 1,
+            Height = 1
         };
         view.SetFocus ();
 

+ 1 - 1
Tests/UnitTests/Application/MainLoopCoordinatorTests.cs

@@ -26,7 +26,7 @@ public class MainLoopCoordinatorTests
 
         // StartAsync boots the main loop and the input thread. But if the input class bombs
         // on startup it is important that the exception surface at the call site and not lost
-        var ex = await Assert.ThrowsAsync<AggregateException>(c.StartInputTaskAsync);
+        var ex = await Assert.ThrowsAsync<AggregateException>(() => c.StartInputTaskAsync (null));
         Assert.Equal ("Crash on boot", ex.InnerExceptions [0].Message);
 
 

+ 19 - 19
Tests/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs

@@ -126,7 +126,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (0, view1.OnMouseEnterCalled);
@@ -139,7 +139,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -152,7 +152,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -165,7 +165,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -178,7 +178,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -253,7 +253,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (0, view1.OnMouseEnterCalled);
@@ -266,7 +266,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -279,7 +279,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -292,7 +292,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -305,7 +305,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -318,7 +318,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -372,7 +372,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (0, view1.OnMouseEnterCalled);
@@ -385,7 +385,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -398,7 +398,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -411,7 +411,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (1, view1.OnMouseEnterCalled);
@@ -424,7 +424,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (2, view1.OnMouseEnterCalled);
@@ -437,7 +437,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (2, view1.OnMouseEnterCalled);
@@ -450,7 +450,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (2, view1.OnMouseEnterCalled);
@@ -463,7 +463,7 @@ public class ApplicationMouseEnterLeaveTests
 
             Application.RaiseMouseEnterLeaveEvents (
                                                     mousePosition,
-                                                    View.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
+                                                    Application.Current.GetViewsUnderLocation (mousePosition, ViewportSettingsFlags.TransparentMouse));
 
             // Assert
             Assert.Equal (3, view1.OnMouseEnterCalled);

+ 2 - 2
Tests/UnitTests/View/Adornment/AdornmentSubViewTests.cs

@@ -37,7 +37,7 @@ public class AdornmentSubViewTests (ITestOutputHelper output)
         Application.Current.Margin!.Add (subView);
         Application.Current.Layout ();
 
-        var foundView = View.GetViewsUnderLocation (new Point(0, 0), ViewportSettingsFlags.None).LastOrDefault ();
+        var foundView = Application.Current.GetViewsUnderLocation (new Point(0, 0), ViewportSettingsFlags.None).LastOrDefault ();
 
         bool found = foundView == subView || foundView == subView.Margin;
         Assert.Equal (expectedFound, found);
@@ -66,7 +66,7 @@ public class AdornmentSubViewTests (ITestOutputHelper output)
         Application.Current.Padding.Add (subView);
         Application.Current.Layout ();
 
-        Assert.Equal (Application.Current.Padding, View.GetViewsUnderLocation (new Point(0, 0), ViewportSettingsFlags.None).LastOrDefault ());
+        Assert.Equal (Application.Current.Padding, Application.Current.GetViewsUnderLocation (new Point(0, 0), ViewportSettingsFlags.None).LastOrDefault ());
         Application.Current?.Dispose ();
         Application.ResetState (ignoreDisposed: true);
     }

+ 2 - 1
Tests/UnitTests/View/Adornment/ShadowStyleTests.cs

@@ -136,7 +136,8 @@ public class ShadowStyleTests (ITestOutputHelper output)
     {
         var superView = new View
         {
-            Height = 10, Width = 10
+            Height = 10, Width = 10,
+            App = ApplicationImpl.Instance
         };
 
         View view = new ()

+ 4 - 2
Tests/UnitTests/View/Draw/ClipTests.cs

@@ -252,7 +252,8 @@ public class ClipTests (ITestOutputHelper _output)
         {
             Width = Dim.Fill (),
             Height = Dim.Fill (),
-            ViewportSettings = ViewportSettingsFlags.ClipContentOnly
+            ViewportSettings = ViewportSettingsFlags.ClipContentOnly,
+            App = ApplicationImpl.Instance
         };
         view.SetContentSize (new Size (10, 10));
         view.Border!.Thickness = new (1);
@@ -286,7 +287,8 @@ public class ClipTests (ITestOutputHelper _output)
         var view = new View
         {
             Width = Dim.Fill (),
-            Height = Dim.Fill ()
+            Height = Dim.Fill (),
+            App = ApplicationImpl.Instance
         };
         view.SetContentSize (new Size (10, 10));
         view.Border!.Thickness = new (1);

+ 22 - 22
Tests/UnitTests/View/Layout/GetViewsUnderLocationTests.cs

@@ -85,7 +85,7 @@ public class GetViewsUnderLocationTests
         var location = new Point (testX, testY);
 
         // Act
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (location, ViewportSettingsFlags.TransparentMouse);
+        List<View?> viewsUnderMouse = Application.Current.GetViewsUnderLocation (location, ViewportSettingsFlags.TransparentMouse);
 
         // Assert
         if (expectedViewsFound.Length == 0)
@@ -117,7 +117,7 @@ public class GetViewsUnderLocationTests
         var location = new Point (testX, testY);
 
         // Act
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (location, ViewportSettingsFlags.TransparentMouse);
+        List<View?> viewsUnderMouse = Application.Current.GetViewsUnderLocation (location, ViewportSettingsFlags.TransparentMouse);
 
         // Assert
         Assert.Contains (viewsUnderMouse, v => v == Application.Current);
@@ -139,7 +139,7 @@ public class GetViewsUnderLocationTests
             Width = 10, Height = 10
         };
 
-        Assert.Same (Application.Current, View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ());
+        Assert.Same (Application.Current, Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ());
         Application.Current.Dispose ();
         Application.ResetState (true);
     }
@@ -167,7 +167,7 @@ public class GetViewsUnderLocationTests
         };
         Application.Current.Add (subview);
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -197,7 +197,7 @@ public class GetViewsUnderLocationTests
         };
         Application.Current.Add (subview);
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -229,7 +229,7 @@ public class GetViewsUnderLocationTests
         subview.Visible = true;
         Assert.True (subview.Visible);
         Assert.False (Application.Current.Visible);
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -262,7 +262,7 @@ public class GetViewsUnderLocationTests
         };
         Application.Current.Add (subview);
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -294,7 +294,7 @@ public class GetViewsUnderLocationTests
         };
         Application.Current.Add (subview);
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -328,7 +328,7 @@ public class GetViewsUnderLocationTests
         Application.Current.BeginInit ();
         Application.Current.EndInit ();
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == subview);
         Application.Current.Dispose ();
@@ -367,7 +367,7 @@ public class GetViewsUnderLocationTests
         };
         Application.Current.Add (subview);
 
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
+        List<View?> viewsUnderMouse = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
         string [] foundIds = viewsUnderMouse.Select (v => v!.Id).ToArray ();
 
         Assert.Equal (expectedViewsFound, foundIds);
@@ -404,7 +404,7 @@ public class GetViewsUnderLocationTests
         subview.Border!.Id = "border";
         Application.Current.Add (subview);
 
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
+        List<View?> viewsUnderMouse = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
         string [] foundIds = viewsUnderMouse.Select (v => v!.Id).ToArray ();
 
         Assert.Equal (expectedViewsFound, foundIds);
@@ -442,7 +442,7 @@ public class GetViewsUnderLocationTests
         subview.Border!.Id = "border";
         Application.Current.Add (subview);
 
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
+        List<View?> viewsUnderMouse = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse);
         string [] foundIds = viewsUnderMouse.Select (v => v!.Id).ToArray ();
 
         Assert.Equal (expectedViewsFound, foundIds);
@@ -490,7 +490,7 @@ public class GetViewsUnderLocationTests
         Application.Current.BeginInit ();
         Application.Current.EndInit ();
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == paddingSubView);
         Application.Current.Dispose ();
@@ -541,7 +541,7 @@ public class GetViewsUnderLocationTests
         Application.Current.BeginInit ();
         Application.Current.EndInit ();
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
 
         Assert.Equal (expectedSubViewFound, found == paddingSubView);
         Application.Current.Dispose ();
@@ -585,7 +585,7 @@ public class GetViewsUnderLocationTests
 
         Application.Current.Add (subviews [0]);
 
-        View? found = View.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
+        View? found = Application.Current.GetViewsUnderLocation (new (testX, testY), ViewportSettingsFlags.TransparentMouse).LastOrDefault ();
         Assert.Equal (expectedSubViewFound, subviews.IndexOf (found!));
         Application.Current.Dispose ();
         Application.ResetState (true);
@@ -632,7 +632,7 @@ public class GetViewsUnderLocationTests
         view.Add (subView);
         Application.Current.Add (view);
 
-        List<View?> found = View.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
 
         string [] foundIds = found.Select (v => v!.Id).ToArray ();
 
@@ -685,7 +685,7 @@ public class GetViewsUnderLocationTests
         view.Add (popOver);
         Application.Current.Add (view);
 
-        List<View?> found = View.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
 
         string [] foundIds = found.Select (v => v!.Id).ToArray ();
 
@@ -719,7 +719,7 @@ public class GetViewsUnderLocationTests
         Application.SessionStack.Push (secondaryToplevel);
         Application.Current = secondaryToplevel;
 
-        List<View?> found = View.GetViewsUnderLocation (new (2, 2), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (2, 2), ViewportSettingsFlags.TransparentMouse);
         Assert.Contains (found, v => v?.Id == topToplevel.Id);
         Assert.Contains (found, v => v == topToplevel);
 
@@ -753,7 +753,7 @@ public class GetViewsUnderLocationTests
         Application.SessionStack.Push (secondaryToplevel);
         Application.Current = secondaryToplevel;
 
-        List<View?> found = View.GetViewsUnderLocation (new (7, 7), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (7, 7), ViewportSettingsFlags.TransparentMouse);
         Assert.Contains (found, v => v?.Id == secondaryToplevel.Id);
         Assert.DoesNotContain (found, v => v?.Id == topToplevel.Id);
 
@@ -788,13 +788,13 @@ public class GetViewsUnderLocationTests
 
         secondaryToplevel.Margin!.ViewportSettings = ViewportSettingsFlags.None;
 
-        List<View?> found = View.GetViewsUnderLocation (new (5, 5), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (5, 5), ViewportSettingsFlags.TransparentMouse);
         Assert.Contains (found, v => v == secondaryToplevel);
         Assert.Contains (found, v => v == secondaryToplevel.Margin);
         Assert.DoesNotContain (found, v => v?.Id == topToplevel.Id);
 
         secondaryToplevel.Margin!.ViewportSettings = ViewportSettingsFlags.TransparentMouse;
-        found = View.GetViewsUnderLocation (new (5, 5), ViewportSettingsFlags.TransparentMouse);
+        found = Application.Current.GetViewsUnderLocation (new (5, 5), ViewportSettingsFlags.TransparentMouse);
         Assert.DoesNotContain (found, v => v == secondaryToplevel);
         Assert.DoesNotContain (found, v => v == secondaryToplevel.Margin);
         Assert.Contains (found, v => v?.Id == topToplevel.Id);
@@ -829,7 +829,7 @@ public class GetViewsUnderLocationTests
         Application.SessionStack.Push (secondaryToplevel);
         Application.Current = secondaryToplevel;
 
-        List<View?> found = View.GetViewsUnderLocation (new (20, 20), ViewportSettingsFlags.TransparentMouse);
+        List<View?> found = Application.Current.GetViewsUnderLocation (new (20, 20), ViewportSettingsFlags.TransparentMouse);
         Assert.Empty (found);
 
         topToplevel.Dispose ();

+ 1 - 1
Tests/UnitTests/View/Layout/Pos.CombineTests.cs

@@ -68,7 +68,7 @@ public class PosCombineTests (ITestOutputHelper output)
         Assert.Equal (new Rectangle (0, 2, 10, 3), win2.Frame);
         Assert.Equal (new Rectangle (0, 0, 8, 1), view2.Frame);
         Assert.Equal (new Rectangle (0, 0, 7, 1), view3.Frame);
-        var foundView = View.GetViewsUnderLocation (new Point(9, 4), ViewportSettingsFlags.None).LastOrDefault ();
+        var foundView = Application.Current.GetViewsUnderLocation (new Point(9, 4), ViewportSettingsFlags.None).LastOrDefault ();
         Assert.Equal (foundView, view2);
         Application.Current.Dispose ();
     }

+ 0 - 3
Tests/UnitTests/View/Navigation/NavigationTests.cs

@@ -28,7 +28,6 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
 
         Toplevel top = new ();
         Application.Current = top;
-        Application.Navigation = new ();
 
         View otherView = new ()
         {
@@ -119,7 +118,6 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
 
         Toplevel top = new ();
         Application.Current = top;
-        Application.Navigation = new ();
 
         View otherView = new ()
         {
@@ -283,7 +281,6 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
         Toplevel top = new ();
 
         Application.Current = top;
-        Application.Navigation = new ();
 
         View otherView = new ()
         {

+ 0 - 1
Tests/UnitTests/Views/CheckBoxTests.cs

@@ -15,7 +15,6 @@ public class CheckBoxTests (ITestOutputHelper output)
     [Fact]
     public void Commands_Select ()
     {
-        Application.Navigation = new ();
         Application.Current = new ();
         View otherView = new () { CanFocus = true };
         var ckb = new CheckBox ();

+ 0 - 2
Tests/UnitTests/Views/ColorPickerTests.cs

@@ -772,8 +772,6 @@ public class ColorPickerTests
         cp.Style.ShowColorName = showName;
         cp.ApplyStyleChanges ();
 
-        Application.Navigation = new ();
-
         Application.Current = new () { Width = 20, Height = 5 };
         Application.Current.Add (cp);
 

+ 0 - 1
Tests/UnitTests/Views/ComboBoxTests.cs

@@ -1013,7 +1013,6 @@ Three
     [Fact]
     public void Source_Equal_Null_Or_Count_Equal_Zero_Sets_SelectedItem_Equal_To_Minus_One ()
     {
-        Application.Navigation = new ();
         var cb = new ComboBox ();
         var top = new Toplevel ();
         Application.Current = top;

+ 13 - 21
Tests/UnitTests/Views/HexViewTests.cs

@@ -1,6 +1,5 @@
 #nullable enable
 using System.Text;
-using JetBrains.Annotations;
 
 namespace UnitTests.ViewsTests;
 
@@ -32,8 +31,8 @@ public class HexViewTests
     public void ReadOnly_Prevents_Edits ()
     {
         var hv = new HexView (LoadStream (null, out _, true)) { Width = 20, Height = 20 };
-        Application.Navigation = new ApplicationNavigation ();
-        Application.Current = new Toplevel ();
+
+        Application.Current = new ();
         Application.Current.Add (hv);
         Application.Current.SetFocus ();
 
@@ -77,8 +76,7 @@ public class HexViewTests
     [Fact]
     public void ApplyEdits_With_Argument ()
     {
-        Application.Navigation = new ApplicationNavigation ();
-        Application.Current = new Toplevel ();
+        Application.Current = new ();
 
         byte [] buffer = Encoding.Default.GetBytes ("Fest");
         var original = new MemoryStream ();
@@ -107,7 +105,7 @@ public class HexViewTests
         Assert.Equal ("Test", Encoding.Default.GetString (readBuffer));
 
         Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); // Move to right side
-        Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft)); 
+        Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft));
         Assert.True (Application.RaiseKeyDownEvent (Key.Z.WithShift));
         readBuffer [hv.Edits.ToList () [0].Key] = hv.Edits.ToList () [0].Value;
         Assert.Equal ("Zest", Encoding.Default.GetString (readBuffer));
@@ -144,10 +142,8 @@ public class HexViewTests
     [Fact]
     public void Position_Encoding_Default ()
     {
-        Application.Navigation = new ApplicationNavigation ();
-
         var hv = new HexView (LoadStream (null, out _)) { Width = 100, Height = 100 };
-        Application.Current = new Toplevel ();
+        Application.Current = new ();
         Application.Current.Add (hv);
 
         Application.Current.LayoutSubViews ();
@@ -182,10 +178,8 @@ public class HexViewTests
     [Fact]
     public void Position_Encoding_Unicode ()
     {
-        Application.Navigation = new ApplicationNavigation ();
-
-        var hv = new HexView (LoadStream (null, out _, unicode: true)) { Width = 100, Height = 100 };
-        Application.Current = new Toplevel ();
+        var hv = new HexView (LoadStream (null, out _, true)) { Width = 100, Height = 100 };
+        Application.Current = new ();
         Application.Current.Add (hv);
 
         hv.LayoutSubViews ();
@@ -264,8 +258,7 @@ public class HexViewTests
     [Fact]
     public void KeyBindings_Test_Movement_LeftSide ()
     {
-        Application.Navigation = new ApplicationNavigation ();
-        Application.Current = new Toplevel ();
+        Application.Current = new ();
         var hv = new HexView (LoadStream (null, out _)) { Width = 20, Height = 10 };
         Application.Current.Add (hv);
 
@@ -320,9 +313,8 @@ public class HexViewTests
     [Fact]
     public void PositionChanged_Event ()
     {
-        Application.Navigation = new ApplicationNavigation ();
         var hv = new HexView (LoadStream (null, out _)) { Width = 20, Height = 10 };
-        Application.Current = new Toplevel ();
+        Application.Current = new ();
         Application.Current.Add (hv);
 
         Application.Current.LayoutSubViews ();
@@ -346,9 +338,8 @@ public class HexViewTests
     [Fact]
     public void Source_Sets_Address_To_Zero_If_Greater_Than_Source_Length ()
     {
-        Application.Navigation = new ApplicationNavigation ();
         var hv = new HexView (LoadStream (null, out _)) { Width = 10, Height = 5 };
-        Application.Current = new Toplevel ();
+        Application.Current = new ();
         Application.Current.Add (hv);
 
         Application.Current.Layout ();
@@ -400,6 +391,7 @@ public class HexViewTests
         {
             bArray = Encoding.Default.GetBytes (memString);
         }
+
         numBytesInMemString = bArray.Length;
 
         stream.Write (bArray);
@@ -421,8 +413,8 @@ public class HexViewTests
         }
 
         public override void Flush () { baseStream.Flush (); }
-        public override int Read (byte [] buffer, int offset, int count) { return baseStream.Read (buffer, offset, count); }
-        public override long Seek (long offset, SeekOrigin origin) { throw new NotImplementedException (); }
+        public override int Read (byte [] buffer, int offset, int count) => baseStream.Read (buffer, offset, count);
+        public override long Seek (long offset, SeekOrigin origin) => throw new NotImplementedException ();
         public override void SetLength (long value) { throw new NotSupportedException (); }
         public override void Write (byte [] buffer, int offset, int count) { baseStream.Write (buffer, offset, count); }
     }

+ 24 - 10
Tests/UnitTests/Views/LabelTests.cs

@@ -111,9 +111,17 @@ public class LabelTests (ITestOutputHelper output)
 
         AutoInitShutdownAttribute.RunIteration ();
 
-        tf1.Draw (driver: Application.Driver, screen: new (new (0, 1), tfSize), normalColor: label.GetAttributeForRole (VisualRole.Normal), hotColor: label.GetAttributeForRole (VisualRole.HotNormal));
-
-        tf2.Draw (driver: Application.Driver, screen: new (new (0, 2), tfSize), normalColor: label.GetAttributeForRole (VisualRole.Normal), hotColor: label.GetAttributeForRole (VisualRole.HotNormal));
+        tf1.Draw (
+                  Application.Driver,
+                  new (new (0, 1), tfSize),
+                  label.GetAttributeForRole (VisualRole.Normal),
+                  label.GetAttributeForRole (VisualRole.HotNormal));
+
+        tf2.Draw (
+                  Application.Driver,
+                  new (new (0, 2), tfSize),
+                  label.GetAttributeForRole (VisualRole.Normal),
+                  label.GetAttributeForRole (VisualRole.HotNormal));
 
         DriverAssert.AssertDriverContentsWithFrameAre (
                                                        @"
@@ -135,11 +143,19 @@ This TextFormatter (tf2) with fill will be cleared on rewritten.       ",
 
         tf1.Text = "This TextFormatter (tf1) is rewritten.";
 
-        tf1.Draw (driver: Application.Driver, screen: new (new (0, 1), tfSize), normalColor: label.GetAttributeForRole (VisualRole.Normal), hotColor: label.GetAttributeForRole (VisualRole.HotNormal));
+        tf1.Draw (
+                  Application.Driver,
+                  new (new (0, 1), tfSize),
+                  label.GetAttributeForRole (VisualRole.Normal),
+                  label.GetAttributeForRole (VisualRole.HotNormal));
 
         tf2.Text = "This TextFormatter (tf2) is rewritten.";
 
-        tf2.Draw (driver: Application.Driver, screen: new (new (0, 2), tfSize), normalColor: label.GetAttributeForRole (VisualRole.Normal), hotColor: label.GetAttributeForRole (VisualRole.HotNormal));
+        tf2.Draw (
+                  Application.Driver,
+                  new (new (0, 2), tfSize),
+                  label.GetAttributeForRole (VisualRole.Normal),
+                  label.GetAttributeForRole (VisualRole.HotNormal));
 
         DriverAssert.AssertDriverContentsWithFrameAre (
                                                        @"
@@ -916,6 +932,7 @@ e
 
         var win = new View
         {
+            App = ApplicationImpl.Instance,
             CanFocus = true, BorderStyle = LineStyle.Single, Width = Dim.Fill (), Height = Dim.Fill ()
         };
         win.Add (label);
@@ -1212,7 +1229,7 @@ e
             Text = "nextView",
             CanFocus = true
         };
-        Application.Navigation = new ();
+
         Application.Current = new ();
         Application.Current.Add (otherView, label, nextView);
 
@@ -1234,7 +1251,6 @@ e
         View otherView = new () { X = 0, Y = 0, Width = 1, Height = 1, Id = "otherView", CanFocus = true };
         Label label = new () { X = 0, Y = 1, Text = "_label" };
         View nextView = new () { X = Pos.Right (label), Y = Pos.Top (label), Width = 1, Height = 1, Id = "nextView", CanFocus = true };
-        Application.Navigation = new ();
         Application.Current = new ();
         Application.Current.Add (otherView, label, nextView);
         Application.Current.Layout ();
@@ -1264,7 +1280,7 @@ e
             Text = "view",
             CanFocus = true
         };
-        Application.Navigation = new ();
+
         Application.Current = new ();
         Application.Current.Add (label, view);
 
@@ -1286,8 +1302,6 @@ e
     [Fact]
     public void CanFocus_True_MouseClick_Focuses ()
     {
-        Application.Navigation = new ();
-
         Label label = new ()
         {
             Text = "label",

+ 28 - 32
Tests/UnitTests/Views/MenuBarTests.cs

@@ -10,18 +10,33 @@ public class MenuBarTests ()
     public void DefaultKey_Activates_And_Opens ()
     {
         // Arrange
+        var top = new Toplevel ()
+        {
+            App = ApplicationImpl.Instance
+        };
+
+        var menuBar = new MenuBarv2 () { Id = "menuBar" };
+        top.Add (menuBar);
+
         var menuItem = new MenuItemv2 { Id = "menuItem", Title = "_Item" };
         var menu = new Menuv2 ([menuItem]) { Id = "menu" };
         var menuBarItem = new MenuBarItemv2 { Id = "menuBarItem", Title = "_New" };
         var menuBarItemPopover = new PopoverMenu ();
+
+        menuBar.Add (menuBarItem);
         menuBarItem.PopoverMenu = menuBarItemPopover;
         menuBarItemPopover.Root = menu;
-        var menuBar = new MenuBarv2 () { Id = "menuBar" };
-        menuBar.Add (menuBarItem);
+
+
+        Assert.NotNull (menuBar.App);
+        Assert.NotNull (menu.App);
+        Assert.NotNull (menuItem.App);
+        Assert.NotNull (menuBarItem);
+        Assert.NotNull (menuBarItemPopover);
+
         Assert.Single (menuBar.SubViews);
         Assert.Single (menuBarItem.SubViews);
-        var top = new Toplevel ();
-        top.Add (menuBar);
+
         SessionToken rs = Application.Begin (top);
         Assert.False (menuBar.Active);
 
@@ -43,17 +58,10 @@ public class MenuBarTests ()
     public void DefaultKey_Deactivates ()
     {
         // Arrange
-        var menuItem = new MenuItemv2 { Id = "menuItem", Title = "_Item" };
-        var menu = new Menuv2 ([menuItem]) { Id = "menu" };
-        var menuBarItem = new MenuBarItemv2 { Id = "menuBarItem", Title = "_New" };
-        var menuBarItemPopover = new PopoverMenu ();
-        menuBarItem.PopoverMenu = menuBarItemPopover;
-        menuBarItemPopover.Root = menu;
-        var menuBar = new MenuBarv2 () { Id = "menuBar" };
-        menuBar.Add (menuBarItem);
-        Assert.Single (menuBar.SubViews);
-        Assert.Single (menuBarItem.SubViews);
-        var top = new Toplevel ();
+        var top = new Toplevel () { App = ApplicationImpl.Instance };
+        MenuBarv2 menuBar = new MenuBarv2 () { App = ApplicationImpl.Instance };
+        menuBar.EnableForDesign (ref top);
+
         top.Add (menuBar);
         SessionToken rs = Application.Begin (top);
         Assert.False (menuBar.Active);
@@ -61,15 +69,12 @@ public class MenuBarTests ()
         // Act
         Application.RaiseKeyDownEvent (MenuBarv2.DefaultKey);
         Assert.True (menuBar.IsOpen ());
-        Assert.True (menuBarItem.PopoverMenu.Visible);
 
         Application.RaiseKeyDownEvent (MenuBarv2.DefaultKey);
         Assert.False (menuBar.Active);
         Assert.False (menuBar.IsOpen ());
         Assert.False (menuBar.HasFocus);
         Assert.False (menuBar.CanFocus);
-        Assert.False (menuBarItem.PopoverMenu.Visible);
-        Assert.False (menuBarItem.PopoverMenu.HasFocus);
 
         Application.End (rs);
         top.Dispose ();
@@ -377,17 +382,10 @@ public class MenuBarTests ()
     public void Mouse_Click_Activates_And_Opens ()
     {
         // Arrange
-        var menuItem = new MenuItemv2 { Id = "menuItem", Title = "_Item" };
-        var menu = new Menuv2 ([menuItem]) { Id = "menu" };
-        var menuBarItem = new MenuBarItemv2 { Id = "menuBarItem", Title = "_New" };
-        var menuBarItemPopover = new PopoverMenu ();
-        menuBarItem.PopoverMenu = menuBarItemPopover;
-        menuBarItemPopover.Root = menu;
-        var menuBar = new MenuBarv2 () { Id = "menuBar" };
-        menuBar.Add (menuBarItem);
-        Assert.Single (menuBar.SubViews);
-        Assert.Single (menuBarItem.SubViews);
-        var top = new Toplevel ();
+        var top = new Toplevel () { App = ApplicationImpl.Instance };
+        MenuBarv2 menuBar = new MenuBarv2 () { App = ApplicationImpl.Instance };
+        menuBar.EnableForDesign (ref top);
+
         top.Add (menuBar);
         SessionToken rs = Application.Begin (top);
         Assert.False (menuBar.Active);
@@ -401,8 +399,6 @@ public class MenuBarTests ()
         Assert.True (menuBar.IsOpen ());
         Assert.True (menuBar.HasFocus);
         Assert.True (menuBar.CanFocus);
-        Assert.True (menuBarItem.PopoverMenu.Visible);
-        Assert.True (menuBarItem.PopoverMenu.HasFocus);
 
         Application.End (rs);
         top.Dispose ();
@@ -483,7 +479,7 @@ public class MenuBarTests ()
         Application.RaiseKeyDownEvent (Key.N.WithAlt);
         Assert.Equal (0, action);
 
-        Assert.Equal(Key.I, menuItem.HotKey);
+        Assert.Equal (Key.I, menuItem.HotKey);
         Application.RaiseKeyDownEvent (Key.I);
         Assert.Equal (1, action);
         Assert.False (menuBar.Active);

+ 9 - 4
Tests/UnitTests/Views/ShortcutTests.cs

@@ -349,16 +349,16 @@ public class ShortcutTests
     [InlineData (KeyCode.F1, 0)]
     public void KeyDown_App_Scope_Invokes_Accept (KeyCode key, int expectedAccept)
     {
-        Application.Current = new ();
+        Application.Current = new () { App = new ApplicationImpl () };
 
         var shortcut = new Shortcut
         {
             Key = Key.A,
-            BindKeyToApplication = true,
             Text = "0",
             Title = "_C"
         };
         Application.Current.Add (shortcut);
+        shortcut.BindKeyToApplication = true;
         Application.Current.SetFocus ();
 
         var accepted = 0;
@@ -431,14 +431,19 @@ public class ShortcutTests
 
         var shortcut = new Shortcut
         {
-            Key = Key.A,
             BindKeyToApplication = true,
+            Key = Key.A,
             Text = "0",
             Title = "_C",
             CanFocus = canFocus
         };
 
         Application.Current.Add (shortcut);
+
+        // Shortcut requires Init for App scoped hotkeys to work
+        Application.Current.BeginInit ();
+        Application.Current.EndInit();
+
         Application.Current.SetFocus ();
 
         var action = 0;
@@ -457,7 +462,7 @@ public class ShortcutTests
     public void Scheme_SetScheme_Does_Not_Fault_3664 ()
     {
         Application.Current = new ();
-        Application.Navigation = new ();
+
         var shortcut = new Shortcut ();
 
         Application.Current.SetScheme (null);

+ 1 - 1
Tests/UnitTests/Views/TableViewTests.cs

@@ -3397,7 +3397,7 @@ A B C
         tableView.BeginInit ();
         tableView.EndInit ();
 
-        Application.Navigation = new ();
+
         Application.Current = new ();
         tf1 = new ();
         tf2 = new ();

+ 10 - 0
Tests/UnitTestsParallelizable/Application/ApplicationPopoverTests.cs

@@ -1,5 +1,6 @@
 #nullable enable
 using Moq;
+using Terminal.Gui.App;
 
 namespace UnitTests_Parallelizable.ApplicationTests;
 
@@ -42,6 +43,7 @@ public class ApplicationPopoverTests
         // Arrange
         var popover = new Mock<PopoverTestClass> ().Object;
         var popoverManager = new ApplicationPopover ();
+        popoverManager.Register (popover);
 
         // Act
         popoverManager.Show (popover);
@@ -56,6 +58,7 @@ public class ApplicationPopoverTests
         // Arrange
         var popover = new Mock<IPopover> ().Object;
         var popoverManager = new ApplicationPopover ();
+        popoverManager.Register (popover);
         popoverManager.Show (popover);
 
         // Act
@@ -72,6 +75,8 @@ public class ApplicationPopoverTests
         // Arrange
         var popover = new PopoverTestClass ();
         var popoverManager = new ApplicationPopover ();
+        popoverManager.Register (popover);
+
         popoverManager.Show (popover);
 
         // Act
@@ -88,6 +93,7 @@ public class ApplicationPopoverTests
         // Arrange
         var popover = new PopoverTestClass ();
         var popoverManager = new ApplicationPopover ();
+        popoverManager.Register (popover);
         popoverManager.Show (popover);
 
         // Act
@@ -106,6 +112,8 @@ public class ApplicationPopoverTests
         var activePopover = new PopoverTestClass () { Id = "activePopover" };
         var inactivePopover = new PopoverTestClass () { Id = "inactivePopover" }; ;
         var popoverManager = new ApplicationPopover ();
+
+        popoverManager.Register (activePopover);
         popoverManager.Show (activePopover);
         popoverManager.Register (inactivePopover);
 
@@ -126,6 +134,8 @@ public class ApplicationPopoverTests
         var activePopover = new PopoverTestClass ();
         var inactivePopover = new PopoverTestClass ();
         var popoverManager = new ApplicationPopover ();
+        popoverManager.Register (activePopover);
+
         popoverManager.Show (activePopover);
         popoverManager.Register (inactivePopover);
 

+ 2 - 2
Tests/UnitTestsParallelizable/Application/PopoverBaseImplTests.cs

@@ -59,11 +59,11 @@ public class PopoverBaseImplTests
     }
 
     [Fact]
-    public void Show_DoesNotThrow_BasePopoverImpl ()
+    public void Show_Throw_If_Not_Registered ()
     {
         var popover = new TestPopover ();
 
         var popoverManager = new ApplicationPopover ();
-        popoverManager.Show (popover);
+        Assert.Throws<InvalidOperationException> (() => popoverManager.Show (popover));
     }
 }

+ 1 - 1
Tests/UnitTestsParallelizable/TestSetup.cs

@@ -70,7 +70,7 @@ public class GlobalTestSetup : IDisposable
         // Assert.Null (Application.Navigation);
 
         // Popover
-        Assert.Null (Application.Popover);
+        //Assert.Null (Application.Popover);
 
         // Events - Can't check
         //Assert.Null (Application.SessionBegun);

+ 2 - 2
Tests/UnitTestsParallelizable/View/Layout/GetViewsUnderLocationTests.cs

@@ -20,7 +20,7 @@ public class GetViewsUnderLocationTests
         var location = new Point (testX, testY);
 
         // Act
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (location, ViewportSettingsFlags.None);
+        List<View?> viewsUnderMouse = view.GetViewsUnderLocation (location, ViewportSettingsFlags.None);
 
         // Assert
         Assert.Empty (viewsUnderMouse);
@@ -42,7 +42,7 @@ public class GetViewsUnderLocationTests
         var location = new Point (testX, testY);
 
         // Act
-        List<View?> viewsUnderMouse = View.GetViewsUnderLocation (location, ViewportSettingsFlags.None);
+        List<View?> viewsUnderMouse = view.GetViewsUnderLocation (location, ViewportSettingsFlags.None);
 
         // Assert
         Assert.Empty (viewsUnderMouse);

+ 8 - 5
Tests/UnitTestsParallelizable/Views/ShortcutTests.cs

@@ -108,7 +108,7 @@ public class ShortcutTests
         // | C  H  K |
         Assert.Equal (expectedWidth, shortcut.Frame.Width);
 
-        shortcut = new()
+        shortcut = new ()
         {
             HelpText = help,
             Title = command,
@@ -118,7 +118,7 @@ public class ShortcutTests
         shortcut.Layout ();
         Assert.Equal (expectedWidth, shortcut.Frame.Width);
 
-        shortcut = new()
+        shortcut = new ()
         {
             HelpText = help,
             Key = key,
@@ -128,7 +128,7 @@ public class ShortcutTests
         shortcut.Layout ();
         Assert.Equal (expectedWidth, shortcut.Frame.Width);
 
-        shortcut = new()
+        shortcut = new ()
         {
             Key = key,
             HelpText = help,
@@ -314,13 +314,16 @@ public class ShortcutTests
         shortcut.Key = Key.A;
         Assert.True (shortcut.HotKeyBindings.TryGet (Key.A, out _));
 
+        shortcut.App = new ApplicationImpl ();
         shortcut.BindKeyToApplication = true;
+        shortcut.BeginInit ();
+        shortcut.EndInit ();
         Assert.False (shortcut.HotKeyBindings.TryGet (Key.A, out _));
-        Assert.True (Application.KeyBindings.TryGet (Key.A, out _));
+        Assert.True (shortcut.App?.Keyboard.KeyBindings.TryGet (Key.A, out _));
 
         shortcut.BindKeyToApplication = false;
         Assert.True (shortcut.HotKeyBindings.TryGet (Key.A, out _));
-        Assert.False (Application.KeyBindings.TryGet (Key.A, out _));
+        Assert.False (shortcut.App?.Keyboard.KeyBindings.TryGet (Key.A, out _));
     }
 
     [Theory]