Browse Source

Merge branch 'v2_develop' into copilot/fix-3ee850b1-eb6b-46b0-964b-3b98d2c0c14e

Tig 3 weeks ago
parent
commit
4613452166
100 changed files with 1335 additions and 747 deletions
  1. 5 0
      .config/dotnet-tools.json
  2. 1 1
      Examples/CommunityToolkitExample/Program.cs
  3. 1 1
      Examples/ReactiveExample/Program.cs
  4. 1 1
      Examples/ReactiveExample/TerminalScheduler.cs
  5. 2 3
      Examples/UICatalog/Resources/config.json
  6. 2 2
      Examples/UICatalog/Scenario.cs
  7. 2 2
      Examples/UICatalog/Scenarios/AllViewsTester.cs
  8. 1 1
      Examples/UICatalog/Scenarios/AnimationScenario/AnimationScenario.cs
  9. 61 58
      Examples/UICatalog/Scenarios/AnsiRequestsScenario.cs
  10. 8 8
      Examples/UICatalog/Scenarios/Bars.cs
  11. 3 3
      Examples/UICatalog/Scenarios/CombiningMarks.cs
  12. 2 2
      Examples/UICatalog/Scenarios/ComboBoxIteration.cs
  13. 1 1
      Examples/UICatalog/Scenarios/ConfigurationEditor.cs
  14. 56 52
      Examples/UICatalog/Scenarios/ContextMenus.cs
  15. 1 1
      Examples/UICatalog/Scenarios/CsvEditor.cs
  16. 12 12
      Examples/UICatalog/Scenarios/DynamicMenuBar.cs
  17. 21 8
      Examples/UICatalog/Scenarios/DynamicStatusBar.cs
  18. 1 1
      Examples/UICatalog/Scenarios/Images.cs
  19. 4 4
      Examples/UICatalog/Scenarios/ListViewWithSelection.cs
  20. 1 1
      Examples/UICatalog/Scenarios/ListsAndCombos.cs
  21. 3 3
      Examples/UICatalog/Scenarios/Mazing.cs
  22. 1 1
      Examples/UICatalog/Scenarios/Menus.cs
  23. 1 1
      Examples/UICatalog/Scenarios/Navigation.cs
  24. 1 1
      Examples/UICatalog/Scenarios/Notepad.cs
  25. 1 1
      Examples/UICatalog/Scenarios/Progress.cs
  26. 19 19
      Examples/UICatalog/Scenarios/RegionScenario.cs
  27. 27 27
      Examples/UICatalog/Scenarios/Shortcuts.cs
  28. 2 2
      Examples/UICatalog/Scenarios/SingleBackgroundWorker.cs
  29. 1 1
      Examples/UICatalog/Scenarios/SpinnerStyles.cs
  30. 1 1
      Examples/UICatalog/Scenarios/TableEditor.cs
  31. 4 4
      Examples/UICatalog/Scenarios/Themes.cs
  32. 6 6
      Examples/UICatalog/Scenarios/TreeUseCases.cs
  33. 1 1
      Examples/UICatalog/Scenarios/TreeViewFileSystem.cs
  34. 5 5
      Examples/UICatalog/Scenarios/ViewExperiments.cs
  35. 1 1
      Examples/UICatalog/Scenarios/WindowsAndFrameViews.cs
  36. 15 6
      Examples/UICatalog/UICatalog.cs
  37. 1 0
      Examples/UICatalog/UICatalog.csproj
  38. 13 4
      Examples/UICatalog/UICatalogTop.cs
  39. 163 0
      NULLABLE_VIEWS_REMAINING.md
  40. 322 0
      PR_DESCRIPTION_UPDATED.md
  41. 1 1
      Scripts/Run-LocalCoverage.ps1
  42. 18 0
      Terminal.Gui/App/Application.Current.cs
  43. 6 2
      Terminal.Gui/App/Application.Driver.cs
  44. 5 12
      Terminal.Gui/App/Application.Keyboard.cs
  45. 20 46
      Terminal.Gui/App/Application.Lifecycle.cs
  46. 7 11
      Terminal.Gui/App/Application.Mouse.cs
  47. 3 2
      Terminal.Gui/App/Application.Navigation.cs
  48. 2 2
      Terminal.Gui/App/Application.Popover.cs
  49. 25 8
      Terminal.Gui/App/Application.Run.cs
  50. 3 1
      Terminal.Gui/App/Application.Screen.cs
  51. 0 18
      Terminal.Gui/App/Application.Toplevel.cs
  52. 11 78
      Terminal.Gui/App/Application.cs
  53. 1 2
      Terminal.Gui/App/ApplicationImpl.Driver.cs
  54. 18 18
      Terminal.Gui/App/ApplicationImpl.Lifecycle.cs
  55. 78 53
      Terminal.Gui/App/ApplicationImpl.Run.cs
  56. 15 8
      Terminal.Gui/App/ApplicationImpl.Screen.cs
  57. 64 21
      Terminal.Gui/App/ApplicationImpl.cs
  58. 7 3
      Terminal.Gui/App/ApplicationNavigation.cs
  59. 32 13
      Terminal.Gui/App/ApplicationPopover.cs
  60. 1 2
      Terminal.Gui/App/CWP/CWPEventHelper.cs
  61. 0 2
      Terminal.Gui/App/CWP/CWPPropertyHelper.cs
  62. 1 2
      Terminal.Gui/App/CWP/CWPWorkflowHelper.cs
  63. 0 1
      Terminal.Gui/App/CWP/CancelEventArgs.cs
  64. 0 1
      Terminal.Gui/App/CWP/EventArgs.cs
  65. 1 2
      Terminal.Gui/App/CWP/ResultEventArgs.cs
  66. 0 1
      Terminal.Gui/App/CWP/ValueChangedEventArgs.cs
  67. 1 2
      Terminal.Gui/App/CWP/ValueChangingEventArgs.cs
  68. 2 3
      Terminal.Gui/App/Clipboard/Clipboard.cs
  69. 1 0
      Terminal.Gui/App/Clipboard/ClipboardBase.cs
  70. 0 2
      Terminal.Gui/App/Clipboard/ClipboardProcessRunner.cs
  71. 37 23
      Terminal.Gui/App/IApplication.cs
  72. 5 6
      Terminal.Gui/App/IPopover.cs
  73. 2 3
      Terminal.Gui/App/Keyboard/IKeyboard.cs
  74. 18 21
      Terminal.Gui/App/Keyboard/KeyboardImpl.cs
  75. 19 16
      Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs
  76. 8 2
      Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs
  77. 2 1
      Terminal.Gui/App/MainLoop/IMainLoopCoordinator.cs
  78. 18 16
      Terminal.Gui/App/MainLoop/MainLoopCoordinator.cs
  79. 37 36
      Terminal.Gui/App/MainLoop/MainLoopSyncContext.cs
  80. 2 8
      Terminal.Gui/App/Mouse/IMouse.cs
  81. 0 1
      Terminal.Gui/App/Mouse/IMouseGrabHandler.cs
  82. 0 1
      Terminal.Gui/App/Mouse/MouseGrabHandler.cs
  83. 12 14
      Terminal.Gui/App/Mouse/MouseImpl.cs
  84. 17 5
      Terminal.Gui/App/PopoverBaseImpl.cs
  85. 1 1
      Terminal.Gui/App/SessionToken.cs
  86. 10 1
      Terminal.Gui/App/Timeout/ITimedEvents.cs
  87. 1 0
      Terminal.Gui/App/Timeout/LogarithmicTimeout.cs
  88. 1 0
      Terminal.Gui/App/Timeout/SmoothAcceleratingTimeout.cs
  89. 26 2
      Terminal.Gui/App/Timeout/TimedEvents.cs
  90. 1 1
      Terminal.Gui/App/Timeout/Timeout.cs
  91. 5 3
      Terminal.Gui/App/Toplevel/IToplevelTransitionManager.cs
  92. 7 8
      Terminal.Gui/App/Toplevel/ToplevelTransitionManager.cs
  93. 1 2
      Terminal.Gui/Configuration/AppSettingsScope.cs
  94. 2 2
      Terminal.Gui/Configuration/AttributeJsonConverter.cs
  95. 1 1
      Terminal.Gui/Configuration/ColorJsonConverter.cs
  96. 1 0
      Terminal.Gui/Configuration/ConcurrentDictionaryJsonConverter.cs
  97. 1 2
      Terminal.Gui/Configuration/ConfigLocations.cs
  98. 1 2
      Terminal.Gui/Configuration/ConfigProperty.cs
  99. 1 3
      Terminal.Gui/Configuration/ConfigurationManager.cs
  100. 1 3
      Terminal.Gui/Configuration/ConfigurationManagerEventArgs.cs

+ 5 - 0
.config/dotnet-tools.json

@@ -0,0 +1,5 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {}
+}

+ 1 - 1
Examples/CommunityToolkitExample/Program.cs

@@ -16,7 +16,7 @@ public static class Program
         Services = ConfigureServices ();
         Application.Init ();
         Application.Run (Services.GetRequiredService<LoginView> ());
-        Application.Top?.Dispose ();
+        Application.Current?.Dispose ();
         Application.Shutdown ();
     }
 

+ 1 - 1
Examples/ReactiveExample/Program.cs

@@ -16,7 +16,7 @@ public static class Program
         RxApp.MainThreadScheduler = TerminalScheduler.Default;
         RxApp.TaskpoolScheduler = TaskPoolScheduler.Default;
         Application.Run (new LoginView (new LoginViewModel ()));
-        Application.Top.Dispose ();
+        Application.Current.Dispose ();
         Application.Shutdown ();
     }
 }

+ 1 - 1
Examples/ReactiveExample/TerminalScheduler.cs

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

+ 2 - 3
Examples/UICatalog/Resources/config.json

@@ -86,7 +86,7 @@
             "Menu": {
               "Normal": {
                 "Foreground": "Black",
-                "Background": "WHite"
+                "Background": "White"
               },
               "Focus": {
                 "Foreground": "White",
@@ -136,17 +136,16 @@
     {
       "UI Catalog Theme": {
         "Window.DefaultShadow": "Transparent",
+        "Button.DefaultShadow": "None",
         "CheckBox.DefaultHighlightStates": "In, Pressed, PressedOutside",
         "MessageBox.DefaultButtonAlignment": "Start",
         "StatusBar.DefaultSeparatorLineStyle": "Single",
         "Dialog.DefaultMinimumWidth": 80,
-        "MessageBox.DefaultBorderStyle": "Dotted",
         "NerdFonts.Enable": false,
         "MessageBox.DefaultMinimumWidth": 0,
         "Window.DefaultBorderStyle": "Double",
         "Dialog.DefaultShadow": "Opaque",
         "Dialog.DefaultButtonAlignment": "Start",
-        "Button.DefaultShadow": "Transparent",
         "FrameView.DefaultBorderStyle": "Double",
         "MessageBox.DefaultMinimumHeight": 0,
         "Button.DefaultHighlightStates": "In, Pressed",

+ 2 - 2
Examples/UICatalog/Scenario.cs

@@ -221,7 +221,7 @@ public class Scenario : IDisposable
 
     private void OnApplicationSessionBegun (object? sender, SessionTokenEventArgs e)
     {
-        SubscribeAllSubViews (Application.Top!);
+        SubscribeAllSubViews (Application.Current!);
 
         _demoKeys = GetDemoKeyStrokes ();
 
@@ -241,7 +241,7 @@ public class Scenario : IDisposable
 
         return;
 
-        // Get a list of all subviews under Application.Top (and their subviews, etc.)
+        // Get a list of all subviews under Application.Current (and their subviews, etc.)
         // and subscribe to their DrawComplete event
         void SubscribeAllSubViews (View view)
         {

+ 2 - 2
Examples/UICatalog/Scenarios/AllViewsTester.cs

@@ -28,7 +28,7 @@ public class AllViewsTester : Scenario
 
     public override void Main ()
     {
-        // Don't create a sub-win (Scenario.Win); just use Application.Top
+        // Don't create a sub-win (Scenario.Win); just use Application.Current
         Application.Init ();
 
         var app = new Window
@@ -65,7 +65,7 @@ public class AllViewsTester : Scenario
                                                   // Dispose existing current View, if any
                                                   DisposeCurrentView ();
 
-                                                  CreateCurrentView (_viewClasses.Values.ToArray () [_classListView.SelectedItem]);
+                                                  CreateCurrentView (_viewClasses.Values.ToArray () [_classListView.SelectedItem.Value]);
 
                                                   // Force ViewToEdit to be the view and not a subview
                                                   if (_adornmentsEditor is { })

+ 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 ();

+ 61 - 58
Examples/UICatalog/Scenarios/AnsiRequestsScenario.cs

@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+#nullable enable
 using System.Text;
 
 namespace UICatalog.Scenarios;
@@ -9,16 +7,19 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Tests")]
 public sealed class AnsiEscapeSequenceRequests : Scenario
 {
-    private GraphView _graphView;
+    private GraphView? _graphView;
 
-    private ScatterSeries _sentSeries;
-    private ScatterSeries _answeredSeries;
+    private ScatterSeries? _sentSeries;
+    private ScatterSeries? _answeredSeries;
 
     private readonly List<DateTime> _sends = new ();
 
     private readonly object _lockAnswers = new object ();
     private readonly Dictionary<DateTime, string> _answers = new ();
-    private Label _lblSummary;
+    private Label? _lblSummary;
+
+    private object? _updateTimeoutToken;
+    private object? _sendDarTimeoutToken;
 
     public override void Main ()
     {
@@ -32,7 +33,7 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
             CanFocus = true
         };
 
-        Tab single = new Tab ();
+        Tab single = new ();
         single.DisplayText = "Single";
         single.View = BuildSingleTab ();
 
@@ -57,6 +58,8 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
         single.View.Dispose ();
         appWindow.Dispose ();
 
+        Application.RemoveTimeout (_updateTimeoutToken!);
+        Application.RemoveTimeout (_sendDarTimeoutToken!);
         // Shutdown - Calling Application.Shutdown is required.
         Application.Shutdown ();
     }
@@ -70,7 +73,7 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
             CanFocus = true
         };
 
-        w.Padding.Thickness = new (1);
+        w!.Padding!.Thickness = new (1);
 
         var scrRequests = new List<string>
         {
@@ -103,7 +106,7 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
                                               }
 
                                               var selAnsiEscapeSequenceRequestName = scrRequests [cbRequests.SelectedItem];
-                                              AnsiEscapeSequence selAnsiEscapeSequenceRequest = null;
+                                              AnsiEscapeSequence? selAnsiEscapeSequenceRequest = null;
 
                                               switch (selAnsiEscapeSequenceRequestName)
                                               {
@@ -163,12 +166,12 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
                                          Value = string.IsNullOrEmpty (tfValue.Text) ? null : tfValue.Text
                                      };
 
-                                     Application.Driver.QueueAnsiRequest (
+                                     Application.Driver?.QueueAnsiRequest (
                                                                           new ()
                                                                           {
                                                                               Request = ansiEscapeSequenceRequest.Request,
                                                                               Terminator = ansiEscapeSequenceRequest.Terminator,
-                                                                              ResponseReceived = (s) => OnSuccess (s, tvResponse, tvError, tvValue, tvTerminator, lblSuccess),
+                                                                              ResponseReceived = (s) => OnSuccess (s!, tvResponse, tvError, tvValue, tvTerminator, lblSuccess),
                                                                               Abandoned = () => OnFail (tvResponse, tvError, tvValue, tvTerminator, lblSuccess)
                                                                           });
                                  };
@@ -218,21 +221,21 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
             Width = Dim.Fill ()
         };
 
-        Application.AddTimeout (
-                                TimeSpan.FromMilliseconds (1000),
-                                () =>
-                                {
-                                    lock (_lockAnswers)
-                                    {
-                                        UpdateGraph ();
+        _updateTimeoutToken = Application.AddTimeout (
+                                                      TimeSpan.FromMilliseconds (1000),
+                                                      () =>
+                                                      {
+                                                          lock (_lockAnswers)
+                                                          {
+                                                              UpdateGraph ();
 
-                                        UpdateResponses ();
-                                    }
+                                                              UpdateResponses ();
+                                                          }
 
 
 
-                                    return true;
-                                });
+                                                          return true;
+                                                      });
 
         var tv = new TextView ()
         {
@@ -266,28 +269,28 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
 
         int lastSendTime = Environment.TickCount;
         object lockObj = new object ();
-        Application.AddTimeout (
-                                TimeSpan.FromMilliseconds (50),
-                                () =>
-                                {
-                                    lock (lockObj)
-                                    {
-                                        if (cbDar.Value > 0)
-                                        {
-                                            int interval = 1000 / cbDar.Value; // Calculate the desired interval in milliseconds
-                                            int currentTime = Environment.TickCount; // Current system time in milliseconds
-
-                                            // Check if the time elapsed since the last send is greater than the interval
-                                            if (currentTime - lastSendTime >= interval)
-                                            {
-                                                SendDar (); // Send the request
-                                                lastSendTime = currentTime; // Update the last send time
-                                            }
-                                        }
-                                    }
-
-                                    return true;
-                                });
+        _sendDarTimeoutToken = Application.AddTimeout (
+                                                          TimeSpan.FromMilliseconds (50),
+                                                          () =>
+                                                          {
+                                                              lock (lockObj)
+                                                              {
+                                                                  if (cbDar.Value > 0)
+                                                                  {
+                                                                      int interval = 1000 / cbDar.Value; // Calculate the desired interval in milliseconds
+                                                                      int currentTime = Environment.TickCount; // Current system time in milliseconds
+
+                                                                      // Check if the time elapsed since the last send is greater than the interval
+                                                                      if (currentTime - lastSendTime >= interval)
+                                                                      {
+                                                                          SendDar (); // Send the request
+                                                                          lastSendTime = currentTime; // Update the last send time
+                                                                      }
+                                                                  }
+                                                              }
+
+                                                              return true;
+                                                          });
 
 
         _graphView = new GraphView ()
@@ -318,7 +321,7 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
     }
     private void UpdateResponses ()
     {
-        _lblSummary.Text = GetSummary ();
+        _lblSummary!.Text = GetSummary ();
         _lblSummary.SetNeedsDraw ();
     }
 
@@ -340,8 +343,8 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
     private void SetupGraph ()
     {
 
-        _graphView.Series.Add (_sentSeries = new ScatterSeries ());
-        _graphView.Series.Add (_answeredSeries = new ScatterSeries ());
+        _graphView!.Series.Add (_sentSeries = new ScatterSeries ());
+        _graphView!.Series.Add (_answeredSeries = new ScatterSeries ());
 
         _sentSeries.Fill = new GraphCellToRender (new Rune ('.'), new Attribute (ColorName16.BrightGreen, ColorName16.Black));
         _answeredSeries.Fill = new GraphCellToRender (new Rune ('.'), new Attribute (ColorName16.BrightRed, ColorName16.Black));
@@ -358,17 +361,17 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
 
     private void UpdateGraph ()
     {
-        _sentSeries.Points = _sends
+        _sentSeries!.Points = _sends
                              .GroupBy (ToSeconds)
                              .Select (g => new PointF (g.Key, g.Count ()))
                              .ToList ();
 
-        _answeredSeries.Points = _answers.Keys
+        _answeredSeries!.Points = _answers.Keys
                                         .GroupBy (ToSeconds)
                                         .Select (g => new PointF (g.Key, g.Count ()))
                                         .ToList ();
         //  _graphView.ScrollOffset  = new PointF(,0);
-        _graphView.SetNeedsDraw ();
+        _graphView!.SetNeedsDraw ();
 
     }
 
@@ -379,13 +382,13 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
 
     private void SendDar ()
     {
-        Application.Driver.QueueAnsiRequest (
-                                             new ()
-                                             {
-                                                 Request = EscSeqUtils.CSI_SendDeviceAttributes.Request,
-                                                 Terminator = EscSeqUtils.CSI_SendDeviceAttributes.Terminator,
-                                                 ResponseReceived = HandleResponse
-                                             });
+        Application.Driver?.QueueAnsiRequest (
+                                              new ()
+                                              {
+                                                  Request = EscSeqUtils.CSI_SendDeviceAttributes.Request,
+                                                  Terminator = EscSeqUtils.CSI_SendDeviceAttributes.Terminator,
+                                                  ResponseReceived = HandleResponse!
+                                              });
         _sends.Add (DateTime.Now);
     }
 

+ 8 - 8
Examples/UICatalog/Scenarios/Bars.cs

@@ -28,7 +28,7 @@ public class Bars : Scenario
     // QuitKey and it only sticks if changed after init
     private void App_Loaded (object sender, EventArgs e)
     {
-        Application.Top!.Title = GetQuitKeyAndName ();
+        Application.Current!.Title = GetQuitKeyAndName ();
 
         ObservableCollection<string> eventSource = new ();
         ListView eventLog = new ListView ()
@@ -41,7 +41,7 @@ public class Bars : Scenario
             Source = new ListWrapper<string> (eventSource)
         };
         eventLog.Border!.Thickness = new (0, 1, 0, 0);
-        Application.Top.Add (eventLog);
+        Application.Current.Add (eventLog);
 
         FrameView menuBarLikeExamples = new ()
         {
@@ -51,7 +51,7 @@ public class Bars : Scenario
             Width = Dim.Fill () - Dim.Width (eventLog),
             Height = Dim.Percent(33),
         };
-        Application.Top.Add (menuBarLikeExamples);
+        Application.Current.Add (menuBarLikeExamples);
 
         Label label = new Label ()
         {
@@ -98,7 +98,7 @@ public class Bars : Scenario
             Width = Dim.Fill () - Dim.Width (eventLog),
             Height = Dim.Percent (33),
         };
-        Application.Top.Add (menuLikeExamples);
+        Application.Current.Add (menuLikeExamples);
 
         label = new Label ()
         {
@@ -212,7 +212,7 @@ public class Bars : Scenario
             Width = Dim.Width (menuLikeExamples),
             Height = Dim.Percent (33),
         };
-        Application.Top.Add (statusBarLikeExamples);
+        Application.Current.Add (statusBarLikeExamples);
 
         label = new Label ()
         {
@@ -249,7 +249,7 @@ public class Bars : Scenario
         ConfigStatusBar (bar);
         statusBarLikeExamples.Add (bar);
 
-        foreach (FrameView frameView in Application.Top.SubViews.Where (f => f is FrameView)!)
+        foreach (FrameView frameView in Application.Current.SubViews.Where (f => f is FrameView)!)
         {
             foreach (Bar barView in frameView.SubViews.Where (b => b is Bar)!)
             {
@@ -269,8 +269,8 @@ public class Bars : Scenario
 
     //private void SetupContentMenu ()
     //{
-    //    Application.Top.Add (new Label { Text = "Right Click for Context Menu", X = Pos.Center (), Y = 4 });
-    //    Application.Top.MouseClick += ShowContextMenu;
+    //    Application.Current.Add (new Label { Text = "Right Click for Context Menu", X = Pos.Center (), Y = 4 });
+    //    Application.Current.MouseClick += ShowContextMenu;
     //}
 
     //private void ShowContextMenu (object s, MouseEventEventArgs e)

+ 3 - 3
Examples/UICatalog/Scenarios/CombiningMarks.cs

@@ -13,7 +13,7 @@ public class CombiningMarks : Scenario
         top.DrawComplete += (s, e) =>
         {
             // Forces reset _lineColsOffset because we're dealing with direct draw
-            Application.Top!.SetNeedsDraw ();
+            Application.Current!.SetNeedsDraw ();
 
             var i = -1;
             top.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
@@ -58,9 +58,9 @@ public class CombiningMarks : Scenario
             top.Move (0, ++i);
             top.AddStr ("From now on we are using TextFormatter");
             TextFormatter tf = new () { Text = "[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using TextFormatter." };
-            tf.Draw (new (0, ++i, tf.Text.Length, 1), top.GetAttributeForRole (VisualRole.Normal), top.GetAttributeForRole (VisualRole.Normal));
+            tf.Draw (driver: Application.Driver, screen: new (0, ++i, tf.Text.Length, 1), normalColor: top.GetAttributeForRole (VisualRole.Normal), hotColor: top.GetAttributeForRole (VisualRole.Normal));
             tf.Text = "[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using TextFormatter.";
-            tf.Draw (new (0, ++i, tf.Text.Length, 1), top.GetAttributeForRole (VisualRole.Normal), top.GetAttributeForRole (VisualRole.Normal));
+            tf.Draw (driver: Application.Driver, screen: new (0, ++i, tf.Text.Length, 1), normalColor: top.GetAttributeForRole (VisualRole.Normal), hotColor: top.GetAttributeForRole (VisualRole.Normal));
             i++;
             top.Move (0, ++i);
             top.AddStr ("From now on we are using Surrogate pairs with combining diacritics");

+ 2 - 2
Examples/UICatalog/Scenarios/ComboBoxIteration.cs

@@ -42,8 +42,8 @@ public class ComboBoxIteration : Scenario
 
         listview.SelectedItemChanged += (s, e) =>
                                         {
-                                            lbListView.Text = items [e.Item];
-                                            comboBox.SelectedItem = e.Item;
+                                            lbListView.Text = items [e.Item!.Value];
+                                            comboBox.SelectedItem = e.Item.Value;
                                         };
 
         comboBox.SelectedItemChanged += (sender, text) =>

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

@@ -75,7 +75,7 @@ public class ConfigurationEditor : Scenario
 
         void ConfigurationManagerOnApplied (object? sender, ConfigurationManagerEventArgs e)
         {
-            Application.Top?.SetNeedsDraw ();
+            Application.Current?.SetNeedsDraw ();
         }
     }
     public void Save ()

+ 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/CsvEditor.cs

@@ -502,7 +502,7 @@ public class CsvEditor : Scenario
             // Only set the current filename if we successfully loaded the entire file
             _currentFile = filename;
             _selectedCellTextField.SuperView.Enabled = true;
-            Application.Top.Title = $"{GetName ()} - {Path.GetFileName (_currentFile)}";
+            Application.Current.Title = $"{GetName ()} - {Path.GetFileName (_currentFile)}";
         }
         catch (Exception ex)
         {

+ 12 - 12
Examples/UICatalog/Scenarios/DynamicMenuBar.cs

@@ -712,7 +712,7 @@ public class DynamicMenuBar : Scenario
 
             btnUp.Accepting += (s, e) =>
                              {
-                                 int i = _lstMenus.SelectedItem;
+                                 int i = _lstMenus.SelectedItem.Value;
                                  MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
 
                                  if (menuItem != null)
@@ -734,7 +734,7 @@ public class DynamicMenuBar : Scenario
 
             btnDown.Accepting += (s, e) =>
                                {
-                                   int i = _lstMenus.SelectedItem;
+                                   int i = _lstMenus.SelectedItem.Value;
                                    MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
 
                                    if (menuItem != null)
@@ -836,7 +836,7 @@ public class DynamicMenuBar : Scenario
                                                               : MenuItemCheckStyle.Radio,
                                          ShortcutKey = frmMenuDetails.TextShortcutKey.Text
                                      };
-                                     UpdateMenuItem (_currentEditMenuBarItem, menuItem, _lstMenus.SelectedItem);
+                                     UpdateMenuItem (_currentEditMenuBarItem, menuItem, _lstMenus.SelectedItem.Value);
                                  }
                              };
 
@@ -885,8 +885,8 @@ public class DynamicMenuBar : Scenario
 
             btnRemove.Accepting += (s, e) =>
                                 {
-                                    MenuItem menuItem = (DataContext.Menus.Count > 0 && _lstMenus.SelectedItem > -1
-                                                             ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
+                                    MenuItem menuItem = (DataContext.Menus.Count > 0 && _lstMenus.SelectedItem is {} selectedItem
+                                                             ? DataContext.Menus [selectedItem].MenuItem
                                                              : _currentEditMenuBarItem);
 
                                     if (menuItem != null)
@@ -905,9 +905,9 @@ public class DynamicMenuBar : Scenario
                                             SelectCurrentMenuBarItem ();
                                         }
 
-                                        if (_lstMenus.SelectedItem > -1)
+                                        if (_lstMenus.SelectedItem is {} selected)
                                         {
-                                            DataContext.Menus?.RemoveAt (_lstMenus.SelectedItem);
+                                            DataContext.Menus?.RemoveAt (selected);
                                         }
 
                                         if (_lstMenus.Source.Count > 0 && _lstMenus.SelectedItem > _lstMenus.Source.Count - 1)
@@ -927,7 +927,7 @@ public class DynamicMenuBar : Scenario
 
             _lstMenus.OpenSelectedItem += (s, e) =>
                                           {
-                                              _currentMenuBarItem = DataContext.Menus [e.Item].MenuItem;
+                                              _currentMenuBarItem = DataContext.Menus [e.Item.Value].MenuItem;
 
                                               if (!(_currentMenuBarItem is MenuBarItem))
                                               {
@@ -945,8 +945,8 @@ public class DynamicMenuBar : Scenario
 
             _lstMenus.HasFocusChanging += (s, e) =>
                                {
-                                   MenuItem menuBarItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
-                                                              ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
+                                   MenuItem menuBarItem = _lstMenus.SelectedItem is {} selectedItem && DataContext.Menus.Count > 0
+                                                              ? DataContext.Menus [selectedItem].MenuItem
                                                               : null;
                                    SetFrameDetails (menuBarItem);
                                };
@@ -1077,8 +1077,8 @@ public class DynamicMenuBar : Scenario
 
                 if (menuBarItem == null)
                 {
-                    menuItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
-                                   ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
+                    menuItem = _lstMenus.SelectedItem is {} selectedItem && DataContext.Menus.Count > 0
+                                   ? DataContext.Menus [selectedItem].MenuItem
                                    : _currentEditMenuBarItem;
                 }
                 else

+ 21 - 8
Examples/UICatalog/Scenarios/DynamicStatusBar.cs

@@ -312,7 +312,12 @@ public class DynamicStatusBar : Scenario
 
             btnUp.Accepting += (s, e) =>
                               {
-                                  int i = _lstItems.SelectedItem;
+                                  if (_lstItems.SelectedItem is null)
+                                  {
+                                      return;
+                                  }
+                                  int i = _lstItems.SelectedItem.Value;
+
                                   Shortcut statusItem = DataContext.Items.Count > 0 ? DataContext.Items [i].Shortcut : null;
 
                                   if (statusItem != null)
@@ -335,7 +340,12 @@ public class DynamicStatusBar : Scenario
 
             btnDown.Accepting += (s, e) =>
                                 {
-                                    int i = _lstItems.SelectedItem;
+                                    if (_lstItems.SelectedItem is null)
+                                    {
+                                        return;
+                                    }
+                                    int i = _lstItems.SelectedItem.Value;
+
                                     Shortcut statusItem = DataContext.Items.Count > 0 ? DataContext.Items [i].Shortcut : null;
 
                                     if (statusItem != null)
@@ -376,14 +386,17 @@ public class DynamicStatusBar : Scenario
                                   }
                                   else if (_currentEditStatusItem != null)
                                   {
-
                                       var statusItem = new DynamicStatusItem
                                       {
                                           Title = frmStatusBarDetails.TextTitle.Text,
                                           Action = frmStatusBarDetails.TextAction.Text,
                                           Shortcut = frmStatusBarDetails.TextShortcut.Text
                                       };
-                                      UpdateStatusItem (_currentEditStatusItem, statusItem, _lstItems.SelectedItem);
+
+                                      if (_lstItems.SelectedItem is { } selectedItem)
+                                      {
+                                          UpdateStatusItem (_currentEditStatusItem, statusItem, selectedItem);
+                                      }
                                   }
                               };
 
@@ -420,14 +433,14 @@ public class DynamicStatusBar : Scenario
             btnRemove.Accepting += (s, e) =>
                                   {
                                       Shortcut statusItem = DataContext.Items.Count > 0
-                                                                  ? DataContext.Items [_lstItems.SelectedItem].Shortcut
+                                                                  ? DataContext.Items [_lstItems.SelectedItem.Value].Shortcut
                                                                   : null;
 
                                       if (statusItem != null)
                                       {
                                           _statusBar.RemoveShortcut (_currentSelectedStatusBar);
                                           statusItem.Dispose ();
-                                          DataContext.Items.RemoveAt (_lstItems.SelectedItem);
+                                          DataContext.Items.RemoveAt (_lstItems.SelectedItem.Value);
 
                                           if (_lstItems.Source.Count > 0 && _lstItems.SelectedItem > _lstItems.Source.Count - 1)
                                           {
@@ -442,7 +455,7 @@ public class DynamicStatusBar : Scenario
             _lstItems.HasFocusChanging += (s, e) =>
                                {
                                    Shortcut statusItem = DataContext.Items.Count > 0
-                                                               ? DataContext.Items [_lstItems.SelectedItem].Shortcut
+                                                               ? DataContext.Items [_lstItems.SelectedItem.Value].Shortcut
                                                                : null;
                                    SetFrameDetails (statusItem);
                                };
@@ -489,7 +502,7 @@ public class DynamicStatusBar : Scenario
                 if (statusItem == null)
                 {
                     newStatusItem = DataContext.Items.Count > 0
-                                        ? DataContext.Items [_lstItems.SelectedItem].Shortcut
+                                        ? DataContext.Items [_lstItems.SelectedItem.Value].Shortcut
                                         : null;
                 }
                 else

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

@@ -151,7 +151,7 @@ public class Images : Scenario
         _win.Add (_tabView);
 
         // Start trying to detect sixel support
-        var sixelSupportDetector = new SixelSupportDetector ();
+        var sixelSupportDetector = new SixelSupportDetector (Application.Driver);
         sixelSupportDetector.Detect (UpdateSixelSupportState);
 
         Application.Run (_win);

+ 4 - 4
Examples/UICatalog/Scenarios/ListViewWithSelection.cs

@@ -237,7 +237,7 @@ public class ListViewWithSelection : Scenario
             int col,
             int line,
             int width,
-            int start = 0
+            int viewportX = 0
         )
         {
             container.Move (col, line);
@@ -247,7 +247,7 @@ public class ListViewWithSelection : Scenario
                                       string.Format ("{{0,{0}}}", -_nameColumnWidth),
                                       Scenarios [item].GetName ()
                                      );
-            RenderUstr (container, $"{s} ({Scenarios [item].GetDescription ()})", col, line, width, start);
+            RenderUstr (container, $"{s} ({Scenarios [item].GetDescription ()})", col, line, width, viewportX);
         }
 
         public void SetMark (int item, bool value)
@@ -288,10 +288,10 @@ public class ListViewWithSelection : Scenario
         }
 
         // A slightly adapted method from: https://github.com/gui-cs/Terminal.Gui/blob/fc1faba7452ccbdf49028ac49f0c9f0f42bbae91/Terminal.Gui/Views/ListView.cs#L433-L461
-        private void RenderUstr (View view, string ustr, int col, int line, int width, int start = 0)
+        private void RenderUstr (View view, string ustr, int col, int line, int width, int viewportX = 0)
         {
             var used = 0;
-            int index = start;
+            int index = viewportX;
 
             while (index < ustr.Length)
             {

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

@@ -50,7 +50,7 @@ public class ListsAndCombos : Scenario
             Width = Dim.Percent (40),
             Source = new ListWrapper<string> (items)
         };
-        listview.SelectedItemChanged += (s, e) => lbListView.Text = items [listview.SelectedItem];
+        listview.SelectedItemChanged += (s, e) => lbListView.Text = items [listview.SelectedItem.Value];
         win.Add (lbListView, listview);
 
         //var scrollBar = new ScrollBarView (listview, true);

+ 3 - 3
Examples/UICatalog/Scenarios/Mazing.cs

@@ -171,7 +171,7 @@ public class Mazing : Scenario
                 if (_m.PlayerHp <= 0)
                 {
                     _message = "You died!";
-                    Application.Top!.SetNeedsDraw (); // trigger redraw
+                    Application.Current!.SetNeedsDraw (); // trigger redraw
                     _dead = true;
 
                     return; // Stop further action if dead
@@ -190,7 +190,7 @@ public class Mazing : Scenario
                 _message = string.Empty;
             }
 
-            Application.Top!.SetNeedsDraw (); // trigger redraw
+            Application.Current!.SetNeedsDraw (); // trigger redraw
         }
 
         // Optional win condition:
@@ -200,7 +200,7 @@ public class Mazing : Scenario
             _m = new (); // Generate a new maze
             _m.PlayerHp = hp;
             GenerateNpcs ();
-            Application.Top!.SetNeedsDraw (); // trigger redraw
+            Application.Current!.SetNeedsDraw (); // trigger redraw
         }
     }
 }

+ 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,

+ 19 - 19
Examples/UICatalog/Scenarios/RegionScenario.cs

@@ -24,31 +24,31 @@ public class RegionScenario : Scenario
     {
         Application.Init ();
 
-        Window app = new ()
+        Window appWindow = new ()
         {
             Title = GetQuitKeyAndName (),
             TabStop = TabBehavior.TabGroup
         };
-        app.Padding!.Thickness = new (1);
+        appWindow.Padding!.Thickness = new (1);
 
         var tools = new ToolsView { Title = "Tools", X = Pos.AnchorEnd (), Y = 2 };
 
-        tools.CurrentAttribute = app.GetAttributeForRole (VisualRole.HotNormal);
+        tools.CurrentAttribute = appWindow.GetAttributeForRole (VisualRole.HotNormal);
 
         tools.SetStyle += b =>
                           {
                               _drawStyle = b;
-                              app.SetNeedsDraw ();
+                              appWindow.SetNeedsDraw ();
                           };
 
         tools.RegionOpChanged += (s, e) => { _regionOp = e; };
 
         //tools.AddLayer += () => canvas.AddLayer ();
 
-        app.Add (tools);
+        appWindow.Add (tools);
 
         // Add drag handling to window
-        app.MouseEvent += (s, e) =>
+        appWindow.MouseEvent += (s, e) =>
                           {
                               if (e.Flags.HasFlag (MouseFlags.Button1Pressed))
                               {
@@ -62,7 +62,7 @@ public class RegionScenario : Scenario
                                       // Drag
                                       if (_isDragging && _dragStart.HasValue)
                                       {
-                                          app.SetNeedsDraw ();
+                                          appWindow.SetNeedsDraw ();
                                       }
                                   }
                               }
@@ -77,31 +77,31 @@ public class RegionScenario : Scenario
                                       _dragStart = null;
                                   }
 
-                                  app.SetNeedsDraw ();
+                                  appWindow.SetNeedsDraw ();
                               }
                           };
 
         // Draw the regions
-        app.DrawingContent += (s, e) =>
+        appWindow.DrawingContent += (s, e) =>
                               {
                                   // Draw all regions with single line style
                                   //_region.FillRectangles (_attribute.Value, _fillRune);
                                   switch (_drawStyle)
                                   {
                                       case RegionDrawStyles.FillOnly:
-                                          _region.FillRectangles (tools.CurrentAttribute!.Value, _previewFillRune);
+                                          _region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, _previewFillRune);
 
                                           break;
 
                                       case RegionDrawStyles.InnerBoundaries:
-                                          _region.DrawBoundaries (app.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
-                                          _region.FillRectangles (tools.CurrentAttribute!.Value, (Rune)' ');
+                                          _region.DrawBoundaries (appWindow.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
+                                          _region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
 
                                           break;
 
                                       case RegionDrawStyles.OuterBoundary:
-                                          _region.DrawOuterBoundary (app.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
-                                          _region.FillRectangles (tools.CurrentAttribute!.Value, (Rune)' ');
+                                          _region.DrawOuterBoundary (appWindow.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
+                                          _region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
 
                                           break;
                                   }
@@ -109,14 +109,14 @@ public class RegionScenario : Scenario
                                   // If currently dragging, draw preview rectangle
                                   if (_isDragging && _dragStart.HasValue)
                                   {
-                                      Point currentMousePos = Application.GetLastMousePosition ()!.Value;
+                                      Point currentMousePos = appWindow.App!.Mouse.LastMousePosition!.Value;
                                       Rectangle previewRect = GetRectFromPoints (_dragStart.Value, currentMousePos);
                                       var previewRegion = new Region (previewRect);
 
-                                      previewRegion.FillRectangles (tools.CurrentAttribute!.Value, (Rune)' ');
+                                      previewRegion.FillRectangles (appWindow.App.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
 
                                       previewRegion.DrawBoundaries (
-                                                                    app.LineCanvas,
+                                                                    appWindow.LineCanvas,
                                                                     LineStyle.Dashed,
                                                                     new (
                                                                          tools.CurrentAttribute!.Value.Foreground.GetBrighterColor (),
@@ -124,10 +124,10 @@ public class RegionScenario : Scenario
                                   }
                               };
 
-        Application.Run (app);
+        Application.Run (appWindow);
 
         // Clean up
-        app.Dispose ();
+        appWindow.Dispose ();
         Application.Shutdown ();
     }
 

+ 27 - 27
Examples/UICatalog/Scenarios/Shortcuts.cs

@@ -28,7 +28,7 @@ public class Shortcuts : Scenario
     private void App_Loaded (object? sender, EventArgs e)
     {
         Application.QuitKey = Key.F4.WithCtrl;
-        Application.Top!.Title = GetQuitKeyAndName ();
+        Application.Current!.Title = GetQuitKeyAndName ();
 
         ObservableCollection<string> eventSource = new ();
 
@@ -46,14 +46,14 @@ public class Shortcuts : Scenario
 
         eventLog.Width = Dim.Func (
                                    _ => Math.Min (
-                                                  Application.Top.Viewport.Width / 2,
+                                                  Application.Current.Viewport.Width / 2,
                                                   eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
 
         eventLog.Width = Dim.Func (
                                    _ => Math.Min (
                                                   eventLog.SuperView!.Viewport.Width / 2,
                                                   eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
-        Application.Top.Add (eventLog);
+        Application.Current.Add (eventLog);
 
         var alignKeysShortcut = new Shortcut
         {
@@ -86,7 +86,7 @@ public class Shortcuts : Scenario
                                                                           };
 
 
-        Application.Top.Add (alignKeysShortcut);
+        Application.Current.Add (alignKeysShortcut);
 
         var commandFirstShortcut = new Shortcut
         {
@@ -115,7 +115,7 @@ public class Shortcuts : Scenario
                                                                                                       $"{commandFirstShortcut.Id}.CommandView.CheckedStateChanging: {cb.Text}");
                                                                                      eventLog.MoveDown ();
 
-                                                                                     IEnumerable<View> toAlign = Application.Top.SubViews.OfType<Shortcut> ();
+                                                                                     IEnumerable<View> toAlign = Application.Current.SubViews.OfType<Shortcut> ();
                                                                                      IEnumerable<View> enumerable = toAlign as View [] ?? toAlign.ToArray ();
 
                                                                                      foreach (View view in enumerable)
@@ -134,7 +134,7 @@ public class Shortcuts : Scenario
                                                                                  }
                                                                              };
 
-        Application.Top.Add (commandFirstShortcut);
+        Application.Current.Add (commandFirstShortcut);
 
         var canFocusShortcut = new Shortcut
         {
@@ -159,7 +159,7 @@ public class Shortcuts : Scenario
                                                                                  SetCanFocus (e.Result == CheckState.Checked);
                                                                              }
                                                                          };
-        Application.Top.Add (canFocusShortcut);
+        Application.Current.Add (canFocusShortcut);
 
         var appShortcut = new Shortcut
         {
@@ -173,7 +173,7 @@ public class Shortcuts : Scenario
             BindKeyToApplication = true
         };
 
-        Application.Top.Add (appShortcut);
+        Application.Current.Add (appShortcut);
 
         var buttonShortcut = new Shortcut
         {
@@ -193,7 +193,7 @@ public class Shortcuts : Scenario
         var button = (Button)buttonShortcut.CommandView;
         buttonShortcut.Accepting += Button_Clicked;
 
-        Application.Top.Add (buttonShortcut);
+        Application.Current.Add (buttonShortcut);
 
         var optionSelectorShortcut = new Shortcut
         {
@@ -221,7 +221,7 @@ public class Shortcuts : Scenario
                                                                                     }
                                                                                 };
 
-        Application.Top.Add (optionSelectorShortcut);
+        Application.Current.Add (optionSelectorShortcut);
 
         var sliderShortcut = new Shortcut
         {
@@ -248,7 +248,7 @@ public class Shortcuts : Scenario
                                                                            eventLog.MoveDown ();
                                                                        };
 
-        Application.Top.Add (sliderShortcut);
+        Application.Current.Add (sliderShortcut);
 
         ListView listView = new ListView ()
         {
@@ -270,7 +270,7 @@ public class Shortcuts : Scenario
             Key = Key.F5.WithCtrl,
         };
 
-        Application.Top.Add (listViewShortcut);
+        Application.Current.Add (listViewShortcut);
 
         var noCommandShortcut = new Shortcut
         {
@@ -282,7 +282,7 @@ public class Shortcuts : Scenario
             Key = Key.D0
         };
 
-        Application.Top.Add (noCommandShortcut);
+        Application.Current.Add (noCommandShortcut);
 
         var noKeyShortcut = new Shortcut
         {
@@ -295,7 +295,7 @@ public class Shortcuts : Scenario
             HelpText = "Keyless"
         };
 
-        Application.Top.Add (noKeyShortcut);
+        Application.Current.Add (noKeyShortcut);
 
         var noHelpShortcut = new Shortcut
         {
@@ -308,7 +308,7 @@ public class Shortcuts : Scenario
             HelpText = ""
         };
 
-        Application.Top.Add (noHelpShortcut);
+        Application.Current.Add (noHelpShortcut);
         noHelpShortcut.SetFocus ();
 
         var framedShortcut = new Shortcut
@@ -340,7 +340,7 @@ public class Shortcuts : Scenario
         }
 
         framedShortcut.SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Toplevel);
-        Application.Top.Add (framedShortcut);
+        Application.Current.Add (framedShortcut);
 
         // Horizontal
         var progressShortcut = new Shortcut
@@ -387,7 +387,7 @@ public class Shortcuts : Scenario
                          };
         timer.Start ();
 
-        Application.Top.Add (progressShortcut);
+        Application.Current.Add (progressShortcut);
 
         var textField = new TextField
         {
@@ -408,7 +408,7 @@ public class Shortcuts : Scenario
         };
         textField.CanFocus = true;
 
-        Application.Top.Add (textFieldShortcut);
+        Application.Current.Add (textFieldShortcut);
 
         var bgColorShortcut = new Shortcut
         {
@@ -450,19 +450,19 @@ public class Shortcuts : Scenario
                                         eventSource.Add ($"ColorChanged: {o.GetType ().Name} - {args.Result}");
                                         eventLog.MoveDown ();
 
-                                        Application.Top.SetScheme (
-                                                                   new (Application.Top.GetScheme ())
+                                        Application.Current.SetScheme (
+                                                                   new (Application.Current.GetScheme ())
                                                                    {
                                                                        Normal = new (
-                                                                                     Application.Top!.GetAttributeForRole (VisualRole.Normal).Foreground,
+                                                                                     Application.Current!.GetAttributeForRole (VisualRole.Normal).Foreground,
                                                                                      args.Result,
-                                                                                     Application.Top!.GetAttributeForRole (VisualRole.Normal).Style)
+                                                                                     Application.Current!.GetAttributeForRole (VisualRole.Normal).Style)
                                                                    });
                                     }
                                 };
         bgColorShortcut.CommandView = bgColor;
 
-        Application.Top.Add (bgColorShortcut);
+        Application.Current.Add (bgColorShortcut);
 
         var appQuitShortcut = new Shortcut
         {
@@ -476,9 +476,9 @@ public class Shortcuts : Scenario
         };
         appQuitShortcut.Accepting += (o, args) => { Application.RequestStop (); };
 
-        Application.Top.Add (appQuitShortcut);
+        Application.Current.Add (appQuitShortcut);
 
-        foreach (Shortcut shortcut in Application.Top.SubViews.OfType<Shortcut> ())
+        foreach (Shortcut shortcut in Application.Current.SubViews.OfType<Shortcut> ())
         {
             shortcut.Selecting += (o, args) =>
                                   {
@@ -529,7 +529,7 @@ public class Shortcuts : Scenario
 
         void SetCanFocus (bool canFocus)
         {
-            foreach (Shortcut peer in Application.Top!.SubViews.OfType<Shortcut> ())
+            foreach (Shortcut peer in Application.Current!.SubViews.OfType<Shortcut> ())
             {
                 if (peer.CanFocus)
                 {
@@ -542,7 +542,7 @@ public class Shortcuts : Scenario
         {
             var max = 0;
 
-            IEnumerable<Shortcut> toAlign = Application.Top!.SubViews.OfType<Shortcut> ().Where(s => !s.Y.Has<PosAnchorEnd>(out _)).Cast<Shortcut>();
+            IEnumerable<Shortcut> toAlign = Application.Current!.SubViews.OfType<Shortcut> ().Where(s => !s.Y.Has<PosAnchorEnd>(out _)).Cast<Shortcut>();
             IEnumerable<Shortcut> enumerable = toAlign as Shortcut [] ?? toAlign.ToArray ();
 
             if (align)

+ 2 - 2
Examples/UICatalog/Scenarios/SingleBackgroundWorker.cs

@@ -179,9 +179,9 @@ public class SingleBackgroundWorker : Scenario
 
                                                   var builderUI =
                                                       new StagingUIController (_startStaging, e.Result as ObservableCollection<string>);
-                                                  Toplevel top = Application.Top;
+                                                  Toplevel top = Application.Current;
                                                   top.Visible = false;
-                                                  Application.Top.Visible = false;
+                                                  Application.Current.Visible = false;
                                                   builderUI.Load ();
                                                   builderUI.Dispose ();
                                                   top.Visible = true;

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

@@ -153,7 +153,7 @@ public class SpinnerViewStyles : Scenario
                                           else
                                           {
                                               spinner.Visible = true;
-                                              spinner.Style = (SpinnerStyle)Activator.CreateInstance (styleDict [e.Item].Value);
+                                              spinner.Style = (SpinnerStyle)Activator.CreateInstance (styleDict [e.Item.Value].Value);
                                               delayField.Text = spinner.SpinDelay.ToString ();
                                               ckbBounce.CheckedState = spinner.SpinBounce ? CheckState.Checked : CheckState.UnChecked;
                                               ckbNoSpecial.CheckedState = !spinner.HasSpecialCharacters ? CheckState.Checked : CheckState.UnChecked;

+ 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));
     }
 

+ 4 - 4
Examples/UICatalog/Scenarios/Themes.cs

@@ -129,7 +129,7 @@ public sealed class Themes : Scenario
                                           {
                                               if (_view is { })
                                               {
-                                                  Application.Top!.SchemeName = args.NewValue;
+                                                  Application.Current!.SchemeName = args.NewValue;
 
                                                   if (_view.HasScheme)
                                                   {
@@ -160,11 +160,11 @@ public sealed class Themes : Scenario
                                                             TabStop = TabBehavior.TabStop
                                                         };
 
-                                                        allViewsView.FocusedChanged += (s, args) =>
+                                                        allViewsView.FocusedChanged += (s, a) =>
                                                                                        {
                                                                                            allViewsView.Title =
-                                                                                               $"All Views - Focused: {args.NewFocused.Title}";
-                                                                                           viewPropertiesEditor.ViewToEdit = args.NewFocused.SubViews.ElementAt(0);
+                                                                                               $"All Views - Focused: {a.NewFocused?.Title}";
+                                                                                           viewPropertiesEditor.ViewToEdit = a.NewFocused?.SubViews.ElementAt(0);
 
                                                                                        };
                                                         appWindow.Add (allViewsView);

+ 6 - 6
Examples/UICatalog/Scenarios/TreeUseCases.cs

@@ -77,7 +77,7 @@ public class TreeUseCases : Scenario
 
         if (_currentTree != null)
         {
-            Application.Top.Remove (_currentTree);
+            Application.Current.Remove (_currentTree);
             _currentTree.Dispose ();
         }
 
@@ -97,7 +97,7 @@ public class TreeUseCases : Scenario
             tree.TreeBuilder = new GameObjectTreeBuilder ();
         }
 
-        Application.Top.Add (tree);
+        Application.Current.Add (tree);
 
         tree.AddObject (army1);
 
@@ -117,13 +117,13 @@ public class TreeUseCases : Scenario
 
         if (_currentTree != null)
         {
-            Application.Top.Remove (_currentTree);
+            Application.Current.Remove (_currentTree);
             _currentTree.Dispose ();
         }
 
         var tree = new TreeView { X = 0, Y = 1, Width = Dim.Fill(), Height = Dim.Fill (1) };
 
-        Application.Top.Add (tree);
+        Application.Current.Add (tree);
 
         tree.AddObject (myHouse);
 
@@ -134,13 +134,13 @@ public class TreeUseCases : Scenario
     {
         if (_currentTree != null)
         {
-            Application.Top.Remove (_currentTree);
+            Application.Current.Remove (_currentTree);
             _currentTree.Dispose ();
         }
 
         var tree = new TreeView { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill (1) };
 
-        Application.Top.Add (tree);
+        Application.Current.Add (tree);
 
         var root1 = new TreeNode ("Root1");
         root1.Children.Add (new TreeNode ("Child1.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;
             }
         }
 

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

@@ -69,7 +69,7 @@ public class WindowsAndFrameViews : Scenario
         // add it to our list
         listWin.Add (win);
 
-        // create 3 more Windows in a loop, adding them Application.Top
+        // create 3 more Windows in a loop, adding them Application.Current
         // Each with a
         //	button
         //  sub Window with

+ 15 - 6
Examples/UICatalog/UICatalog.cs

@@ -242,7 +242,7 @@ public class UICatalog
 
     /// <summary>
     ///     Shows the UI Catalog selection UI. When the user selects a Scenario to run, the UI Catalog main app UI is
-    ///     killed and the Scenario is run as though it were Application.Top. When the Scenario exits, this function exits.
+    ///     killed and the Scenario is run as though it were Application.Current. When the Scenario exits, this function exits.
     /// </summary>
     /// <returns></returns>
     private static Scenario RunUICatalogTopLevel ()
@@ -269,7 +269,7 @@ public class UICatalog
     [SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
     private static readonly FileSystemWatcher _homeDirWatcher = new ();
 
-    private static void StartConfigFileWatcher ()
+    private static void StartConfigWatcher ()
     {
         // Set up a file system watcher for `./.tui/`
         _currentDirWatcher.NotifyFilter = NotifyFilters.LastWrite;
@@ -317,10 +317,19 @@ public class UICatalog
 
         //_homeDirWatcher.Created += ConfigFileChanged;
         _homeDirWatcher.EnableRaisingEvents = true;
+
+        ThemeManager.ThemeChanged += ThemeManagerOnThemeChanged;
     }
 
-    private static void StopConfigFileWatcher ()
+    private static void ThemeManagerOnThemeChanged (object? sender, EventArgs<string> e)
     {
+        CM.Apply ();
+    }
+
+    private static void StopConfigWatcher ()
+    {
+        ThemeManager.ThemeChanged += ThemeManagerOnThemeChanged;
+
         _currentDirWatcher.EnableRaisingEvents = false;
         _currentDirWatcher.Changed -= ConfigFileChanged;
         _currentDirWatcher.Created -= ConfigFileChanged;
@@ -332,7 +341,7 @@ public class UICatalog
 
     private static void ConfigFileChanged (object sender, FileSystemEventArgs e)
     {
-        if (Application.Top == null)
+        if (Application.Current == null)
         {
             return;
         }
@@ -398,7 +407,7 @@ public class UICatalog
         if (!Options.DontEnableConfigurationManagement)
         {
             ConfigurationManager.Enable (ConfigLocations.All);
-            StartConfigFileWatcher ();
+            StartConfigWatcher ();
         }
 
         while (RunUICatalogTopLevel () is { } scenario)
@@ -440,7 +449,7 @@ public class UICatalog
 #endif
         }
 
-        StopConfigFileWatcher ();
+        StopConfigWatcher ();
         VerifyObjectsWereDisposed ();
     }
 

+ 1 - 0
Examples/UICatalog/UICatalog.csproj

@@ -49,4 +49,5 @@
         <Using Include="System.Drawing.Size" Alias="Size" />
         <Using Include="System.Drawing.SizeF" Alias="SizeF" />
     </ItemGroup>
+    <ProjectExtensions><VisualStudio><UserProperties resources_4config_1json__JsonSchema="..\..\..\docfx\schemas\tui-config-schema.json" /></VisualStudio></ProjectExtensions>
 </Project>

+ 13 - 4
Examples/UICatalog/UICatalogTop.cs

@@ -43,7 +43,11 @@ public class UICatalogTop : Toplevel
         Unloaded += UnloadedHandler;
 
         // Restore previous selections
-        _categoryList.SelectedItem = _cachedCategoryIndex;
+        if (_categoryList.Source?.Count > 0) {
+            _categoryList.SelectedItem = _cachedCategoryIndex ?? 0;
+        } else {
+            _categoryList.SelectedItem = null;
+        }
         _scenarioList.SelectedRow = _cachedScenarioIndex;
 
         SchemeName = CachedTopLevelScheme = SchemeManager.SchemesToSchemeName (Schemes.Base);
@@ -211,6 +215,7 @@ public class UICatalogTop : Toplevel
                                                          return;
                                                      }
                                                      ThemeManager.Theme = ThemeManager.GetThemeNames () [(int)args.Value];
+
                                                  };
 
                 var menuItem = new MenuItemv2
@@ -509,7 +514,7 @@ public class UICatalogTop : Toplevel
     #region Category List
 
     private readonly ListView? _categoryList;
-    private static int _cachedCategoryIndex;
+    private static int? _cachedCategoryIndex;
     public static ObservableCollection<string>? CachedCategories { get; set; }
 
     private ListView CreateCategoryList ()
@@ -539,7 +544,11 @@ public class UICatalogTop : Toplevel
 
     private void CategoryView_SelectedChanged (object? sender, ListViewItemEventArgs? e)
     {
-        string item = CachedCategories! [e!.Item];
+        if (e is null or { Item: null })
+        {
+            return;
+        }
+        string item = CachedCategories! [e.Item.Value];
         ObservableCollection<Scenario> newScenarioList;
 
         if (e.Item == 0)
@@ -691,7 +700,7 @@ public class UICatalogTop : Toplevel
         _disableMouseCb!.CheckedState = Application.IsMouseDisabled ? CheckState.Checked : CheckState.UnChecked;
         _force16ColorsShortcutCb!.CheckedState = Application.Force16Colors ? CheckState.Checked : CheckState.UnChecked;
 
-        Application.Top?.SetNeedsDraw ();
+        Application.Current?.SetNeedsDraw ();
     }
 
     private void ConfigAppliedHandler (object? sender, ConfigurationManagerEventArgs? a) { ConfigApplied (); }

+ 163 - 0
NULLABLE_VIEWS_REMAINING.md

@@ -0,0 +1,163 @@
+# View Subclasses Still With `#nullable disable`
+
+This document lists all View-related files in the `/Views` directory that still have `#nullable disable` set.
+
+**Total**: 121 files
+
+## Breakdown by Subdirectory
+
+### Autocomplete (8 files)
+- Autocomplete/AppendAutocomplete.cs
+- Autocomplete/AutocompleteBase.cs
+- Autocomplete/AutocompleteContext.cs
+- Autocomplete/AutocompleteFilepathContext.cs
+- Autocomplete/IAutocomplete.cs
+- Autocomplete/ISuggestionGenerator.cs
+- Autocomplete/SingleWordSuggestionGenerator.cs
+- Autocomplete/Suggestion.cs
+
+### CollectionNavigation (7 files)
+- CollectionNavigation/CollectionNavigator.cs
+- CollectionNavigation/CollectionNavigatorBase.cs
+- CollectionNavigation/DefaultCollectionNavigatorMatcher.cs
+- CollectionNavigation/ICollectionNavigator.cs
+- CollectionNavigation/ICollectionNavigatorMatcher.cs
+- CollectionNavigation/IListCollectionNavigator.cs
+- CollectionNavigation/TableCollectionNavigator.cs
+
+### Color/ColorPicker (13 files)
+- Color/BBar.cs
+- Color/ColorBar.cs
+- Color/ColorModelStrategy.cs
+- Color/ColorPicker.16.cs
+- Color/ColorPicker.Prompt.cs
+- Color/ColorPicker.Style.cs
+- Color/ColorPicker.cs
+- Color/GBar.cs
+- Color/HueBar.cs
+- Color/IColorBar.cs
+- Color/LightnessBar.cs
+- Color/RBar.cs
+- Color/SaturationBar.cs
+- Color/ValueBar.cs
+
+### FileDialogs (10 files)
+- FileDialogs/AllowedType.cs
+- FileDialogs/DefaultFileOperations.cs
+- FileDialogs/FileDialogCollectionNavigator.cs
+- FileDialogs/FileDialogHistory.cs
+- FileDialogs/FileDialogState.cs
+- FileDialogs/FileDialogStyle.cs
+- FileDialogs/FileDialogTableSource.cs
+- FileDialogs/FilesSelectedEventArgs.cs
+- FileDialogs/OpenDialog.cs
+- FileDialogs/OpenMode.cs
+- FileDialogs/SaveDialog.cs
+
+### GraphView (9 files)
+- GraphView/Axis.cs
+- GraphView/BarSeriesBar.cs
+- GraphView/GraphCellToRender.cs
+- GraphView/GraphView.cs
+- GraphView/IAnnotation.cs
+- GraphView/LegendAnnotation.cs
+- GraphView/LineF.cs
+- GraphView/PathAnnotation.cs
+- GraphView/TextAnnotation.cs
+
+### Menu (3 files)
+- Menu/MenuBarv2.cs
+- Menu/Menuv2.cs
+- Menu/PopoverMenu.cs
+
+### Menuv1 (4 files)
+- Menuv1/MenuClosingEventArgs.cs
+- Menuv1/MenuItemCheckStyle.cs
+- Menuv1/MenuOpenedEventArgs.cs
+- Menuv1/MenuOpeningEventArgs.cs
+
+### ScrollBar (2 files)
+- ScrollBar/ScrollBar.cs
+- ScrollBar/ScrollSlider.cs
+
+### Selectors (2 files)
+- Selectors/FlagSelector.cs
+- Selectors/SelectorStyles.cs
+
+### Slider (9 files)
+- Slider/Slider.cs
+- Slider/SliderAttributes.cs
+- Slider/SliderConfiguration.cs
+- Slider/SliderEventArgs.cs
+- Slider/SliderOption.cs
+- Slider/SliderOptionEventArgs.cs
+- Slider/SliderStyle.cs
+- Slider/SliderType.cs
+
+### SpinnerView (2 files)
+- SpinnerView/SpinnerStyle.cs
+- SpinnerView/SpinnerView.cs
+
+### TabView (4 files)
+- TabView/Tab.cs
+- TabView/TabChangedEventArgs.cs
+- TabView/TabMouseEventArgs.cs
+- TabView/TabStyle.cs
+
+### TableView (18 files)
+- TableView/CellActivatedEventArgs.cs
+- TableView/CellColorGetterArgs.cs
+- TableView/CellToggledEventArgs.cs
+- TableView/CheckBoxTableSourceWrapper.cs
+- TableView/CheckBoxTableSourceWrapperByIndex.cs
+- TableView/CheckBoxTableSourceWrapperByObject.cs
+- TableView/ColumnStyle.cs
+- TableView/DataTableSource.cs
+- TableView/EnumerableTableSource.cs
+- TableView/IEnumerableTableSource.cs
+- TableView/ITableSource.cs
+- TableView/ListColumnStyle.cs
+- TableView/ListTableSource.cs
+- TableView/RowColorGetterArgs.cs
+- TableView/SelectedCellChangedEventArgs.cs
+- TableView/TableSelection.cs
+- TableView/TableStyle.cs
+- TableView/TableView.cs
+- TableView/TreeTableSource.cs
+
+### TextInput (11 files)
+- TextInput/ContentsChangedEventArgs.cs
+- TextInput/DateField.cs
+- TextInput/HistoryTextItemEventArgs.cs
+- TextInput/ITextValidateProvider.cs
+- TextInput/NetMaskedTextProvider.cs
+- TextInput/TextEditingLineStatus.cs
+- TextInput/TextField.cs
+- TextInput/TextRegexProvider.cs
+- TextInput/TextValidateField.cs
+- TextInput/TimeField.cs
+
+### TreeView (14 files)
+- TreeView/AspectGetterDelegate.cs
+- TreeView/Branch.cs
+- TreeView/DelegateTreeBuilder.cs
+- TreeView/DrawTreeViewLineEventArgs.cs
+- TreeView/ITreeBuilder.cs
+- TreeView/ITreeViewFilter.cs
+- TreeView/ObjectActivatedEventArgs.cs
+- TreeView/SelectionChangedEventArgs.cs
+- TreeView/TreeBuilder.cs
+- TreeView/TreeNode.cs
+- TreeView/TreeNodeBuilder.cs
+- TreeView/TreeStyle.cs
+- TreeView/TreeView.cs
+- TreeView/TreeViewTextFilter.cs
+
+### Wizard (3 files)
+- Wizard/Wizard.cs
+- Wizard/WizardEventArgs.cs
+- Wizard/WizardStep.cs
+
+## Summary
+
+These 121 View-related files still have `#nullable disable` as they require additional work to be fully nullable-compliant. All other files in the Terminal.Gui library (outside of the Views directory) have been updated to support nullable reference types.

+ 322 - 0
PR_DESCRIPTION_UPDATED.md

@@ -0,0 +1,322 @@
+# Fixes #4329 - Major Architectural Improvements: API Rename, Nullable Types, and Application Decoupling
+
+## Overview
+
+This PR delivers **three major architectural improvements** to Terminal.Gui v2:
+
+1. **API Terminology Modernization** - Renamed confusing `Application.Top`/`TopLevels` to intuitive `Application.Current`/`Session Stack`
+2. **Nullable Reference Types** - Enabled nullable for 143 non-View library files  
+3. **Application Decoupling** - Introduced `View.App` property to decouple View hierarchy from static Application class
+
+**Impact**: 561 files changed, 7,033 insertions(+), 2,736 deletions(-) across library, tests, and examples.
+
+---
+
+## Part 1: API Terminology Modernization (Breaking Change)
+
+### Changes
+
+- **`Application.Top` → `Application.Current`** (684 occurrences across codebase)
+- **`Application.TopLevels` → `Application.SessionStack`** (31 occurrences)
+- Updated `IApplication` interface, `ApplicationImpl`, all tests, examples, and documentation
+
+### Rationale
+
+The old naming was ambiguous and inconsistent with .NET patterns:
+- `Top` didn't clearly indicate "currently active/running view"
+- `TopLevels` exposed implementation detail (it's a stack!) and didn't match `SessionToken` terminology
+
+New naming follows established patterns:
+- `Current` matches `Thread.CurrentThread`, `HttpContext.Current`, `Synchronization Context.Current`
+- `SessionStack` clearly describes both content (sessions) and structure (stack), aligning with `SessionToken`
+
+### Impact Statistics
+
+| Category | Files Changed | Occurrences Updated |
+|----------|---------------|---------------------|
+| Terminal.Gui library | 41 | 715 |
+| Unit tests | 43 | 631 |
+| Integration tests | 3 | 25 |
+| Examples | 15 | 15 |
+| Documentation | 3 | 14 |
+| **Total** | **91** | **~800** |
+
+###Breaking Changes
+
+**All references must be updated:**
+```csharp
+// OLD (v1/early v2)
+Application.Top?.SetNeedsDraw();
+foreach (var tl in Application.TopLevels) { }
+
+// NEW (v2 current)
+Application.Current?.SetNeedsDraw();
+foreach (var tl in Application.SessionStack) { }
+```
+
+---
+
+## Part 2: Nullable Reference Types Enabled
+
+### Changes
+
+**Phase 1** - Project Configuration (commit 439e161):
+- Added `<Nullable>enable</Nullable>` to `Terminal.Gui.csproj` (project-wide default)
+- Removed redundant `#nullable enable` from 37 files
+- Added `#nullable disable` to 170 files not yet compliant
+
+**Phase 2** - Non-View Compliance (commit 06bd50d):
+- **Removed `#nullable disable` from ALL 143 non-View library files**
+- Build successful with 0 errors
+- All core infrastructure now fully nullable-aware
+
+**Phase 3** - Cleanup (commits 97d9c7d, 49d4fb2):
+- Fixed duplicate `#nullable` directives in 37 files
+- All files now have clean, single nullable directive
+
+### Impact Statistics
+
+| Directory | Files Nullable-Enabled |
+|-----------|------------------------|
+| App/ | 25 ✅ |
+| Configuration/ | 24 ✅ |
+| ViewBase/ | 30 ✅ |
+| Drivers/ | 25 ✅ |
+| Drawing/ | 18 ✅ |
+| FileServices/ | 7 ✅ |
+| Input/ | 6 ✅ |
+| Text/ | 5 ✅ |
+| Resources/ | 3 ✅ |
+| **Views/** | **121 ⏸️ (documented in NULLABLE_VIEWS_REMAINING.md)** |
+| **Total Enabled** | **143 files** |
+
+### Remaining Work
+
+See [NULLABLE_VIEWS_REMAINING.md](./NULLABLE_VIEWS_REMAINING.md) for the 121 View subclass files still with `#nullable disable`. These require careful migration due to complex view hierarchies and will be addressed in a follow-up PR.
+
+---
+
+## Part 3: Application Decoupling (MASSIVE Change)
+
+### Problem
+
+Prior to this PR, Views were tightly coupled to the **static** `Application` class:
+- Direct static calls: `Application.Current`, `Application.Driver`, `Application.MainLoop`
+- Made Views untestable in isolation
+- Violated dependency inversion principle
+- Prevented Views from working with different IApplication implementations
+
+### Solution: `View.App` Property
+
+Introduced `View.App` property that provides IApplication instance:
+
+```csharp
+// Terminal.Gui/ViewBase/View.cs
+public IApplication? App
+{
+    get => GetApp();
+    internal set => _app = value;
+}
+
+private IApplication? GetApp()
+{
+    // Walk up hierarchy to find IApplication
+    if (_app is { }) return _app;
+    if (SuperView is { }) return SuperView.App;
+    return Application.Instance;  // Fallback to global
+}
+```
+
+### Migration Pattern
+
+**Before** (tightly coupled):
+```csharp
+// Direct static dependency
+Application.Driver.Move(x, y);
+if (Application.Current == this) { }
+Application.MainLoop.Invoke(() => { });
+```
+
+**After** (decoupled via View.App):
+```csharp
+// Use injected IApplication instance
+App?.Driver.Move(x, y);
+if (App?.Current == this) { }
+App?.MainLoop.Invoke(() => { });
+```
+
+### Impact Statistics
+
+- **90 files changed** in decoupling commit (899fd76)
+- **987 insertions, 728 deletions**
+- Affects ViewBase, Views, Adornments, Input handling, Drawing
+
+### Benefits
+
+✅ **Testability**: Views can now be tested with mock IApplication  
+✅ **Flexibility**: Views work with any IApplication implementation  
+✅ **Cleaner Architecture**: Follows dependency injection pattern  
+✅ **Future-proof**: Enables multi-application scenarios  
+✅ **Maintainability**: Clearer dependencies, easier to refactor
+
+### Known Remaining Coupling
+
+After decoupling work, only **1 direct Application dependency** remains in ViewBase:
+- `Border.Arrangement.cs`: Uses `Application.ArrangeKey` for hotkey binding
+
+Additional investigation areas for future work:
+1. Some Views still reference Application for convenience (non-critical)
+2. Test infrastructure may have residual static dependencies
+3. Example applications use Application.Run (expected pattern)
+
+---
+
+## Part 4: Test Infrastructure Improvements
+
+### New Test File: `ApplicationImplBeginEndTests.cs`
+
+Added **16 comprehensive tests** validating fragile Begin/End state management:
+
+**Critical Test Coverage:**
+- `End_ThrowsArgumentException_WhenNotBalanced` - Ensures proper Begin/End pairing
+- `End_RestoresCurrentToPreviousToplevel` - Validates Current property management
+- `MultipleBeginEnd_MaintainsStackIntegrity` - Tests nested sessions (5 levels deep)
+
+**Additional Coverage:**
+- Argument validation (null checks)
+- SessionStack push/pop operations
+- Current property state transitions
+- Unique ID generation for toplevels
+- SessionToken management
+- ResetState cleanup behavior
+- Toplevel activation/deactivation events
+
+### Test Quality Improvements
+
+All new tests follow best practices:
+- Work directly with ApplicationImpl instances (no global Application pollution)
+- Use try-finally blocks ensuring Shutdown() always called
+- Properly dispose toplevels before Shutdown (satisfies DEBUG_IDISPOSABLE assertions)
+- No redundant ResetState calls (Shutdown calls it internally)
+
+**Result**: All 16 new tests + all existing tests passing ✅
+
+---
+
+## Additional Changes
+
+### Merged from v2_develop
+
+- RunState → SessionToken terminology (precedent for this rename)
+- Application.TopLevels visibility changed to public (made this rename more important)
+- Legacy MainLoop infrastructure removed
+- Driver architecture modernization
+- Test infrastructure improvements
+
+### Documentation
+
+- Created 5 comprehensive terminology proposal documents in `docfx/docs/`:
+  - `terminology-index.md` - Navigation guide
+  - `terminology-proposal.md` - Complete analysis
+  - `terminology-proposal-summary.md` - Quick reference
+  - `terminology-diagrams.md` - 11 Mermaid diagrams
+  - `terminology-before-after.md` - Side-by-side examples
+- Updated `navigation.md`, `config.md`, `migratingfromv1.md`
+- Created `NULLABLE_VIEWS_REMAINING.md` - Tracks remaining nullable work
+
+---
+
+## Testing
+
+- ✅ **Build**: Successful with 0 errors
+- ✅ **Unit Tests**: All 16 new tests + all existing tests passing
+- ✅ **Integration Tests**: Updated and passing
+- ✅ **Examples**: UICatalog, ReactiveExample, CommunityToolkitExample all updated and functional
+- ✅ **Documentation**: Builds successfully
+
+---
+
+## Breaking Changes Summary
+
+### API Changes (Requires Code Updates)
+
+1. **`Application.Top` → `Application.Current`**
+   - All usages must be updated
+   - Affects any code accessing the currently running toplevel
+   
+2. **`Application.TopLevels` → `Application.SessionStack`**
+   - All usages must be updated
+   - Affects code iterating over running sessions
+
+### Non-Breaking Changes
+
+- Nullable reference types: Improved type safety, no runtime changes
+- View.App property: Additive, existing Application. * calls still work (for now)
+
+---
+
+## Migration Guide
+
+### For Terminology Changes
+
+```bash
+# Find and replace in your codebase
+Application.Top → Application.Current
+Application.TopLevels → Application.SessionStack
+```
+
+### For View.App Usage (Recommended, Not Required)
+
+When writing new View code or refactoring existing Views:
+
+```csharp
+// Prefer (future-proof, testable)
+App?.Driver.AddRune(rune);
+if (App?.Current == this) { }
+
+// Over (works but tightly coupled)
+Application.Driver.AddRune(rune);
+if (Application.Current == this) { }
+```
+
+---
+
+## Future Work
+
+### Nullable Types
+- Enable nullable for remaining 121 View files
+- Document nullable patterns for View subclass authors
+
+### Application Decoupling
+- Remove last `Application.ArrangeKey` reference from Border
+- Consider making View.App property public for advanced scenarios
+- Add documentation on using View.App for testable Views
+
+### Tests
+- Expand ApplicationImpl test coverage based on new patterns discovered
+- Add tests for View.App hierarchy traversal
+
+---
+
+## Pull Request Checklist
+
+- [x] I've named my PR in the form of "Fixes #issue. Terse description."
+- [x] My code follows the style guidelines of Terminal.Gui
+- [x] My code follows the Terminal.Gui library design guidelines  
+- [x] I ran `dotnet test` before commit
+- [x] I have made corresponding changes to the API documentation
+- [x] My changes generate no new warnings
+- [x] I have checked my code and corrected any poor grammar or misspellings
+- [x] I conducted basic QA to assure all features are working
+
+---
+
+## Related Issues
+
+- Fixes #4329 - Rename/Clarify Application.Toplevels/Top Terminology
+- Related to #2491 - Toplevel refactoring
+- Fixes #4333 (duplicate/related issue)
+
+---
+
+**Note**: This is a large, multi-faceted PR that delivers significant architectural improvements. The changes are well-tested and maintain backward compatibility except for the intentional breaking API rename. The work positions Terminal.Gui v2 for better testability, maintainability, and future enhancements.

+ 1 - 1
Scripts/Run-LocalCoverage.ps1

@@ -27,7 +27,7 @@ dotnet test Tests/UnitTests `
   --verbosity minimal `
   --collect:"XPlat Code Coverage" `
   --settings Tests/UnitTests/runsettings.coverage.xml `
-  --blame-hang-timeout 10s
+  --blame-hang-timeout 60s
 
 # ------------------------------------------------------------
 # 4. Run UNIT TESTS (parallel)

+ 18 - 0
Terminal.Gui/App/Application.Current.cs

@@ -0,0 +1,18 @@
+using System.Collections.Concurrent;
+
+namespace Terminal.Gui.App;
+
+public static partial class Application // Current handling
+{
+    /// <inheritdoc cref="IApplication.SessionStack"/>
+    [Obsolete ("The legacy static Application object is going away.")] public static ConcurrentStack<Toplevel> SessionStack => ApplicationImpl.Instance.SessionStack;
+
+    /// <summary>The <see cref="Toplevel"/> that is currently active.</summary>
+    /// <value>The current toplevel.</value>
+    [Obsolete ("The legacy static Application object is going away.")]
+    public static Toplevel? Current
+    {
+        get => ApplicationImpl.Instance.Current;
+        internal set => ApplicationImpl.Instance.Current = value;
+    }
+}

+ 6 - 2
Terminal.Gui/App/Application.Driver.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 using System.Diagnostics.CodeAnalysis;
 
@@ -7,6 +6,7 @@ namespace Terminal.Gui.App;
 public static partial class Application // Driver abstractions
 {
     /// <inheritdoc cref="IApplication.Driver"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static IDriver? Driver
     {
         get => ApplicationImpl.Instance.Driver;
@@ -15,6 +15,7 @@ public static partial class Application // Driver abstractions
 
     /// <inheritdoc cref="IApplication.Force16Colors"/>
     [ConfigurationProperty (Scope = typeof (SettingsScope))]
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool Force16Colors
     {
         get => ApplicationImpl.Instance.Force16Colors;
@@ -23,6 +24,7 @@ public static partial class Application // Driver abstractions
 
     /// <inheritdoc cref="IApplication.ForceDriver"/>
     [ConfigurationProperty (Scope = typeof (SettingsScope))]
+    [Obsolete ("The legacy static Application object is going away.")]
     public static string ForceDriver
     {
         get => ApplicationImpl.Instance.ForceDriver;
@@ -30,11 +32,13 @@ public static partial class Application // Driver abstractions
     }
 
     /// <inheritdoc cref="IApplication.Sixel"/>
+    [Obsolete ("The legacy static Application object is going away.")] 
     public static List<SixelToRender> Sixel => ApplicationImpl.Instance.Sixel;
 
     /// <summary>Gets a list of <see cref="IDriver"/> types and type names that are available.</summary>
     /// <returns></returns>
     [RequiresUnreferencedCode ("AOT")]
+    [Obsolete ("The legacy static Application object is going away.")]
     public static (List<Type?>, List<string?>) GetDriverTypes ()
     {
         // use reflection to get the list of drivers
@@ -59,4 +63,4 @@ public static partial class Application // Driver abstractions
 
         return (driverTypes, driverTypeNames);
     }
-}
+}

+ 5 - 12
Terminal.Gui/App/Application.Keyboard.cs

@@ -1,10 +1,9 @@
-#nullable enable
-
-namespace Terminal.Gui.App;
+namespace Terminal.Gui.App;
 
 public static partial class Application // Keyboard handling
 {
     /// <inheritdoc cref="IApplication.Keyboard"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static IKeyboard Keyboard
     {
         get => ApplicationImpl.Instance.Keyboard;
@@ -13,14 +12,9 @@ public static partial class Application // Keyboard handling
     }
 
     /// <inheritdoc cref="IKeyboard.RaiseKeyDownEvent"/>
+    [Obsolete ("The legacy static Application object is going away.")] 
     public static bool RaiseKeyDownEvent (Key key) => ApplicationImpl.Instance.Keyboard.RaiseKeyDownEvent (key);
 
-    /// <inheritdoc cref="IKeyboard.InvokeCommandsBoundToKey"/>
-    public static bool? InvokeCommandsBoundToKey (Key key) => ApplicationImpl.Instance.Keyboard.InvokeCommandsBoundToKey (key);
-
-    /// <inheritdoc cref="IKeyboard.InvokeCommand"/>
-    public static bool? InvokeCommand (Command command, Key key, KeyBinding binding) => ApplicationImpl.Instance.Keyboard.InvokeCommand (command, key, binding);
-
     /// <summary>
     ///     Raised when the user presses a key.
     ///     <para>
@@ -33,15 +27,14 @@ public static partial class Application // Keyboard handling
     ///     <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
     ///     <para>Fired after <see cref="KeyDown"/> and before <see cref="KeyUp"/>.</para>
     /// </remarks>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<Key>? KeyDown
     {
         add => ApplicationImpl.Instance.Keyboard.KeyDown += value;
         remove => ApplicationImpl.Instance.Keyboard.KeyDown -= value;
     }
 
-    /// <inheritdoc cref="IKeyboard.RaiseKeyUpEvent"/>
-    public static bool RaiseKeyUpEvent (Key key) => ApplicationImpl.Instance.Keyboard.RaiseKeyUpEvent (key);
-
     /// <inheritdoc cref="IKeyboard.KeyBindings"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static KeyBindings KeyBindings => ApplicationImpl.Instance.Keyboard.KeyBindings;
 }

+ 20 - 46
Terminal.Gui/App/Application.Lifecycle.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
@@ -11,68 +10,41 @@ namespace Terminal.Gui.App;
 
 public static partial class Application // Lifecycle (Init/Shutdown)
 {
+    /// <summary>
+    ///     Creates a new <see cref="IApplication"/> instance.
+    /// </summary>
+    /// <remarks>
+    ///     The recommended pattern is for developers to call <c>Application.Create()</c> and then use the returned
+    ///     <see cref="IApplication"/> instance for all subsequent application operations.
+    /// </remarks>
+    /// <returns>A new <see cref="IApplication"/> instance.</returns>
+    public static IApplication Create () { return new ApplicationImpl (); }
 
-    /// <summary>Initializes a new instance of a Terminal.Gui Application. <see cref="Shutdown"/> must be called when the application is closing.</summary>
-    /// <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
-    /// <para>
-    ///     This function loads the right <see cref="IDriver"/> for the platform, Creates a <see cref="Toplevel"/>. and
-    ///     assigns it to <see cref="Top"/>
-    /// </para>
-    /// <para>
-    ///     <see cref="Shutdown"/> must be called when the application is closing (typically after
-    ///     <see cref="Run{T}"/> has returned) to ensure resources are cleaned up and
-    ///     terminal settings
-    ///     restored.
-    /// </para>
-    /// <para>
-    ///     The <see cref="Run{T}"/> function combines
-    ///     <see cref="Init(IDriver,string)"/> and <see cref="Run(Toplevel, Func{Exception, bool})"/>
-    ///     into a single
-    ///     call. An application can use <see cref="Run{T}"/> without explicitly calling
-    ///     <see cref="Init(IDriver,string)"/>.
-    /// </para>
-    /// <param name="driver">
-    ///     The <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or
-    ///     <paramref name="driverName"/> are specified the default driver for the platform will be used.
-    /// </param>
-    /// <param name="driverName">
-    ///     The short name (e.g. "dotnet", "windows", "unix", or "fake") of the
-    ///     <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
-    ///     specified the default driver for the platform will be used.
-    /// </param>
+    /// <inheritdoc cref="IApplication.Init"/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public static void Init (IDriver? driver = null, string? driverName = null)
+    [Obsolete ("The legacy static Application object is going away.")]
+    public static void Init (string? driverName = null)
     {
-        ApplicationImpl.Instance.Init (driver, driverName ?? ForceDriver);
+        ApplicationImpl.Instance.Init (driverName ?? ForceDriver);
     }
 
     /// <summary>
     ///     Gets or sets the main thread ID for the application.
     /// </summary>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static int? MainThreadId
     {
         get => ((ApplicationImpl)ApplicationImpl.Instance).MainThreadId;
         set => ((ApplicationImpl)ApplicationImpl.Instance).MainThreadId = value;
     }
 
-    /// <summary>Shutdown an application initialized with <see cref="Init"/>.</summary>
-    /// <remarks>
-    ///     Shutdown must be called for every call to <see cref="Init"/> or
-    ///     <see cref="Application.Run(Toplevel, Func{Exception, bool})"/> to ensure all resources are cleaned
-    ///     up (Disposed)
-    ///     and terminal settings are restored.
-    /// </remarks>
+    /// <inheritdoc cref="IApplication.Shutdown"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void Shutdown () => ApplicationImpl.Instance.Shutdown ();
 
-    /// <summary>
-    ///     Gets whether the application has been initialized with <see cref="Init"/> and not yet shutdown with <see cref="Shutdown"/>.
-    /// </summary>
-    /// <remarks>
-    /// <para>
-    ///     The <see cref="InitializedChanged"/> event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
-    /// </para>
-    /// </remarks>
+    /// <inheritdoc cref="IApplication.Initialized"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool Initialized
     {
         get => ApplicationImpl.Instance.Initialized;
@@ -80,6 +52,7 @@ public static partial class Application // Lifecycle (Init/Shutdown)
     }
 
     /// <inheritdoc cref="IApplication.InitializedChanged"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<EventArgs<bool>>? InitializedChanged
     {
         add => ApplicationImpl.Instance.InitializedChanged += value;
@@ -91,5 +64,6 @@ public static partial class Application // Lifecycle (Init/Shutdown)
     // this in a function like this ensures we don't make mistakes in
     // guaranteeing that the state of this singleton is deterministic when Init
     // starts running and after Shutdown returns.
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static void ResetState (bool ignoreDisposed = false) => ApplicationImpl.Instance?.ResetState (ignoreDisposed);
 }

+ 7 - 11
Terminal.Gui/App/Application.Mouse.cs

@@ -1,17 +1,12 @@
-#nullable enable
 using System.ComponentModel;
 
 namespace Terminal.Gui.App;
 
 public static partial class Application // Mouse handling
 {
-    /// <summary>
-    ///     Gets the most recent position of the mouse.
-    /// </summary>
-    public static Point? GetLastMousePosition () { return Mouse.GetLastMousePosition (); }
-
     /// <summary>Disable or enable the mouse. The mouse is enabled by default.</summary>
     [ConfigurationProperty (Scope = typeof (SettingsScope))]
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool IsMouseDisabled
     {
         get => Mouse.IsMouseDisabled;
@@ -26,12 +21,8 @@ public static partial class Application // Mouse handling
     ///         This property provides access to mouse-related functionality in a way that supports
     ///         parallel test execution by avoiding static state.
     ///     </para>
-    ///     <para>
-    ///         New code should use <c>Application.Mouse</c> instead of the static properties and methods
-    ///         for better testability. Legacy static properties like <see cref="IsMouseDisabled"/> and
-    ///         <see cref="GetLastMousePosition"/> are retained for backward compatibility.
-    ///     </para>
     /// </remarks>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static IMouse Mouse => ApplicationImpl.Instance.Mouse;
 
 #pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved
@@ -54,6 +45,7 @@ public static partial class Application // Mouse handling
     ///         Use this even to handle mouse events at the application level, before View-specific handling.
     ///     </para>
     /// </remarks>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<MouseEventArgs>? MouseEvent
     {
         add => Mouse.MouseEvent += value;
@@ -65,11 +57,13 @@ public static partial class Application // Mouse handling
     ///     INTERNAL: Holds the non-<see cref="ViewportSettingsFlags.TransparentMouse"/> views that are currently under the
     ///     mouse.
     /// </summary>
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static List<View?> CachedViewsUnderMouse => Mouse.CachedViewsUnderMouse;
 
     /// <summary>
     ///     INTERNAL API: Holds the last mouse position.
     /// </summary>
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static Point? LastMousePosition
     {
         get => Mouse.LastMousePosition;
@@ -81,6 +75,7 @@ public static partial class Application // Mouse handling
     /// </summary>
     /// <param name="screenPosition">The position of the mouse.</param>
     /// <param name="currentViewsUnderMouse">The most recent result from GetViewsUnderLocation().</param>
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static void RaiseMouseEnterLeaveEvents (Point screenPosition, List<View?> currentViewsUnderMouse)
     {
         Mouse.RaiseMouseEnterLeaveEvents (screenPosition, currentViewsUnderMouse);
@@ -92,6 +87,7 @@ public static partial class Application // Mouse handling
     /// </summary>
     /// <remarks>This method can be used to simulate a mouse event, e.g. in unit tests.</remarks>
     /// <param name="mouseEvent">The mouse event with coordinates relative to the screen.</param>
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static void RaiseMouseEvent (MouseEventArgs mouseEvent)
     {
         Mouse.RaiseMouseEvent (mouseEvent);

+ 3 - 2
Terminal.Gui/App/Application.Navigation.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
@@ -7,6 +6,7 @@ public static partial class Application // Navigation stuff
     /// <summary>
     ///     Gets the <see cref="ApplicationNavigation"/> instance for the current <see cref="Application"/>.
     /// </summary>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static ApplicationNavigation? Navigation
     {
         get => ApplicationImpl.Instance.Navigation;
@@ -15,7 +15,7 @@ public static partial class Application // Navigation stuff
 
     /// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
     [ConfigurationProperty (Scope = typeof (SettingsScope))]
-    public static Key NextTabGroupKey
+      [Obsolete ("The legacy static Application object is going away.")]public static Key NextTabGroupKey
     {
         get => ApplicationImpl.Instance.Keyboard.NextTabGroupKey;
         set => ApplicationImpl.Instance.Keyboard.NextTabGroupKey = value;
@@ -41,6 +41,7 @@ public static partial class Application // Navigation stuff
     ///     <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
     ///     <para>Fired after <see cref="KeyDown"/>.</para>
     /// </remarks>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<Key>? KeyUp
     {
         add => ApplicationImpl.Instance.Keyboard.KeyUp += value;

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

@@ -1,13 +1,13 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
 public static partial class Application // Popover handling
 {
     /// <summary>Gets the Application <see cref="Popover"/> manager.</summary>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static ApplicationPopover? Popover
     {
         get => ApplicationImpl.Instance.Popover;
         internal set => ApplicationImpl.Instance.Popover = value;
     }
-}
+}

+ 25 - 8
Terminal.Gui/App/Application.Run.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics.CodeAnalysis;
 
 namespace Terminal.Gui.App;
@@ -22,41 +21,57 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     }
 
     /// <inheritdoc cref="IApplication.Begin"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static SessionToken Begin (Toplevel toplevel) => ApplicationImpl.Instance.Begin (toplevel);
 
     /// <inheritdoc cref="IApplication.PositionCursor"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool PositionCursor () => ApplicationImpl.Instance.PositionCursor ();
 
     /// <inheritdoc cref="IApplication.Run(Func{Exception, bool}, string)"/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public static Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driver = null) => ApplicationImpl.Instance.Run (errorHandler, driver);
+    [Obsolete ("The legacy static Application object is going away.")]
+    public static Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driverName = null) => ApplicationImpl.Instance.Run (errorHandler, driverName);
 
     /// <inheritdoc cref="IApplication.Run{TView}(Func{Exception, bool}, string)"/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public static TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driver = null)
-        where TView : Toplevel, new() => ApplicationImpl.Instance.Run<TView> (errorHandler, driver);
+    [Obsolete ("The legacy static Application object is going away.")]
+    public static TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driverName = null)
+        where TView : Toplevel, new() => ApplicationImpl.Instance.Run<TView> (errorHandler, driverName);
 
     /// <inheritdoc cref="IApplication.Run(Toplevel, Func{Exception, bool})"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void Run (Toplevel view, Func<Exception, bool>? errorHandler = null) => ApplicationImpl.Instance.Run (view, errorHandler);
 
     /// <inheritdoc cref="IApplication.AddTimeout"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static object? AddTimeout (TimeSpan time, Func<bool> callback) => ApplicationImpl.Instance.AddTimeout (time, callback);
 
     /// <inheritdoc cref="IApplication.RemoveTimeout"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool RemoveTimeout (object token) => ApplicationImpl.Instance.RemoveTimeout (token);
 
     /// <inheritdoc cref="IApplication.TimedEvents"/>
     /// 
+    [Obsolete ("The legacy static Application object is going away.")]
     public static ITimedEvents? TimedEvents => ApplicationImpl.Instance?.TimedEvents;
-    /// <inheritdoc cref="IApplication.Invoke"/>
+
+    /// <inheritdoc cref="IApplication.Invoke(Action{IApplication})"/>
+    [Obsolete ("The legacy static Application object is going away.")]
+    public static void Invoke (Action<IApplication> action) => ApplicationImpl.Instance.Invoke (action);
+
+    /// <inheritdoc cref="IApplication.Invoke(Action)"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void Invoke (Action action) => ApplicationImpl.Instance.Invoke (action);
 
     /// <inheritdoc cref="IApplication.LayoutAndDraw"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void LayoutAndDraw (bool forceRedraw = false) => ApplicationImpl.Instance.LayoutAndDraw (forceRedraw);
 
     /// <inheritdoc cref="IApplication.StopAfterFirstIteration"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static bool StopAfterFirstIteration
     {
         get => ApplicationImpl.Instance.StopAfterFirstIteration;
@@ -64,15 +79,15 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     }
 
     /// <inheritdoc cref="IApplication.RequestStop(Toplevel)"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void RequestStop (Toplevel? top = null) => ApplicationImpl.Instance.RequestStop (top);
 
     /// <inheritdoc cref="IApplication.End"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static void End (SessionToken sessionToken) => ApplicationImpl.Instance.End (sessionToken);
 
-    /// <inheritdoc cref="IApplication.RaiseIteration"/>
-    internal static void RaiseIteration () => ApplicationImpl.Instance.RaiseIteration ();
-
     /// <inheritdoc cref="IApplication.Iteration"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<IterationEventArgs>? Iteration
     {
         add => ApplicationImpl.Instance.Iteration += value;
@@ -80,6 +95,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     }
 
     /// <inheritdoc cref="IApplication.SessionBegun"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<SessionTokenEventArgs>? SessionBegun
     {
         add => ApplicationImpl.Instance.SessionBegun += value;
@@ -87,6 +103,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     }
 
     /// <inheritdoc cref="IApplication.SessionEnded"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<ToplevelEventArgs>? SessionEnded
     {
         add => ApplicationImpl.Instance.SessionEnded += value;

+ 3 - 1
Terminal.Gui/App/Application.Screen.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
@@ -6,6 +5,7 @@ public static partial class Application // Screen related stuff; intended to hid
 {
     /// <inheritdoc cref="IApplication.Screen"/>
 
+    [Obsolete ("The legacy static Application object is going away.")]
     public static Rectangle Screen
     {
         get => ApplicationImpl.Instance.Screen;
@@ -13,6 +13,7 @@ public static partial class Application // Screen related stuff; intended to hid
     }
 
     /// <inheritdoc cref="IApplication.ScreenChanged"/>
+    [Obsolete ("The legacy static Application object is going away.")]
     public static event EventHandler<EventArgs<Rectangle>>? ScreenChanged
     {
         add => ApplicationImpl.Instance.ScreenChanged += value;
@@ -21,6 +22,7 @@ public static partial class Application // Screen related stuff; intended to hid
 
     /// <inheritdoc cref="IApplication.ClearScreenNextIteration"/>
 
+    [Obsolete ("The legacy static Application object is going away.")]
     internal static bool ClearScreenNextIteration
     {
         get => ApplicationImpl.Instance.ClearScreenNextIteration;

+ 0 - 18
Terminal.Gui/App/Application.Toplevel.cs

@@ -1,18 +0,0 @@
-#nullable enable
-using System.Collections.Concurrent;
-
-namespace Terminal.Gui.App;
-
-public static partial class Application // Toplevel handling
-{
-    /// <inheritdoc cref="IApplication.TopLevels"/>
-    public static ConcurrentStack<Toplevel> TopLevels => ApplicationImpl.Instance.TopLevels;
-
-    /// <summary>The <see cref="Toplevel"/> that is currently active.</summary>
-    /// <value>The top.</value>
-    public static Toplevel? Top
-    {
-        get => ApplicationImpl.Instance.Top;
-        internal set => ApplicationImpl.Instance.Top = value;
-    }
-}

+ 11 - 78
Terminal.Gui/App/Application.cs

@@ -1,8 +1,7 @@
-#nullable enable
-
 // We use global using directives to simplify the code and avoid repetitive namespace declarations.
 // Put them here so they are available throughout the application.
 // Do not put them in AssemblyInfo.cs as it will break GitVersion's /updateassemblyinfo
+
 global using Attribute = Terminal.Gui.Drawing.Attribute;
 global using Color = Terminal.Gui.Drawing.Color;
 global using CM = Terminal.Gui.Configuration.ConfigurationManager;
@@ -16,7 +15,6 @@ global using Terminal.Gui.Drawing;
 global using Terminal.Gui.Text;
 global using Terminal.Gui.Resources;
 global using Terminal.Gui.FileServices;
-using System.Diagnostics;
 using System.Globalization;
 using System.Reflection;
 using System.Resources;
@@ -40,95 +38,31 @@ namespace Terminal.Gui.App;
 public static partial class Application
 {
     /// <summary>
-    /// Maximum number of iterations of the main loop (and hence draws)
-    /// to allow to occur per second. Defaults to <see cref="DefaultMaximumIterationsPerSecond"/>> which is a 40ms sleep
-    /// after iteration (factoring in how long iteration took to run).
-    /// <remarks>Note that not every iteration draws (see <see cref="View.NeedsDraw"/>).
-    /// Only affects v2 drivers.</remarks>
+    ///     Maximum number of iterations of the main loop (and hence draws)
+    ///     to allow to occur per second. Defaults to <see cref="DefaultMaximumIterationsPerSecond"/>> which is a 40ms sleep
+    ///     after iteration (factoring in how long iteration took to run).
+    ///     <remarks>
+    ///         Note that not every iteration draws (see <see cref="View.NeedsDraw"/>).
+    ///         Only affects v2 drivers.
+    ///     </remarks>
     /// </summary>
     public static ushort MaximumIterationsPerSecond = DefaultMaximumIterationsPerSecond;
 
     /// <summary>
-    /// Default value for <see cref="MaximumIterationsPerSecond"/>
+    ///     Default value for <see cref="MaximumIterationsPerSecond"/>
     /// </summary>
     public const ushort DefaultMaximumIterationsPerSecond = 25;
 
-    /// <summary>
-    ///     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);
-    }
-
-    /// <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 ();
-    }
-
     /// <summary>Gets all cultures supported by the application without the invariant language.</summary>
     public static List<CultureInfo>? SupportedCultures { get; private set; } = GetSupportedCultures ();
 
-
     internal static List<CultureInfo> GetAvailableCulturesFromEmbeddedResources ()
     {
         ResourceManager rm = new (typeof (Strings));
 
         CultureInfo [] cultures = CultureInfo.GetCultures (CultureTypes.AllCultures);
 
-        return cultures.Where (
-                               cultureInfo =>
+        return cultures.Where (cultureInfo =>
                                    !cultureInfo.Equals (CultureInfo.InvariantCulture)
                                    && rm.GetResourceSet (cultureInfo, true, false) is { }
                               )
@@ -152,8 +86,7 @@ public static partial class Application
         if (cultures.Length > 1 && Directory.Exists (Path.Combine (assemblyLocation, "pt-PT")))
         {
             // Return all culture for which satellite folder found with culture code.
-            return cultures.Where (
-                                   cultureInfo =>
+            return cultures.Where (cultureInfo =>
                                        Directory.Exists (Path.Combine (assemblyLocation, cultureInfo.Name))
                                        && File.Exists (Path.Combine (assemblyLocation, cultureInfo.Name, resourceFilename))
                                   )

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

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Collections.Concurrent;
 
 namespace Terminal.Gui.App;
@@ -80,7 +79,7 @@ public partial class ApplicationImpl
 
         Logging.Trace ($"Created Subcomponents: {Coordinator}");
 
-        Coordinator.StartInputTaskAsync ().Wait ();
+        Coordinator.StartInputTaskAsync (this).Wait ();
 
         if (Driver == null)
         {

+ 18 - 18
Terminal.Gui/App/ApplicationImpl.Lifecycle.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 
@@ -15,7 +14,7 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public void Init (IDriver? driver = null, string? driverName = null)
+    public void Init (string? driverName = null)
     {
         if (Initialized)
         {
@@ -34,11 +33,11 @@ public partial class ApplicationImpl
             _driverName = ForceDriver;
         }
 
-        Debug.Assert (Navigation is null);
-        Navigation = new ();
+       // 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 { };
@@ -50,7 +49,7 @@ public partial class ApplicationImpl
         Key existingPrevTabGroupKey = _keyboard?.PrevTabGroupKey ?? Key.F6.WithShift;
 
         // Reset keyboard to ensure fresh state with default bindings
-        _keyboard = new KeyboardImpl { Application = this };
+        _keyboard = new KeyboardImpl { App = this };
 
         // Restore previously set keys if they existed and were different from defaults
         if (hasExistingKeyboard)
@@ -114,9 +113,6 @@ public partial class ApplicationImpl
 
         // Clear the event to prevent memory leaks
         InitializedChanged = null;
-
-        // Create a new lazy instance for potential future Init
-        _lazyInstance = new (() => new ApplicationImpl ());
     }
 
 #if DEBUG
@@ -156,8 +152,11 @@ public partial class ApplicationImpl
         // Init created. Apps that do any threading will need to code defensively for this.
         // e.g. see Issue #537
 
+        // === 0. Stop all timers ===
+        TimedEvents?.StopAll ();
+
         // === 1. Stop all running toplevels ===
-        foreach (Toplevel? t in TopLevels)
+        foreach (Toplevel? t in SessionStack)
         {
             t!.Running = false;
         }
@@ -170,29 +169,30 @@ public partial class ApplicationImpl
             popover.Visible = false;
         }
 
+        // Any popovers added to Popover have their lifetime controlled by Popover
         Popover?.Dispose ();
         Popover = null;
 
         // === 3. Clean up toplevels ===
-        TopLevels.Clear ();
+        SessionStack.Clear ();
 
 #if DEBUG_IDISPOSABLE
 
-        // Don't dispose the Top. It's up to caller dispose it
-        if (View.EnableDebugIDisposableAsserts && !ignoreDisposed && Top is { })
+        // Don't dispose the Current. It's up to caller dispose it
+        if (View.EnableDebugIDisposableAsserts && !ignoreDisposed && Current is { })
         {
-            Debug.Assert (Top.WasDisposed, $"Title = {Top.Title}, Id = {Top.Id}");
+            Debug.Assert (Current.WasDisposed, $"Title = {Current.Title}, Id = {Current.Id}");
 
             // If End wasn't called _CachedSessionTokenToplevel may be null
             if (CachedSessionTokenToplevel is { })
             {
                 Debug.Assert (CachedSessionTokenToplevel.WasDisposed);
-                Debug.Assert (CachedSessionTokenToplevel == Top);
+                Debug.Assert (CachedSessionTokenToplevel == Current);
             }
         }
 #endif
 
-        Top = null;
+        Current = null;
         CachedSessionTokenToplevel = null;
 
         // === 4. Clean up driver ===
@@ -222,7 +222,7 @@ public partial class ApplicationImpl
 
         // === 7. Clear navigation and screen state ===
         ScreenChanged = null;
-        Navigation = null;
+        //Navigation = null;
 
         // === 8. Reset initialization state ===
         Initialized = false;

+ 78 - 53
Terminal.Gui/App/ApplicationImpl.Run.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 
@@ -37,28 +36,28 @@ public partial class ApplicationImpl
         var rs = new SessionToken (toplevel);
 
 #if DEBUG_IDISPOSABLE
-        if (View.EnableDebugIDisposableAsserts && Top is { } && toplevel != Top && !TopLevels.Contains (Top))
+        if (View.EnableDebugIDisposableAsserts && Current is { } && toplevel != Current && !SessionStack.Contains (Current))
         {
-            // This assertion confirm if the Top was already disposed
-            Debug.Assert (Top.WasDisposed);
-            Debug.Assert (Top == CachedSessionTokenToplevel);
+            // This assertion confirm if the Current was already disposed
+            Debug.Assert (Current.WasDisposed);
+            Debug.Assert (Current == CachedSessionTokenToplevel);
         }
 #endif
 
-        lock (TopLevels)
+        lock (SessionStack)
         {
-            if (Top is { } && toplevel != Top && !TopLevels.Contains (Top))
+            if (Current is { } && toplevel != Current && !SessionStack.Contains (Current))
             {
-                // If Top was already disposed and isn't on the Toplevels Stack,
+                // If Current was already disposed and isn't on the Toplevels Stack,
                 // clean it up here if is the same as _CachedSessionTokenToplevel
-                if (Top == CachedSessionTokenToplevel)
+                if (Current == CachedSessionTokenToplevel)
                 {
-                    Top = null;
+                    Current = null;
                 }
                 else
                 {
                     // Probably this will never hit
-                    throw new ObjectDisposedException (Top.GetType ().FullName);
+                    throw new ObjectDisposedException (Current.GetType ().FullName);
                 }
             }
 
@@ -67,56 +66,58 @@ public partial class ApplicationImpl
             if (string.IsNullOrEmpty (toplevel.Id))
             {
                 var count = 1;
-                var id = (TopLevels.Count + count).ToString ();
+                var id = (SessionStack.Count + count).ToString ();
 
-                while (TopLevels.Count > 0 && TopLevels.FirstOrDefault (x => x.Id == id) is { })
+                while (SessionStack.Count > 0 && SessionStack.FirstOrDefault (x => x.Id == id) is { })
                 {
                     count++;
-                    id = (TopLevels.Count + count).ToString ();
+                    id = (SessionStack.Count + count).ToString ();
                 }
 
-                toplevel.Id = (TopLevels.Count + count).ToString ();
+                toplevel.Id = (SessionStack.Count + count).ToString ();
 
-                TopLevels.Push (toplevel);
+                SessionStack.Push (toplevel);
             }
             else
             {
-                Toplevel? dup = TopLevels.FirstOrDefault (x => x.Id == toplevel.Id);
+                Toplevel? dup = SessionStack.FirstOrDefault (x => x.Id == toplevel.Id);
 
                 if (dup is null)
                 {
-                    TopLevels.Push (toplevel);
+                    SessionStack.Push (toplevel);
                 }
             }
         }
 
-        if (Top is null)
+        if (Current is null)
         {
-            Top = toplevel;
+            toplevel.App = this;
+            Current = toplevel;
         }
 
-        if ((Top?.Modal == false && toplevel.Modal)
-            || (Top?.Modal == false && !toplevel.Modal)
-            || (Top?.Modal == true && toplevel.Modal))
+        if ((Current?.Modal == false && toplevel.Modal)
+            || (Current?.Modal == false && !toplevel.Modal)
+            || (Current?.Modal == true && toplevel.Modal))
         {
             if (toplevel.Visible)
             {
-                if (Top is { HasFocus: true })
+                if (Current is { HasFocus: true })
                 {
-                    Top.HasFocus = false;
+                    Current.HasFocus = false;
                 }
 
-                // Force leave events for any entered views in the old Top
-                if (Mouse.GetLastMousePosition () is { })
+                // Force leave events for any entered views in the old Current
+                if (Mouse.LastMousePosition is { })
                 {
-                    Mouse.RaiseMouseEnterLeaveEvents (Mouse.GetLastMousePosition ()!.Value, new ());
+                    Mouse.RaiseMouseEnterLeaveEvents (Mouse.LastMousePosition!.Value, new ());
                 }
 
-                Top?.OnDeactivate (toplevel);
-                Toplevel previousTop = Top!;
+                Current?.OnDeactivate (toplevel);
+                Toplevel previousTop = Current!;
 
-                Top = toplevel;
-                Top.OnActivate (previousTop);
+                Current = toplevel;
+                Current.App = this;
+                Current.OnActivate (previousTop);
             }
         }
 
@@ -135,7 +136,7 @@ public partial class ApplicationImpl
 
         toplevel.OnLoaded ();
 
-        Instance.LayoutAndDraw (true);
+        LayoutAndDraw (true);
 
         if (PositionCursor ())
         {
@@ -156,18 +157,18 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driver = null) { return Run<Toplevel> (errorHandler, driver); }
+    public Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driverName = null) { return Run<Toplevel> (errorHandler, driverName); }
 
     /// <inheritdoc/>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driver = null)
+    public TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driverName = null)
         where TView : Toplevel, new ()
     {
         if (!Initialized)
         {
             // Init() has NOT been called. Auto-initialize as per interface contract.
-            Init (null, driver);
+            Init (driverName);
         }
 
         TView top = new ();
@@ -193,15 +194,15 @@ public partial class ApplicationImpl
             throw new InvalidOperationException ("Driver was inexplicably null when trying to Run view");
         }
 
-        Top = view;
+        Current = view;
 
-        SessionToken rs = Application.Begin (view);
+        SessionToken rs = Begin (view);
 
-        Top.Running = true;
+        Current.Running = true;
 
         var firstIteration = true;
 
-        while (TopLevels.TryPeek (out Toplevel? found) && found == view && view.Running)
+        while (SessionStack.TryPeek (out Toplevel? found) && found == view && view.Running)
         {
             if (Coordinator is null)
             {
@@ -220,7 +221,7 @@ public partial class ApplicationImpl
         }
 
         Logging.Information ("Run - Calling End");
-        Application.End (rs);
+        End (rs);
     }
 
     /// <inheritdoc/>
@@ -233,11 +234,11 @@ public partial class ApplicationImpl
             ApplicationPopover.HideWithQuitCommand (visiblePopover);
         }
 
-        sessionToken.Toplevel.OnUnloaded ();
+        sessionToken.Toplevel?.OnUnloaded ();
 
         // End the Session
         // First, take it off the Toplevel Stack
-        if (TopLevels.TryPop (out Toplevel? topOfStack))
+        if (SessionStack.TryPop (out Toplevel? topOfStack))
         {
             if (topOfStack != sessionToken.Toplevel)
             {
@@ -250,10 +251,11 @@ public partial class ApplicationImpl
         // Notify that it is closing
         sessionToken.Toplevel?.OnClosed (sessionToken.Toplevel);
 
-        if (TopLevels.TryPeek (out Toplevel? newTop))
+        if (SessionStack.TryPeek (out Toplevel? newTop))
         {
-            Top = newTop;
-            Top?.SetNeedsDraw ();
+            newTop.App = this;
+            Current = newTop;
+            Current?.SetNeedsDraw ();
         }
 
         if (sessionToken.Toplevel is { HasFocus: true })
@@ -261,9 +263,9 @@ public partial class ApplicationImpl
             sessionToken.Toplevel.HasFocus = false;
         }
 
-        if (Top is { HasFocus: false })
+        if (Current is { HasFocus: false })
         {
-            Top.SetFocus ();
+            Current.SetFocus ();
         }
 
         CachedSessionTokenToplevel = sessionToken.Toplevel;
@@ -283,9 +285,9 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     public void RequestStop (Toplevel? top)
     {
-        Logging.Trace ($"Top: '{(top is { } ? top : "null")}'");
+        Logging.Trace ($"Current: '{(top is { } ? top : "null")}'");
 
-        top ??= Top;
+        top ??= Current;
 
         if (top == null)
         {
@@ -321,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 (Top is { Running: true } && MainThreadId == Thread.CurrentThread.ManagedThreadId)
+        if (Current is { Running: true } && MainThreadId == Thread.CurrentThread.ManagedThreadId)
         {
-            action ();
+            action?.Invoke ();
 
             return;
         }
@@ -336,7 +361,7 @@ public partial class ApplicationImpl
                           TimeSpan.Zero,
                           () =>
                           {
-                              action ();
+                              action?.Invoke ();
 
                               return false;
                           }

+ 15 - 8
Terminal.Gui/App/ApplicationImpl.Screen.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
@@ -45,6 +44,11 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     public bool PositionCursor ()
     {
+        if (Driver is null)
+        {
+            return false;
+        }
+
         // Find the most focused view and position the cursor there.
         View? mostFocused = Navigation?.GetFocused ();
 
@@ -66,7 +70,7 @@ public partial class ApplicationImpl
         Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty });
 
         Rectangle superViewViewport =
-            mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver!.Screen;
+            mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver.Screen;
 
         if (!superViewViewport.IntersectsWith (mostFocusedViewport))
         {
@@ -133,7 +137,7 @@ public partial class ApplicationImpl
 
         ScreenChanged?.Invoke (this, new (screen));
 
-        foreach (Toplevel t in TopLevels)
+        foreach (Toplevel t in SessionStack)
         {
             t.OnSizeChanging (new (screen.Size));
             t.SetNeedsLayout ();
@@ -147,7 +151,7 @@ public partial class ApplicationImpl
     /// <inheritdoc/>
     public void LayoutAndDraw (bool forceRedraw = false)
     {
-        List<View> tops = [.. TopLevels];
+        List<View> tops = [.. SessionStack];
 
         if (Popover?.GetActivePopover () as View is { Visible: true } visiblePopover)
         {
@@ -169,9 +173,12 @@ public partial class ApplicationImpl
             Driver?.ClearContents ();
         }
 
-        View.SetClipToScreen ();
-        View.Draw (tops, neededLayout || forceRedraw);
-        View.SetClipToScreen ();
-        Driver?.Refresh ();
+        if (Driver is { })
+        {
+            Driver.Clip = new (Screen);
+            View.Draw (tops, neededLayout || forceRedraw);
+            Driver.Clip = new (Screen);
+            Driver?.Refresh ();
+        }
     }
 }

+ 64 - 21
Terminal.Gui/App/ApplicationImpl.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Collections.Concurrent;
 
 namespace Terminal.Gui.App;
@@ -10,9 +9,9 @@ namespace Terminal.Gui.App;
 public partial class ApplicationImpl : IApplication
 {
     /// <summary>
-    ///     Creates a new instance of the Application backend.
+    ///     INTERNAL: Creates a new instance of the Application backend.
     /// </summary>
-    public ApplicationImpl () { }
+    internal ApplicationImpl () { }
 
     /// <summary>
     ///     INTERNAL: Creates a new instance of the Application backend.
@@ -22,22 +21,22 @@ public partial class ApplicationImpl : IApplication
 
     #region Singleton
 
-    // Private static readonly Lazy instance of Application
-    private static Lazy<IApplication> _lazyInstance = new (() => new ApplicationImpl ());
-
     /// <summary>
-    ///     Change the singleton implementation, should not be called except before application
-    ///     startup. This method lets you provide alternative implementations of core static gateway
-    ///     methods of <see cref="Application"/>.
+    ///     Configures the singleton instance of <see cref="Application"/> to use the specified backend implementation.
     /// </summary>
-    /// <param name="newApplication"></param>
-    public static void ChangeInstance (IApplication? newApplication) { _lazyInstance = new (newApplication!); }
+    /// <param name="app"></param>
+    public static void SetInstance (IApplication? app)
+    {
+        _instance = app;
+    }
+
+    // Private static readonly Lazy instance of Application
+    private static IApplication? _instance;
 
     /// <summary>
     ///     Gets the currently configured backend implementation of <see cref="Application"/> gateway methods.
-    ///     Change to your own implementation by using <see cref="ChangeInstance"/> (before init).
     /// </summary>
-    public static IApplication Instance => _lazyInstance.Value;
+    public static IApplication Instance => _instance ??= new ApplicationImpl ();
 
     #endregion Singleton
 
@@ -57,7 +56,7 @@ public partial class ApplicationImpl : IApplication
         {
             if (_mouse is null)
             {
-                _mouse = new MouseImpl { Application = this };
+                _mouse = new MouseImpl { App = this };
             }
 
             return _mouse;
@@ -66,7 +65,6 @@ public partial class ApplicationImpl : IApplication
     }
 
     private IKeyboard? _keyboard;
-    private bool _stopAfterFirstIteration;
 
     /// <summary>
     ///     Handles keyboard input and key bindings at the Application level
@@ -77,7 +75,7 @@ public partial class ApplicationImpl : IApplication
         {
             if (_keyboard is null)
             {
-                _keyboard = new KeyboardImpl { Application = this };
+                _keyboard = new KeyboardImpl { App = this };
             }
 
             return _keyboard;
@@ -89,22 +87,67 @@ 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;
 
     /// <inheritdoc/>
-    public ApplicationNavigation? Navigation { get; set; }
+    public ApplicationNavigation? Navigation
+    {
+        get
+        {
+            if (_navigation is null)
+            {
+                _navigation = new () { App = this };
+            }
+
+            return _navigation;
+        }
+        set => _navigation = value ?? throw new ArgumentNullException (nameof (value));
+    }
+
+    private Toplevel? _current;
 
     /// <inheritdoc/>
-    public Toplevel? Top { 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 TopLevels. There be dragons here, e.g. see how Toplevel.Id is used. What
+    // BUGBUG: Technically, this is not the full lst of sessions. There be dragons here, e.g. see how Toplevel.Id is used. What
 
     /// <inheritdoc/>
-    public ConcurrentStack<Toplevel> TopLevels { get; } = new ();
+    public ConcurrentStack<Toplevel> SessionStack { get; } = new ();
 
     /// <inheritdoc/>
     public Toplevel? CachedSessionTokenToplevel { get; set; }
 
     #endregion View Management
+
+    /// <inheritdoc/>
+    public new string ToString () => Driver?.ToString () ?? string.Empty;
 }

+ 7 - 3
Terminal.Gui/App/ApplicationNavigation.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 using System.Diagnostics;
 
@@ -17,6 +16,11 @@ public class ApplicationNavigation
         // TODO: Move navigation key bindings here from AddApplicationKeyBindings
     }
 
+    /// <summary>
+    ///     The <see cref="IApplication"/> instance used by this instance.
+    /// </summary>
+    public IApplication? App { get; set; }
+
     private View? _focused;
 
     /// <summary>
@@ -105,10 +109,10 @@ public class ApplicationNavigation
     /// </returns>
     public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)
     {
-        if (Application.Popover?.GetActivePopover () as View is { Visible: true } visiblePopover)
+        if (App?.Popover?.GetActivePopover () as View is { Visible: true } visiblePopover)
         {
             return visiblePopover.AdvanceFocus (direction, behavior);
         }
-        return Application.Top is { } && Application.Top.AdvanceFocus (direction, behavior);
+        return App?.Current is { } && App.Current.AdvanceFocus (direction, behavior);
     }
 }

+ 32 - 13
Terminal.Gui/App/ApplicationPopover.cs

@@ -1,12 +1,11 @@
-#nullable enable
 
 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
 {
@@ -15,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>
@@ -35,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.Top
-            popover.Toplevel ??= Application.Top;
+            // When created, set IPopover.Toplevel to the current Application.Current
+            popover.Current ??= App?.Current;
+
+            if (popover is View popoverView)
+            {
+                popoverView.App = App;
+            }
 
             _popovers.Add (popover);
         }
@@ -46,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.
@@ -59,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;
         }
@@ -100,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;
         }
@@ -120,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 ();
@@ -148,7 +166,7 @@ public sealed class ApplicationPopover : IDisposable
         {
             _activePopover = null;
             popoverView.Visible = false;
-            Application.Top?.SetNeedsDraw ();
+            popoverView.App?.Current?.SetNeedsDraw ();
         }
     }
 
@@ -177,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 })
         {
@@ -197,13 +215,14 @@ public sealed class ApplicationPopover : IDisposable
         {
             if (popover == activePopover
                 || popover is not View popoverView
-                || (popover.Toplevel is { } && popover.Toplevel != Application.Top))
+                || (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)

+ 1 - 2
Terminal.Gui/App/CWP/CWPEventHelper.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 using System;
@@ -53,4 +52,4 @@ public static class CWPEventHelper
         eventHandler.Invoke (null, args);
         return args.Handled;
     }
-}
+}

+ 0 - 2
Terminal.Gui/App/CWP/CWPPropertyHelper.cs

@@ -1,7 +1,5 @@
 namespace Terminal.Gui.App;
 
-#nullable enable
-
 /// <summary>
 ///     Provides helper methods for executing property change workflows in the Cancellable Work Pattern (CWP).
 /// </summary>

+ 1 - 2
Terminal.Gui/App/CWP/CWPWorkflowHelper.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 using System;
@@ -126,4 +125,4 @@ public static class CWPWorkflowHelper
         }
         return args.Result!;
     }
-}
+}

+ 0 - 1
Terminal.Gui/App/CWP/CancelEventArgs.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.ComponentModel;
 
 namespace Terminal.Gui.App;

+ 0 - 1
Terminal.Gui/App/CWP/EventArgs.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 #pragma warning disable CS1711

+ 1 - 2
Terminal.Gui/App/CWP/ResultEventArgs.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 using System;
@@ -42,4 +41,4 @@ public class ResultEventArgs<T>
         Result = result;
     }
 }
-#pragma warning restore CS1711
+#pragma warning restore CS1711

+ 0 - 1
Terminal.Gui/App/CWP/ValueChangedEventArgs.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>

+ 1 - 2
Terminal.Gui/App/CWP/ValueChangingEventArgs.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>
@@ -41,4 +40,4 @@ public class ValueChangingEventArgs<T>
         CurrentValue = currentValue;
         NewValue = newValue;
     }
-}
+}

+ 2 - 3
Terminal.Gui/App/Clipboard/Clipboard.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>Provides cut, copy, and paste support for the OS clipboard.</summary>
@@ -31,7 +30,7 @@ public static class Clipboard
                 if (IsSupported)
                 {
                     // throw new InvalidOperationException ($"{Application.Driver?.GetType ().Name}.GetClipboardData returned null instead of string.Empty");
-                    string? clipData = Application.Driver?.Clipboard?.GetClipboardData () ?? string.Empty;
+                    string clipData = Application.Driver?.Clipboard?.GetClipboardData () ?? string.Empty;
 
                     _contents = clipData;
                 }
@@ -66,4 +65,4 @@ public static class Clipboard
     /// <summary>Returns true if the environmental dependencies are in place to interact with the OS clipboard.</summary>
     /// <remarks></remarks>
     public static bool IsSupported => Application.Driver?.Clipboard?.IsSupported ?? false;
-}
+}

+ 1 - 0
Terminal.Gui/App/Clipboard/ClipboardBase.cs

@@ -1,3 +1,4 @@
+#nullable disable
 using System.Diagnostics;
 
 namespace Terminal.Gui.App;

+ 0 - 2
Terminal.Gui/App/Clipboard/ClipboardProcessRunner.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics;
 
 namespace Terminal.Gui.App;
@@ -45,7 +44,6 @@ internal static class ClipboardProcessRunner
             CreateNoWindow = true
         };
 
-        TaskCompletionSource<bool> eventHandled = new ();
         process.Start ();
 
         if (!string.IsNullOrEmpty (input))

+ 37 - 23
Terminal.Gui/App/IApplication.cs

@@ -1,5 +1,4 @@
-#nullable enable
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
 using System.Diagnostics.CodeAnalysis;
 
 namespace Terminal.Gui.App;
@@ -41,14 +40,9 @@ public interface IApplication
     #region Initialization and Shutdown
 
     /// <summary>Initializes a new instance of <see cref="Terminal.Gui"/> Application.</summary>
-    /// <param name="driver">
-    ///     The <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or
-    ///     <paramref name="driverName"/> are specified the default driver for the platform will be used.
-    /// </param>
     /// <param name="driverName">
     ///     The short name (e.g. "dotnet", "windows", "unix", or "fake") of the
-    ///     <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
-    ///     specified the default driver for the platform will be used.
+    ///     <see cref="IDriver"/> to use. If not specified the default driver for the platform will be used.
     /// </param>
     /// <remarks>
     ///     <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
@@ -61,14 +55,14 @@ public interface IApplication
     ///         <see cref="Run{T}"/> has returned) to ensure resources are cleaned up and terminal settings restored.
     ///     </para>
     ///     <para>
-    ///         The <see cref="Run{T}"/> function combines <see cref="Init(IDriver,string)"/> and
+    ///         The <see cref="Run{T}"/> function combines <see cref="Init(string)"/> and
     ///         <see cref="Run(Toplevel, Func{Exception, bool})"/> into a single call. An application can use
-    ///         <see cref="Run{T}"/> without explicitly calling <see cref="Init(IDriver,string)"/>.
+    ///         <see cref="Run{T}"/> without explicitly calling <see cref="Init(string)"/>.
     ///     </para>
     /// </remarks>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public void Init (IDriver? driver = null, string? driverName = null);
+    public void Init (string? driverName = null);
 
     /// <summary>
     ///     This event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
@@ -137,7 +131,7 @@ public interface IApplication
     ///     stopped, <see cref="End(SessionToken)"/> will be called.
     /// </summary>
     /// <param name="errorHandler">Handler for any unhandled exceptions (resumes when returns true, rethrows when null).</param>
-    /// <param name="driver">
+    /// <param name="driverName">
     ///     The driver name. If not specified the default driver for the platform will be used. Must be
     ///     <see langword="null"/> if <see cref="Init"/> has already been called.
     /// </param>
@@ -154,7 +148,7 @@ public interface IApplication
     /// </remarks>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driver = null);
+    public Toplevel Run (Func<Exception, bool>? errorHandler = null, string? driverName = null);
 
     /// <summary>
     ///     Runs a new Session creating a <see cref="Toplevel"/>-derived object of type <typeparamref name="TView"/>
@@ -163,7 +157,7 @@ public interface IApplication
     /// </summary>
     /// <typeparam name="TView">The type of <see cref="Toplevel"/> to create and run.</typeparam>
     /// <param name="errorHandler">Handler for any unhandled exceptions (resumes when returns true, rethrows when null).</param>
-    /// <param name="driver">
+    /// <param name="driverName">
     ///     The driver name. If not specified the default driver for the platform will be used. Must be
     ///     <see langword="null"/> if <see cref="Init"/> has already been called.
     /// </param>
@@ -206,7 +200,7 @@ public interface IApplication
     /// </remarks>
     [RequiresUnreferencedCode ("AOT")]
     [RequiresDynamicCode ("AOT")]
-    public TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driver = null)
+    public TView Run<TView> (Func<Exception, bool>? errorHandler = null, string? driverName = null)
         where TView : Toplevel, new ();
 
     /// <summary>
@@ -266,6 +260,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>
@@ -296,14 +301,14 @@ public interface IApplication
     /// <remarks>
     ///     <para>This will cause <see cref="Run(Toplevel, Func{Exception, bool})"/> to return.</para>
     ///     <para>
-    ///         This is equivalent to calling <see cref="RequestStop(Toplevel)"/> with <see cref="Top"/> as the parameter.
+    ///         This is equivalent to calling <see cref="RequestStop(Toplevel)"/> with <see cref="Current"/> as the parameter.
     ///     </para>
     /// </remarks>
     void RequestStop ();
 
     /// <summary>Requests that the currently running Session stop. The Session will stop after the current iteration completes.</summary>
     /// <param name="top">
-    ///     The <see cref="Toplevel"/> to stop. If <see langword="null"/>, stops the currently running <see cref="Top"/>.
+    ///     The <see cref="Toplevel"/> to stop. If <see langword="null"/>, stops the currently running <see cref="Current"/>.
     /// </param>
     /// <remarks>
     ///     <para>This will cause <see cref="Run(Toplevel, Func{Exception, bool})"/> to return.</para>
@@ -351,22 +356,22 @@ public interface IApplication
 
     #region Toplevel Management
 
-    /// <summary>Gets or sets the current Toplevel.</summary>
+    /// <summary>Gets or sets the currently active Toplevel.</summary>
     /// <remarks>
     ///     <para>
     ///         This is set by <see cref="Begin(Toplevel)"/> and cleared by <see cref="End(SessionToken)"/>.
     ///     </para>
     /// </remarks>
-    Toplevel? Top { get; set; }
+    Toplevel? Current { get; set; }
 
-    /// <summary>Gets the stack of all Toplevels.</summary>
+    /// <summary>Gets the stack of all active Toplevel sessions.</summary>
     /// <remarks>
     ///     <para>
     ///         Toplevels are added to this stack by <see cref="Begin(Toplevel)"/> and removed by
     ///         <see cref="End(SessionToken)"/>.
     ///     </para>
     /// </remarks>
-    ConcurrentStack<Toplevel> TopLevels { get; }
+    ConcurrentStack<Toplevel> SessionStack { get; }
 
     /// <summary>
     ///     Caches the Toplevel associated with the current Session.
@@ -428,7 +433,7 @@ public interface IApplication
     /// <remarks>
     ///     <para>
     ///         This is typically set to <see langword="true"/> when a View's <see cref="View.Frame"/> changes and that view
-    ///         has no SuperView (e.g. when <see cref="Top"/> is moved or resized).
+    ///         has no SuperView (e.g. when <see cref="Current"/> is moved or resized).
     ///     </para>
     ///     <para>
     ///         Automatically reset to <see langword="false"/> after <see cref="LayoutAndDraw"/> processes it.
@@ -509,12 +514,15 @@ public interface IApplication
     ///     returns <see langword="false"/>, the timeout will stop and be removed.
     /// </param>
     /// <returns>
-    ///     A token that can be used to stop the timeout by calling <see cref="RemoveTimeout(object)"/>.
+    ///     Call <see cref="RemoveTimeout(object)"/> with the returned value to stop the timeout.
     /// </returns>
     /// <remarks>
     ///     <para>
     ///         When the time specified passes, the callback will be invoked on the main UI thread.
     ///     </para>
+    ///     <para>
+    ///         <see cref="IApplication.Shutdown"/> calls StopAll on <see cref="TimedEvents"/> to remove all timeouts.
+    ///     </para>
     /// </remarks>
     object AddTimeout (TimeSpan time, Func<bool> callback);
 
@@ -539,4 +547,10 @@ 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 ();
 }

+ 5 - 6
Terminal.Gui/App/IPopover.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
@@ -51,12 +50,12 @@ namespace Terminal.Gui.App;
 public interface IPopover
 {
     /// <summary>
-    ///     Gets or sets the <see cref="Toplevel"/> that this Popover is associated with. If null, it is not associated with
+    ///     Gets or sets the <see cref="Current"/> that this Popover is associated with. If null, it is not associated with
     ///     any Toplevel and will receive all keyboard
-    ///     events from the <see cref="Application"/>. If set, it will only receive keyboard events the Toplevel would normally
+    ///     events from the <see cref="IApplication"/>. If set, it will only receive keyboard events the Toplevel would normally
     ///     receive.
-    ///     When <see cref="ApplicationPopover.Register"/> is called, the <see cref="Toplevel"/> is set to the current
-    ///     <see cref="Application.Top"/> if not already set.
+    ///     When <see cref="ApplicationPopover.Register"/> is called, the <see cref="Current"/> is set to the current
+    ///     <see cref="IApplication.Current"/> if not already set.
     /// </summary>
-    Toplevel? Toplevel { get; set; }
+    Toplevel? Current { get; set; }
 }

+ 2 - 3
Terminal.Gui/App/Keyboard/IKeyboard.cs

@@ -1,10 +1,9 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>
 ///     Defines a contract for managing keyboard input and key bindings at the Application level.
 ///     <para>
-///         This interface decouples keyboard handling state from the static <see cref="Application"/> class,
+///         This interface decouples keyboard handling state from the static <see cref="App"/> class,
 ///         enabling parallelizable unit tests and better testability.
 ///     </para>
 /// </summary>
@@ -14,7 +13,7 @@ public interface IKeyboard
     /// Sets the application instance that this keyboard 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>
     ///     Called when the user presses a key (by the <see cref="IDriver"/>). Raises the cancelable

+ 18 - 21
Terminal.Gui/App/Keyboard/KeyboardImpl.cs

@@ -1,12 +1,9 @@
-#nullable enable
-using System.Diagnostics;
-
 namespace Terminal.Gui.App;
 
 /// <summary>
 ///     INTERNAL: Implements <see cref="IKeyboard"/> to manage keyboard input and key bindings at the Application level.
 ///     <para>
-///         This implementation decouples keyboard handling state from the static <see cref="Application"/> class,
+///         This implementation decouples keyboard handling state from the static <see cref="App"/> class,
 ///         enabling parallelizable unit tests and better testability.
 ///     </para>
 ///     <para>
@@ -28,7 +25,7 @@ internal class KeyboardImpl : IKeyboard
     private readonly Dictionary<Command, View.CommandImplementation> _commandImplementations = new ();
 
     /// <inheritdoc/>
-    public IApplication? Application { get; set; }
+    public IApplication? App { get; set; }
 
     /// <inheritdoc/>
     public KeyBindings KeyBindings { get; internal set; } = new (null);
@@ -136,16 +133,16 @@ internal class KeyboardImpl : IKeyboard
             return true;
         }
 
-        if (Application?.Popover?.DispatchKeyDown (key) is true)
+        if (App?.Popover?.DispatchKeyDown (key) is true)
         {
             return true;
         }
 
-        if (Application?.Top is null)
+        if (App?.Current is null)
         {
-            if (Application?.TopLevels is { })
+            if (App?.SessionStack is { })
             {
-                foreach (Toplevel topLevel in Application.TopLevels.ToList ())
+                foreach (Toplevel topLevel in App.SessionStack.ToList ())
                 {
                     if (topLevel.NewKeyDownEvent (key))
                     {
@@ -161,7 +158,7 @@ internal class KeyboardImpl : IKeyboard
         }
         else
         {
-            if (Application.Top.NewKeyDownEvent (key))
+            if (App.Current.NewKeyDownEvent (key))
             {
                 return true;
             }
@@ -179,7 +176,7 @@ internal class KeyboardImpl : IKeyboard
     /// <inheritdoc/>
     public bool RaiseKeyUpEvent (Key key)
     {
-        if (Application?.Initialized != true)
+        if (App?.Initialized != true)
         {
             return true;
         }
@@ -194,9 +191,9 @@ internal class KeyboardImpl : IKeyboard
 
         // TODO: Add Popover support
 
-        if (Application?.TopLevels is { })
+        if (App?.SessionStack is { })
         {
-            foreach (Toplevel topLevel in Application.TopLevels.ToList ())
+            foreach (Toplevel topLevel in App.SessionStack.ToList ())
             {
                 if (topLevel.NewKeyUpEvent (key))
                 {
@@ -294,7 +291,7 @@ internal class KeyboardImpl : IKeyboard
                     Command.Quit,
                     () =>
                     {
-                        Application?.RequestStop ();
+                        App?.RequestStop ();
 
                         return true;
                     }
@@ -303,32 +300,32 @@ internal class KeyboardImpl : IKeyboard
                     Command.Suspend,
                     () =>
                     {
-                        Application?.Driver?.Suspend ();
+                        App?.Driver?.Suspend ();
 
                         return true;
                     }
                    );
         AddCommand (
                     Command.NextTabStop,
-                    () => Application?.Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop));
+                    () => App?.Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop));
 
         AddCommand (
                     Command.PreviousTabStop,
-                    () => Application?.Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop));
+                    () => App?.Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop));
 
         AddCommand (
                     Command.NextTabGroup,
-                    () => Application?.Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup));
+                    () => App?.Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup));
 
         AddCommand (
                     Command.PreviousTabGroup,
-                    () => Application?.Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup));
+                    () => App?.Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup));
 
         AddCommand (
                     Command.Refresh,
                     () =>
                     {
-                        Application?.LayoutAndDraw (true);
+                        App?.LayoutAndDraw (true);
 
                         return true;
                     }
@@ -338,7 +335,7 @@ internal class KeyboardImpl : IKeyboard
                     Command.Arrange,
                     () =>
                     {
-                        View? viewToArrange = Application?.Navigation?.GetFocused ();
+                        View? viewToArrange = App?.Navigation?.GetFocused ();
 
                         // Go up the superview hierarchy and find the first that is not ViewArrangement.Fixed
                         while (viewToArrange is { SuperView: { }, Arrangement: ViewArrangement.Fixed })

+ 19 - 16
Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs

@@ -1,8 +1,5 @@
-#nullable enable
-using System;
 using System.Collections.Concurrent;
 using System.Diagnostics;
-using Terminal.Gui.Drivers;
 
 namespace Terminal.Gui.App;
 
@@ -30,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
     {
@@ -82,7 +82,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
     }
 
     /// <summary>
-    ///     Handles raising events and setting required draw status etc when <see cref="Application.Top"/> changes
+    ///     Handles raising events and setting required draw status etc when <see cref="IApplication.Current"/> changes
     /// </summary>
     public IToplevelTransitionManager ToplevelTransitionManager = new ToplevelTransitionManager ();
 
@@ -94,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;
@@ -116,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,14 +142,14 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
         // Pull any input events from the input queue and process them
         InputProcessor.ProcessQueue ();
 
-        ToplevelTransitionManager.RaiseReadyEventIfNeeded ();
-        ToplevelTransitionManager.HandleTopMaybeChanging ();
+        ToplevelTransitionManager.RaiseReadyEventIfNeeded (App);
+        ToplevelTransitionManager.HandleTopMaybeChanging (App);
 
-        if (Application.Top != null)
+        if (App?.Current != null)
         {
-            bool needsDrawOrLayout = AnySubViewsNeedDrawn (Application.Popover?.GetActivePopover () as View)
-                                     || AnySubViewsNeedDrawn (Application.Top)
-                                     || (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 ();
 
@@ -154,7 +157,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
             {
                 Logging.Redraws.Add (1);
 
-                Application.LayoutAndDraw (true);
+                App?.LayoutAndDraw (true);
 
                 Output.Write (OutputBuffer);
 
@@ -173,7 +176,7 @@ public class ApplicationMainLoop<TInputRecord> : IApplicationMainLoop<TInputReco
 
     private void SetCursor ()
     {
-        View? mostFocused = Application.Top!.MostFocused;
+        View? mostFocused = App?.Current!.MostFocused;
 
         if (mostFocused == null)
         {
@@ -205,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 - 2
Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Collections.Concurrent;
 
 namespace Terminal.Gui.App;
@@ -18,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>
@@ -73,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
@@ -98,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.

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

@@ -46,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 ();
@@ -107,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}");
 
@@ -121,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)
@@ -139,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}");
@@ -149,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
         {
@@ -165,7 +167,7 @@ internal class MainLoopCoordinator<TInputRecord> : IMainLoopCoordinator where TI
                     impl.InputImpl = _input;
                 }
 
-                BuildDriverIfPossible ();
+                BuildDriverIfPossible (app);
             }
 
             try

+ 37 - 36
Terminal.Gui/App/MainLoop/MainLoopSyncContext.cs

@@ -1,42 +1,43 @@
+#nullable disable
 namespace Terminal.Gui.App;
 
-/// <summary>
-///     provides the sync context set while executing code in Terminal.Gui, to let
-///     users use async/await on their code
-/// </summary>
-internal sealed class MainLoopSyncContext : SynchronizationContext
-{
-    public override SynchronizationContext CreateCopy () { return new MainLoopSyncContext (); }
+///// <summary>
+/////     provides the sync context set while executing code in Terminal.Gui, to let
+/////     users use async/await on their code
+///// </summary>
+//internal sealed class MainLoopSyncContext : SynchronizationContext
+//{
+//    public override SynchronizationContext CreateCopy () { return new MainLoopSyncContext (); }
 
-    public override void Post (SendOrPostCallback d, object state)
-    {
-        // Queue the task using the modern architecture
-        ApplicationImpl.Instance.Invoke (() => { d (state); });
-    }
+//    public override void Post (SendOrPostCallback d, object state)
+//    {
+//        // Queue the task using the modern architecture
+//        ApplicationImpl.Instance.Invoke (() => { d (state); });
+//    }
 
-    //_mainLoop.Driver.Wakeup ();
-    public override void Send (SendOrPostCallback d, object state)
-    {
-        if (Thread.CurrentThread.ManagedThreadId == Application.MainThreadId)
-        {
-            d (state);
-        }
-        else
-        {
-            var wasExecuted = false;
+//    //_mainLoop.Driver.Wakeup ();
+//    public override void Send (SendOrPostCallback d, object state)
+//    {
+//        if (Thread.CurrentThread.ManagedThreadId == Application.MainThreadId)
+//        {
+//            d (state);
+//        }
+//        else
+//        {
+//            var wasExecuted = false;
 
-            Application.Invoke (
-                                () =>
-                                {
-                                    d (state);
-                                    wasExecuted = true;
-                                }
-                               );
+//            ApplicationImpl.Instance.Invoke (
+//                                             () =>
+//                                             {
+//                                                 d (state);
+//                                                 wasExecuted = true;
+//                                             }
+//                                            );
 
-            while (!wasExecuted)
-            {
-                Thread.Sleep (15);
-            }
-        }
-    }
-}
+//            while (!wasExecuted)
+//            {
+//                Thread.Sleep (15);
+//            }
+//        }
+//    }
+//}

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

@@ -1,4 +1,3 @@
-#nullable enable
 using System.ComponentModel;
 
 namespace Terminal.Gui.App;
@@ -6,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>
@@ -16,18 +15,13 @@ 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.
     /// </summary>
     Point? LastMousePosition { get; set; }
 
-    /// <summary>
-    ///     Gets the most recent position of the mouse.
-    /// </summary>
-    Point? GetLastMousePosition ();
-
     /// <summary>
     ///     Gets or sets whether the mouse is disabled. The mouse is enabled by default.
     /// </summary>

+ 0 - 1
Terminal.Gui/App/Mouse/IMouseGrabHandler.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>

+ 0 - 1
Terminal.Gui/App/Mouse/MouseGrabHandler.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>

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

@@ -1,13 +1,11 @@
-#nullable enable
 using System.ComponentModel;
-using System.Diagnostics;
 
 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>
@@ -19,14 +17,11 @@ internal class MouseImpl : IMouse
     public MouseImpl () { }
 
     /// <inheritdoc/>
-    public IApplication? Application { get; set; }
+    public IApplication? App { get; set; }
 
     /// <inheritdoc/>
     public Point? LastMousePosition { get; set; }
 
-    /// <inheritdoc/>
-    public Point? GetLastMousePosition () { return LastMousePosition; }
-
     /// <inheritdoc/>
     public bool IsMouseDisabled { get; set; }
 
@@ -57,7 +52,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;
@@ -72,9 +67,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 { })
         {
@@ -96,7 +91,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);
@@ -119,9 +114,9 @@ internal class MouseImpl : IMouse
             return;
         }
 
-        // if the mouse is outside the Application.Top 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?.Top, 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;
         }
@@ -161,7 +156,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 { })
         {

+ 17 - 5
Terminal.Gui/App/PopoverBaseImpl.cs

@@ -1,4 +1,3 @@
-#nullable enable
 
 namespace Terminal.Gui.App;
 
@@ -74,8 +73,18 @@ public abstract class PopoverBaseImpl : View, IPopover
         }
     }
 
+    private Toplevel? _current;
+
     /// <inheritdoc/>
-    public Toplevel? Toplevel { get; set; }
+    public Toplevel? Current
+    {
+        get => _current;
+        set
+        {
+            _current = value;
+            App ??= _current?.App;
+        }
+    }
 
     /// <summary>
     ///     Called when the <see cref="View.Visible"/> property is changing.
@@ -100,14 +109,17 @@ public abstract class PopoverBaseImpl : View, IPopover
         {
             // Whenever visible is changing to true, we need to resize;
             // it's our only chance because we don't get laid out until we're visible
-            Layout (Application.Screen.Size);
+            if (App is { })
+            {
+                Layout (App.Screen.Size);
+            }
         }
         else
         {
             // Whenever visible is changing to false, we need to reset the focus
-            if (ApplicationNavigation.IsInHierarchy (this, Application.Navigation?.GetFocused ()))
+            if (ApplicationNavigation.IsInHierarchy (this, App?.Navigation?.GetFocused ()))
             {
-                Application.Navigation?.SetFocused (Application.Top?.MostFocused);
+                App?.Navigation?.SetFocused (App?.Current?.MostFocused);
             }
         }
 

+ 1 - 1
Terminal.Gui/App/SessionToken.cs

@@ -10,7 +10,7 @@ public class SessionToken : IDisposable
     public SessionToken (Toplevel view) { Toplevel = view; }
 
     /// <summary>The <see cref="Toplevel"/> belonging to this <see cref="SessionToken"/>.</summary>
-    public Toplevel Toplevel { get; internal set; }
+    public Toplevel? Toplevel { get; internal set; }
 
     /// <summary>Releases all resource used by the <see cref="SessionToken"/> object.</summary>
     /// <remarks>Call <see cref="Dispose()"/> when you are finished using the <see cref="SessionToken"/>.</remarks>

+ 10 - 1
Terminal.Gui/App/Timeout/ITimedEvents.cs

@@ -1,4 +1,3 @@
-#nullable enable
 namespace Terminal.Gui.App;
 
 /// <summary>
@@ -49,4 +48,14 @@ public interface ITimedEvents
     ///     for each timeout that is not actively executing.
     /// </summary>
     SortedList<long, Timeout> Timeouts { get; }
+
+    /// <summary>
+    ///     Gets the timeout for the specified event.
+    /// </summary>
+    /// <param name="token">The token of the event.</param>
+    /// <returns>The <see cref="TimeSpan"/> for the event, or <see lang="null"/> if the event is not found.</returns>
+    TimeSpan? GetTimeout (object token);
+
+    /// <summary>Stops and removes all timed events.</summary>
+    void StopAll ();
 }

+ 1 - 0
Terminal.Gui/App/Timeout/LogarithmicTimeout.cs

@@ -1,3 +1,4 @@
+#nullable disable
 namespace Terminal.Gui.App;
 
 /// <summary>Implements a logarithmic increasing timeout.</summary>

+ 1 - 0
Terminal.Gui/App/Timeout/SmoothAcceleratingTimeout.cs

@@ -1,3 +1,4 @@
+#nullable disable
 namespace Terminal.Gui.App;
 
 /// <summary>

+ 26 - 2
Terminal.Gui/App/Timeout/TimedEvents.cs

@@ -1,4 +1,3 @@
-#nullable enable
 using System.Diagnostics;
 
 namespace Terminal.Gui.App;
@@ -145,6 +144,22 @@ public class TimedEvents : ITimedEvents
         return false;
     }
 
+    /// <inheritdoc/>
+    public TimeSpan? GetTimeout (object token)
+    {
+        lock (_timeoutsLockToken)
+        {
+            int idx = _timeouts.IndexOfValue ((token as Timeout)!);
+
+            if (idx == -1)
+            {
+                return null;
+            }
+
+            return _timeouts.Values [idx].Span;
+        }
+    }
+
     private void AddTimeout (TimeSpan time, Timeout timeout)
     {
         lock (_timeoutsLockToken)
@@ -202,7 +217,7 @@ public class TimedEvents : ITimedEvents
         {
             if (k < now)
             {
-                if (timeout.Callback ())
+                if (timeout.Callback! ())
                 {
                     AddTimeout (timeout.Span, timeout);
                 }
@@ -216,4 +231,13 @@ public class TimedEvents : ITimedEvents
             }
         }
     }
+
+    /// <inheritdoc/>
+    public void StopAll ()
+    {
+        lock (_timeoutsLockToken)
+        {
+            _timeouts.Clear ();
+        }
+    }
 }

+ 1 - 1
Terminal.Gui/App/Timeout/Timeout.cs

@@ -20,7 +20,7 @@ public class Timeout
     ///     rescheduled and invoked again after the same interval.
     ///     If the callback returns <see langword="false"/>, the timeout will be removed and not invoked again.
     /// </value>
-    public Func<bool> Callback { get; set; }
+    public Func<bool>? Callback { get; set; }
 
     /// <summary>
     ///     Gets or sets the time interval to wait before invoking the <see cref="Callback"/>.

+ 5 - 3
Terminal.Gui/App/Toplevel/IToplevelTransitionManager.cs

@@ -7,14 +7,16 @@
 public interface IToplevelTransitionManager
 {
     /// <summary>
-    ///     Raises the <see cref="Toplevel.Ready"/> event on the current top level
+    ///     Raises the <see cref="Toplevel.Ready"/> event on tahe current top level
     ///     if it has not been raised before now.
     /// </summary>
-    void RaiseReadyEventIfNeeded ();
+    /// <param name="app"></param>
+    void RaiseReadyEventIfNeeded (IApplication? app);
 
     /// <summary>
     ///     Handles any state change needed when the application top changes e.g.
     ///     setting redraw flags
     /// </summary>
-    void HandleTopMaybeChanging ();
+    /// <param name="app"></param>
+    void HandleTopMaybeChanging (IApplication? app);
 }

+ 7 - 8
Terminal.Gui/App/Toplevel/ToplevelTransitionManager.cs

@@ -1,6 +1,3 @@
-#nullable enable
-using Terminal.Gui.Drivers;
-
 namespace Terminal.Gui.App;
 
 /// <summary>
@@ -12,10 +9,11 @@ public class ToplevelTransitionManager : IToplevelTransitionManager
 
     private View? _lastTop;
 
+    /// <param name="app"></param>
     /// <inheritdoc/>
-    public void RaiseReadyEventIfNeeded ()
+    public void RaiseReadyEventIfNeeded (IApplication? app)
     {
-        Toplevel? top = Application.Top;
+        Toplevel? top = app?.Current;
 
         if (top != null && !_readiedTopLevels.Contains (top))
         {
@@ -27,16 +25,17 @@ public class ToplevelTransitionManager : IToplevelTransitionManager
         }
     }
 
+    /// <param name="app"></param>
     /// <inheritdoc/>
-    public void HandleTopMaybeChanging ()
+    public void HandleTopMaybeChanging (IApplication? app)
     {
-        Toplevel? newTop = Application.Top;
+        Toplevel? newTop = app?.Current;
 
         if (_lastTop != null && _lastTop != newTop && newTop != null)
         {
             newTop.SetNeedsDraw ();
         }
 
-        _lastTop = Application.Top;
+        _lastTop = app?.Current;
     }
 }

+ 1 - 2
Terminal.Gui/Configuration/AppSettingsScope.cs

@@ -1,5 +1,4 @@
-#nullable enable
-using System.Text.Json.Serialization;
+using System.Text.Json.Serialization;
 
 namespace Terminal.Gui.Configuration;
 

+ 2 - 2
Terminal.Gui/Configuration/AttributeJsonConverter.cs

@@ -9,7 +9,7 @@ namespace Terminal.Gui.Configuration;
 
 internal class AttributeJsonConverter : JsonConverter<Attribute>
 {
-    private static AttributeJsonConverter _instance;
+    private static AttributeJsonConverter? _instance;
 
     /// <summary></summary>
     public static AttributeJsonConverter Instance
@@ -63,7 +63,7 @@ internal class AttributeJsonConverter : JsonConverter<Attribute>
                 throw new JsonException ($"{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.");
             }
 
-            propertyName = reader.GetString ();
+            propertyName = reader.GetString ()!;
             reader.Read ();
             var property = $"\"{reader.GetString ()}\"";
 

+ 1 - 1
Terminal.Gui/Configuration/ColorJsonConverter.cs

@@ -15,7 +15,7 @@ namespace Terminal.Gui.Configuration;
 /// </summary>
 internal class ColorJsonConverter : JsonConverter<Color>
 {
-    private static ColorJsonConverter _instance;
+    private static ColorJsonConverter? _instance;
 
     /// <summary>Singleton</summary>
     public static ColorJsonConverter Instance

+ 1 - 0
Terminal.Gui/Configuration/ConcurrentDictionaryJsonConverter.cs

@@ -1,3 +1,4 @@
+#nullable disable
 using System.Collections.Concurrent;
 using System.Diagnostics.CodeAnalysis;
 using System.Text.Json;

+ 1 - 2
Terminal.Gui/Configuration/ConfigLocations.cs

@@ -1,5 +1,4 @@
-#nullable enable
-namespace Terminal.Gui.Configuration;
+namespace Terminal.Gui.Configuration;
 
 /// <summary>
 ///     Describes the location of the configuration settings. The constants can be combined (bitwise) to specify multiple

+ 1 - 2
Terminal.Gui/Configuration/ConfigProperty.cs

@@ -1,5 +1,4 @@
-#nullable enable
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
 using System.Collections.Immutable;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;

+ 1 - 3
Terminal.Gui/Configuration/ConfigurationManager.cs

@@ -1,6 +1,4 @@
-#nullable enable
-
-using System.Collections.Frozen;
+using System.Collections.Frozen;
 using System.Collections.Immutable;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;

+ 1 - 3
Terminal.Gui/Configuration/ConfigurationManagerEventArgs.cs

@@ -1,6 +1,4 @@
-#nullable enable
-
-namespace Terminal.Gui.Configuration;
+namespace Terminal.Gui.Configuration;
 
 /// <summary>Event arguments for the <see cref="ConfigurationManager"/> events.</summary>
 public class ConfigurationManagerEventArgs : EventArgs

Some files were not shown because too many files changed in this diff