Przeglądaj źródła

Merge branch 'gui-cs:v2_develop' into v2_develop

Tig 1 miesiąc temu
rodzic
commit
55468fa3fd
100 zmienionych plików z 1196 dodań i 6401 usunięć
  1. 3 3
      .editorconfig
  2. 12 12
      Examples/UICatalog/Scenarios/Adornments.cs
  3. 1 1
      Examples/UICatalog/Scenarios/AllViewsTester.cs
  4. 1 1
      Examples/UICatalog/Scenarios/AnsiRequestsScenario.cs
  5. 1 1
      Examples/UICatalog/Scenarios/Bars.cs
  6. 1 1
      Examples/UICatalog/Scenarios/Clipping.cs
  7. 1 1
      Examples/UICatalog/Scenarios/DimAutoDemo.cs
  8. 3 3
      Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentsEditor.cs
  9. 5 5
      Examples/UICatalog/Scenarios/GraphViewExample.cs
  10. 3 3
      Examples/UICatalog/Scenarios/LineCanvasExperiment.cs
  11. 4 4
      Examples/UICatalog/Scenarios/PosAlignDemo.cs
  12. 1 1
      Examples/UICatalog/Scenarios/Shortcuts.cs
  13. 2 2
      Examples/UICatalog/Scenarios/ViewportSettings.cs
  14. 1 1
      Examples/UICatalog/Scenarios/WindowsAndFrameViews.cs
  15. 2 2
      Examples/UICatalog/UICatalog.cs
  16. 3 2
      Terminal.Gui.Analyzers.Tests/HandledEventArgsAnalyzerTests.cs
  17. 4 111
      Terminal.Gui/App/Application.Lifecycle.cs
  18. 7 7
      Terminal.Gui/App/Application.Run.cs
  19. 8 20
      Terminal.Gui/App/Application.Screen.cs
  20. 8 0
      Terminal.Gui/App/Application.Toplevel.cs
  21. 5 5
      Terminal.Gui/App/Application.cs
  22. 21 34
      Terminal.Gui/App/ApplicationImpl.cs
  23. 5 0
      Terminal.Gui/App/IApplication.cs
  24. 6 6
      Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs
  25. 1 1
      Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs
  26. 1 1
      Terminal.Gui/App/MainLoop/MainLoopCoordinator.cs
  27. 0 12
      Terminal.Gui/App/Timeout/ITimedEvents.cs
  28. 8 5
      Terminal.Gui/Drawing/Ruler.cs
  29. 6 6
      Terminal.Gui/Drawing/Sixel/SixelSupportDetector.cs
  30. 32 29
      Terminal.Gui/Drawing/Thickness.cs
  31. 55 925
      Terminal.Gui/Drivers/AnsiHandling/EscSeqUtils/EscSeqUtils.cs
  32. 1 1
      Terminal.Gui/Drivers/AnsiHandling/Osc8UrlLinker.cs
  33. 2 2
      Terminal.Gui/Drivers/ComponentFactory.cs
  34. 31 19
      Terminal.Gui/Drivers/ConsoleDriver.cs
  35. 37 25
      Terminal.Gui/Drivers/ConsoleDriverFacade.cs
  36. 1 1
      Terminal.Gui/Drivers/ConsoleKeyMapping.cs
  37. 35 0
      Terminal.Gui/Drivers/ConsoleSizeMonitor.cs
  38. 7 1
      Terminal.Gui/Drivers/DotNetDriver/NetOutput.cs
  39. 59 0
      Terminal.Gui/Drivers/FakeDriver/FakeClipboard.cs
  40. 3 2
      Terminal.Gui/Drivers/FakeDriver/FakeComponentFactory.cs
  41. 3 3
      Terminal.Gui/Drivers/FakeDriver/FakeConsole.cs
  42. 16 30
      Terminal.Gui/Drivers/FakeDriver/FakeConsoleOutput.cs
  43. 33 177
      Terminal.Gui/Drivers/FakeDriver/FakeDriver.cs
  44. 0 41
      Terminal.Gui/Drivers/FakeDriver/FakeWindowSizeMonitor.cs
  45. 3 3
      Terminal.Gui/Drivers/IComponentFactory.cs
  46. 14 8
      Terminal.Gui/Drivers/IConsoleDriver.cs
  47. 1 1
      Terminal.Gui/Drivers/IConsoleDriverFacade.cs
  48. 9 2
      Terminal.Gui/Drivers/IConsoleOutput.cs
  49. 3 3
      Terminal.Gui/Drivers/IConsoleSizeMonitor.cs
  50. 1 1
      Terminal.Gui/Drivers/IInputProcessor.cs
  51. 1 1
      Terminal.Gui/Drivers/IOutputBuffer.cs
  52. 2 2
      Terminal.Gui/Drivers/InputProcessor.cs
  53. 1 1
      Terminal.Gui/Drivers/MouseButtonStateEx.cs
  54. 1 1
      Terminal.Gui/Drivers/OutputBase.cs
  55. 3 3
      Terminal.Gui/Drivers/OutputBuffer.cs
  56. 7 1
      Terminal.Gui/Drivers/UnixDriver/UnixOutput.cs
  57. 0 42
      Terminal.Gui/Drivers/WindowSizeMonitor.cs
  58. 31 908
      Terminal.Gui/Drivers/WindowsDriver/WindowsConsole.cs
  59. 9 8
      Terminal.Gui/Drivers/WindowsDriver/WindowsInput.cs
  60. 7 1
      Terminal.Gui/Drivers/WindowsDriver/WindowsOutput.cs
  61. 6 6
      Terminal.Gui/ViewBase/Adornment/Border.Arrangment.cs
  62. 1 1
      Terminal.Gui/ViewBase/Adornment/Border.cs
  63. 7 7
      Terminal.Gui/ViewBase/Adornment/Margin.cs
  64. 2 2
      Terminal.Gui/ViewBase/Adornment/ShadowView.cs
  65. 1 1
      Terminal.Gui/ViewBase/Layout/DimAuto.cs
  66. 8 8
      Terminal.Gui/ViewBase/View.Layout.cs
  67. 2 2
      Terminal.Gui/Views/Menuv1/MenuBar.cs
  68. 9 9
      Terminal.Gui/Views/Shortcut.cs
  69. 1 1
      Terminal.Gui/Views/StatusBar.cs
  70. 1 1
      Terminal.Gui/Views/TextInput/NetMaskedTextProvider.cs
  71. 0 1
      Terminal.Gui/Views/TreeView/Branch.cs
  72. 4 4
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeApplicationFactory.cs
  73. 0 58
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeConsoleDriver.cs
  74. 0 20
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeDriverFactory.cs
  75. 0 0
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeInput.cs
  76. 7 1
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeOutput.cs
  77. 6 6
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeSizeMonitor.cs
  78. 0 0
      Tests/TerminalGuiFluentTesting/FakeDriver/FakeWindowsInput.cs
  79. 0 8
      Tests/TerminalGuiFluentTesting/FakeDriver/IFakeConsoleDriver.cs
  80. 19 36
      Tests/TerminalGuiFluentTesting/GuiTestContext.cs
  81. 1 1
      Tests/UnitTests/Application/Application.NavigationTests.cs
  82. 2 2
      Tests/UnitTests/Application/ApplicationImplTests.cs
  83. 3 2
      Tests/UnitTests/Application/ApplicationPopoverTests.cs
  84. 2 2
      Tests/UnitTests/Application/ApplicationScreenTests.cs
  85. 31 44
      Tests/UnitTests/Application/ApplicationTests.cs
  86. 60 48
      Tests/UnitTests/Application/TimedEventsTests.cs
  87. 8 29
      Tests/UnitTests/AutoInitShutdownAttribute.cs
  88. 57 80
      Tests/UnitTests/ConsoleDrivers/ClipRegionTests.cs
  89. 1 1
      Tests/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs
  90. 106 0
      Tests/UnitTests/ConsoleDrivers/EscSeqUtilsTests.cs
  91. 223 86
      Tests/UnitTests/ConsoleDrivers/FakeDriverTests.cs
  92. 25 25
      Tests/UnitTests/ConsoleDrivers/WindowSizeMonitorTests.cs
  93. 23 23
      Tests/UnitTests/Dialogs/DialogTests.cs
  94. 7 7
      Tests/UnitTests/Dialogs/MessageBoxTests.cs
  95. 23 125
      Tests/UnitTests/Dialogs/WizardTests.cs
  96. 0 1263
      Tests/UnitTests/Drawing/LineCanvasTests.cs
  97. 0 142
      Tests/UnitTests/Drawing/RulerTests.cs
  98. 0 255
      Tests/UnitTests/Drawing/ThicknessTests.cs
  99. 18 19
      Tests/UnitTests/DriverAssert.cs
  100. 0 1582
      Tests/UnitTests/Input/EscSeqUtilsTests.cs

+ 3 - 3
.editorconfig

@@ -82,8 +82,8 @@ dotnet_diagnostic.cs0464.severity = warning
 dotnet_diagnostic.cs0465.severity = warning
 dotnet_diagnostic.cs0469.severity = warning
 dotnet_diagnostic.cs0472.severity = warning
-dotnet_diagnostic.cs0612.severity = warning
-dotnet_diagnostic.cs0618.severity = warning
+dotnet_diagnostic.cs0612.severity = none
+dotnet_diagnostic.cs0618.severity = none
 dotnet_diagnostic.cs0628.severity = warning
 dotnet_diagnostic.cs0642.severity = warning
 dotnet_diagnostic.cs0649.severity = warning
@@ -94,7 +94,7 @@ dotnet_diagnostic.cs0659.severity = warning
 dotnet_diagnostic.cs0660.severity = warning
 dotnet_diagnostic.cs0661.severity = warning
 dotnet_diagnostic.cs0665.severity = warning
-dotnet_diagnostic.cs0672.severity = warning
+dotnet_diagnostic.cs0672.severity = none
 dotnet_diagnostic.cs0675.severity = warning
 dotnet_diagnostic.cs0693.severity = warning
 dotnet_diagnostic.cs0728.severity = warning

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

@@ -26,7 +26,7 @@ public class Adornments : Scenario
             X = Pos.AnchorEnd ()
         };
 
-        editor.Border.Thickness = new (1, 2, 1, 1);
+        editor.Border!.Thickness = new (1, 2, 1, 1);
 
         app.Add (editor);
 
@@ -71,7 +71,7 @@ public class Adornments : Scenario
             Width = 40,
             Height = 6 // TODO: Use Dim.Auto
         };
-        label.Border.Thickness = new (1, 3, 1, 1);
+        label.Border!.Thickness = new (1, 3, 1, 1);
 
         var btnButtonInWindow = new Button { X = Pos.AnchorEnd (), Y = Pos.AnchorEnd (), Text = "Button" };
 
@@ -84,13 +84,13 @@ public class Adornments : Scenario
             SchemeName = "Dialog"
         };
 
-        window.Margin.Data = "Margin";
-        window.Margin.Text = "Margin Text";
-        window.Margin.Thickness = new (0);
+        window.Margin!.Data = "Margin";
+        window.Margin!.Text = "Margin Text";
+        window.Margin!.Thickness = new (0);
 
-        window.Border.Data = "Border";
-        window.Border.Text = "Border Text";
-        window.Border.Thickness = new (0);
+        window.Border!.Data = "Border";
+        window.Border!.Text = "Border Text";
+        window.Border!.Thickness = new (0);
 
         window.Padding.Data = "Padding";
         window.Padding.Text = "Padding Text line 1\nPadding Text line 3\nPadding Text line 3\nPadding Text line 4\nPadding Text line 5";
@@ -134,14 +134,14 @@ public class Adornments : Scenario
                                   };
                                   btnButtonInPadding.Accepting += (s, e) => MessageBox.Query (20, 7, "Hi", "Button in Padding Pressed!", "Ok");
                                   btnButtonInPadding.BorderStyle = LineStyle.Dashed;
-                                  btnButtonInPadding.Border.Thickness = new (1, 1, 1, 1);
+                                  btnButtonInPadding.Border!.Thickness = new (1, 1, 1, 1);
                                   window.Padding.Add (btnButtonInPadding);
 
 #if SUBVIEW_BASED_BORDER
-                                btnButtonInPadding.Border.CloseButton.Visible = true;
+                                btnButtonInPadding.Border!.CloseButton.Visible = true;
 
-                                view.Border.CloseButton.Visible = true;
-                                view.Border.CloseButton.Accept += (s, e) =>
+                                view.Border!.CloseButton.Visible = true;
+                                view.Border!.CloseButton.Accept += (s, e) =>
                                                                   {
                                                                       MessageBox.Query (20, 7, "Hi", "Window Close Button Pressed!", "Ok");
                                                                       e.Handled = true;

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

@@ -38,7 +38,7 @@ public class AllViewsTester : Scenario
 
         // Set the BorderStyle we use for all subviews, but disable the app border thickness
         app.Border!.LineStyle = LineStyle.Heavy;
-        app.Border.Thickness = new (0);
+        app.Border!.Thickness = new (0);
 
 
         _viewClasses = GetAllViewClassesCollection ()

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

@@ -112,7 +112,7 @@ public sealed class AnsiEscapeSequenceRequests : Scenario
 
                                                       break;
                                                   case "CSI_ReportTerminalSizeInChars":
-                                                      selAnsiEscapeSequenceRequest = EscSeqUtils.CSI_ReportTerminalSizeInChars;
+                                                      selAnsiEscapeSequenceRequest = EscSeqUtils.CSI_ReportWindowSizeInChars;
 
                                                       break;
                                                   case "CSI_RequestCursorPositionReport":

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

@@ -40,7 +40,7 @@ public class Bars : Scenario
             SchemeName = "Toplevel",
             Source = new ListWrapper<string> (eventSource)
         };
-        eventLog.Border.Thickness = new (0, 1, 0, 0);
+        eventLog.Border!.Thickness = new (0, 1, 0, 0);
         Application.Top.Add (eventLog);
 
         FrameView menuBarLikeExamples = new ()

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

@@ -151,7 +151,7 @@ public class Clipping : Scenario
         //tiled.Padding.Thickness = new (1);
         //tiled.Padding.Diagnostics =  ViewDiagnosticFlags.Thickness;
 
-        //tiled.Margin.Thickness = new (1);
+        //tiled.Margin!.Thickness = new (1);
 
         FrameView fv = new ()
         {

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

@@ -56,7 +56,7 @@ public class DimAutoDemo : Scenario
             Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: Dim.Percent (25)),
             Height = Dim.Auto (DimAutoStyle.Content, minimumContentDim: 10)
         };
-        dimAutoFrameView.Margin.Thickness = new Thickness (1);
+        dimAutoFrameView.Margin!.Thickness = new Thickness (1);
         dimAutoFrameView.ValidatePosDim = true;
 
         var textEdit = new TextView

+ 3 - 3
Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentsEditor.cs

@@ -99,7 +99,7 @@ public class AdornmentsEditor : EditorBase
             SuperViewRendersLineCanvas = true,
             BorderStyle = LineStyle.Single
         };
-        MarginEditor.Border!.Thickness = MarginEditor.Border.Thickness with { Bottom = 0 };
+        MarginEditor.Border!.Thickness = MarginEditor.Border!.Thickness with { Bottom = 0 };
         Add (MarginEditor);
 
         BorderEditor = new ()
@@ -109,7 +109,7 @@ public class AdornmentsEditor : EditorBase
             SuperViewRendersLineCanvas = true,
             BorderStyle = LineStyle.Single
         };
-        BorderEditor.Border!.Thickness = BorderEditor.Border.Thickness with { Bottom = 0 };
+        BorderEditor.Border!.Thickness = BorderEditor.Border!.Thickness with { Bottom = 0 };
         Add (BorderEditor);
 
         PaddingEditor = new ()
@@ -119,7 +119,7 @@ public class AdornmentsEditor : EditorBase
             SuperViewRendersLineCanvas = true,
             BorderStyle = LineStyle.Single
         };
-        PaddingEditor.Border!.Thickness = PaddingEditor.Border.Thickness with { Bottom = 0 };
+        PaddingEditor.Border!.Thickness = PaddingEditor.Border!.Thickness with { Bottom = 0 };
         Add (PaddingEditor);
 
         Width = Dim.Auto (maximumContentDim: Dim.Func (_ => MarginEditor.Frame.Width - 2));

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

@@ -144,8 +144,8 @@ public class GraphViewExample : Scenario
             Height = Dim.Fill (1),
             BorderStyle = LineStyle.Single
         };
-        _graphView.Border.Thickness = _thickness;
-        _graphView.Margin.Thickness = _thickness;
+        _graphView.Border!.Thickness = _thickness;
+        _graphView.Margin!.Thickness = _thickness;
         _graphView.Padding.Thickness = _thickness;
 
         app.Add (_graphView);
@@ -955,14 +955,14 @@ public class GraphViewExample : Scenario
         if (_miShowBorder.Checked == true)
         {
             _graphView.BorderStyle = LineStyle.Single;
-            _graphView.Border.Thickness = _thickness;
-            _graphView.Margin.Thickness = _thickness;
+            _graphView.Border!.Thickness = _thickness;
+            _graphView.Margin!.Thickness = _thickness;
             _graphView.Padding.Thickness = _thickness;
         }
         else
         {
             _graphView.BorderStyle = LineStyle.None;
-            _graphView.Margin.Thickness = Thickness.Empty;
+            _graphView.Margin!.Thickness = Thickness.Empty;
             _graphView.Padding.Thickness = Thickness.Empty;
         }
     }

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

@@ -130,9 +130,9 @@ public class LineCanvasExperiment : Scenario
         //    //Scheme = Colors.Schemes ["Error"],
         //    SuperViewRendersLineCanvas = true
         //};
-        //marginWindow.Margin.Scheme = Colors.Schemes ["Error"];
-        //marginWindow.Margin.Thickness = new (1);
-        //marginWindow.Border.Thickness = new (1, 2, 1, 1);
+        //marginWindow.Margin!.Scheme = Colors.Schemes ["Error"];
+        //marginWindow.Margin!.Thickness = new (1);
+        //marginWindow.Border!.Thickness = new (1, 2, 1, 1);
 
         //frame1.Add (marginWindow);
 

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

@@ -248,13 +248,13 @@ public sealed class PosAlignDemo : Scenario
         {
             addedViewsUpDown.X = Pos.Align (_horizAligner.Alignment);
             addedViewsUpDown.Y = Pos.Top (alignRadioGroup);
-            addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
+            addedViewsUpDown.Border!.Thickness = new (0, 1, 0, 0);
         }
         else
         {
             addedViewsUpDown.X = Pos.Left (alignRadioGroup);
             addedViewsUpDown.Y = Pos.Align (_vertAligner.Alignment);
-            addedViewsUpDown.Border.Thickness = new (1, 0, 0, 0);
+            addedViewsUpDown.Border!.Thickness = new (1, 0, 0, 0);
         }
 
         addedViewsUpDown.ValueChanging += (s, e) =>
@@ -319,7 +319,7 @@ public sealed class PosAlignDemo : Scenario
                                         aligner.Alignment,
                                         aligner.AlignmentModes,
                                         posAlign!.GroupId);
-                    view.Margin.Thickness = new (_leftMargin, view.Margin.Thickness.Top, view.Margin.Thickness.Right, view.Margin.Thickness.Bottom);
+                    view.Margin!.Thickness = new (_leftMargin, view.Margin!.Thickness.Top, view.Margin!.Thickness.Right, view.Margin!.Thickness.Bottom);
                 }
                 else
                 {
@@ -330,7 +330,7 @@ public sealed class PosAlignDemo : Scenario
                                         aligner.AlignmentModes,
                                         posAlign!.GroupId);
 
-                    view.Margin.Thickness = new (view.Margin.Thickness.Left, _topMargin, view.Margin.Thickness.Right, view.Margin.Thickness.Bottom);
+                    view.Margin!.Thickness = new (view.Margin!.Thickness.Left, _topMargin, view.Margin!.Thickness.Right, view.Margin!.Thickness.Bottom);
                 }
             }
         }

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

@@ -337,7 +337,7 @@ public class Shortcuts : Scenario
 
         if (framedShortcut.CommandView.Margin is { })
         {
-            framedShortcut.CommandView.Margin.SchemeName = framedShortcut.CommandView.SchemeName = "Error";
+            framedShortcut.CommandView.Margin!.SchemeName = framedShortcut.CommandView.SchemeName = "Error";
             framedShortcut.HelpView.Margin!.SchemeName = framedShortcut.HelpView.SchemeName = "Dialog";
             framedShortcut.KeyView.Margin!.SchemeName = framedShortcut.KeyView.SchemeName = "Menu";
         }

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

@@ -178,10 +178,10 @@ public class ViewportSettings : Scenario
         buttonAnchored.Accepting += (sender, args) => MessageBox.Query ("Hi", $"You pressed {((Button)sender)?.Text}", "_Ok");
 
         view.Margin!.Data = "Margin";
-        view.Margin.Thickness = new (0);
+        view.Margin!.Thickness = new (0);
 
         view.Border!.Data = "Border";
-        view.Border.Thickness = new (3);
+        view.Border!.Thickness = new (3);
 
         view.Padding.Data = "Padding";
 

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

@@ -43,7 +43,7 @@ public class WindowsAndFrameViews : Scenario
             Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable
         };
         win.Padding.Thickness = new (padding);
-        win.Margin.Thickness = new (margin);
+        win.Margin!.Thickness = new (margin);
 
         var paddingButton = new Button
         {

+ 2 - 2
Examples/UICatalog/UICatalog.cs

@@ -451,7 +451,7 @@ public class UICatalog
             scenario.StartBenchmark ();
         }
 
-        Application.Init (driverName: _forceDriver);
+        Application.ForceDriver = _forceDriver!;
 
         scenario.Main ();
 
@@ -517,7 +517,7 @@ public class UICatalog
 
         if (benchmarkWindow.Border is { })
         {
-            benchmarkWindow.Border.Thickness = new (0, 0, 0, 0);
+            benchmarkWindow.Border!.Thickness = new (0, 0, 0, 0);
         }
 
         TableView resultsTableView = new ()

+ 3 - 2
Terminal.Gui.Analyzers.Tests/HandledEventArgsAnalyzerTests.cs

@@ -1,7 +1,8 @@
-using Terminal.Gui.Input;
+using Terminal.Gui.Analyzers;
+using Terminal.Gui.Input;
 using Terminal.Gui.Views;
 
-namespace Terminal.Gui.Analyzers.Tests;
+namespace Analyzers.Tests;
 
 public class HandledEventArgsAnalyzerTests
 {

+ 4 - 111
Terminal.Gui/App/Application.Lifecycle.cs

@@ -40,26 +40,6 @@ public static partial class Application // Lifecycle (Init/Shutdown)
     [RequiresDynamicCode ("AOT")]
     public static void Init (IConsoleDriver? driver = null, string? driverName = null)
     {
-        // Check if this is a request for a legacy driver (like FakeDriver)
-        // that isn't supported by the modern application architecture
-        if (driver is null)
-        {
-            var driverNameToCheck = string.IsNullOrWhiteSpace (driverName) ? ForceDriver : driverName;
-            if (!string.IsNullOrEmpty (driverNameToCheck))
-            {
-                (List<Type?> drivers, List<string?> driverTypeNames) = GetDriverTypes ();
-                Type? driverType = drivers.FirstOrDefault (t => t!.Name.Equals (driverNameToCheck, StringComparison.InvariantCultureIgnoreCase));
-                
-                // If it's a legacy IConsoleDriver (not a Facade), use InternalInit which supports legacy drivers
-                if (driverType is { } && !typeof (IConsoleDriverFacade).IsAssignableFrom (driverType))
-                {
-                    InternalInit (driver, driverName);
-                    return;
-                }
-            }
-        }
-        
-        // Otherwise delegate to the ApplicationImpl instance (which uses the modern architecture)
         ApplicationImpl.Instance.Init (driver, driverName ?? ForceDriver);
     }
 
@@ -69,96 +49,6 @@ public static partial class Application // Lifecycle (Init/Shutdown)
         set => ((ApplicationImpl)ApplicationImpl.Instance).MainThreadId = value;
     }
 
-    // INTERNAL function for initializing an app with a Toplevel factory object, driver, and mainloop.
-    //
-    // Called from:
-    //
-    // Init() - When the user wants to use the default Toplevel. calledViaRunT will be false, causing all state to be reset.
-    // Run<T>() - When the user wants to use a custom Toplevel. calledViaRunT will be true, enabling Run<T>() to be called without calling Init first.
-    // Unit Tests - To initialize the app with a custom Toplevel, using the FakeDriver. calledViaRunT will be false, causing all state to be reset.
-    //
-    // calledViaRunT: If false (default) all state will be reset. If true the state will not be reset.
-    [RequiresUnreferencedCode ("AOT")]
-    [RequiresDynamicCode ("AOT")]
-    internal static void InternalInit (
-        IConsoleDriver? driver = null,
-        string? driverName = null,
-        bool calledViaRunT = false
-    )
-    {
-        if (Initialized && driver is null)
-        {
-            return;
-        }
-
-        if (Initialized)
-        {
-            throw new InvalidOperationException ("Init has already been called and must be bracketed by Shutdown.");
-        }
-
-        if (!calledViaRunT)
-        {
-            // Reset all class variables (Application is a singleton).
-            ResetState (ignoreDisposed: true);
-        }
-
-        // For UnitTests
-        if (driver is { })
-        {
-            Driver = driver;
-        }
-
-        // Ignore Configuration for ForceDriver if driverName is specified
-        if (!string.IsNullOrEmpty (driverName))
-        {
-            ForceDriver = driverName;
-        }
-
-        // Check if we need to use a legacy driver (like FakeDriver)
-        // or go through the modern application architecture
-        if (Driver is null)
-        {
-            ApplicationImpl.Instance.Init (driver, driverName);
-            Debug.Assert (Driver is { });
-            return;
-        }
-
-        Debug.Assert (Navigation is null);
-        Navigation = new ();
-
-        Debug.Assert (Popover is null);
-        Popover = new ();
-
-        try
-        {
-            Driver!.Init ();
-            SubscribeDriverEvents ();
-        }
-        catch (InvalidOperationException ex)
-        {
-            // This is a case where the driver is unable to initialize the console.
-            // This can happen if the console is already in use by another process or
-            // if running in unit tests.
-            // In this case, we want to throw a more specific exception.
-            throw new InvalidOperationException (
-                                                 "Unable to initialize the console. This can happen if the console is already in use by another process or in unit tests.",
-                                                 ex
-                                                );
-        }
-
-        SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());
-
-        // TODO: This is probably not needed
-        if (Popover.GetActivePopover () is View popover)
-        {
-            popover.Visible = false;
-        }
-
-        MainThreadId = Thread.CurrentThread.ManagedThreadId;
-        bool init = Initialized = true;
-        InitializedChanged?.Invoke (null, new (init));
-    }
-
     internal static void SubscribeDriverEvents ()
     {
         ArgumentNullException.ThrowIfNull (Driver);
@@ -179,7 +69,10 @@ public static partial class Application // Lifecycle (Init/Shutdown)
         Driver.MouseEvent -= Driver_MouseEvent;
     }
 
-    private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
+    private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e)
+    {
+        RaiseScreenChangedEvent (new Rectangle (new (0, 0), e.Size!.Value));
+    }
     private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); }
     private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); }
     private static void Driver_MouseEvent (object? sender, MouseEventArgs e) { RaiseMouseEvent (e); }

+ 7 - 7
Terminal.Gui/App/Application.Run.cs

@@ -22,10 +22,6 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
         set => Keyboard.ArrangeKey = value;
     }
 
-    // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`.
-    // This variable is set in `End` in this case so that `Begin` correctly sets `Top`.
-    private static Toplevel? _cachedRunStateToplevel;
-
     /// <summary>
     ///     Notify that a new <see cref="RunState"/> was created (<see cref="Begin(Toplevel)"/> was called). The token is
     ///     created in <see cref="Begin(Toplevel)"/> and this event will be fired before that function exits.
@@ -43,7 +39,11 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     ///     must also subscribe to <see cref="NotifyStopRunState"/> and manually dispose of the <see cref="RunState"/> token
     ///     when the application is done.
     /// </remarks>
+#pragma warning disable CS0067 // Event is never used
+#pragma warning disable CS0414 // Event is never used
     public static event EventHandler<ToplevelEventArgs>? NotifyStopRunState;
+#pragma warning restore CS0414 // Event is never used
+#pragma warning restore CS0067 // Event is never used
 
     /// <summary>Building block API: Prepares the provided <see cref="Toplevel"/> for execution.</summary>
     /// <returns>
@@ -74,7 +74,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
         {
             // This assertion confirm if the Top was already disposed
             Debug.Assert (Top.WasDisposed);
-            Debug.Assert (Top == _cachedRunStateToplevel);
+            Debug.Assert (Top == CachedRunStateToplevel);
         }
 #endif
 
@@ -84,7 +84,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
             {
                 // If Top was already disposed and isn't on the Toplevels Stack,
                 // clean it up here if is the same as _cachedRunStateToplevel
-                if (Top == _cachedRunStateToplevel)
+                if (Top == CachedRunStateToplevel)
                 {
                     Top = null;
                 }
@@ -493,7 +493,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
             Top.SetFocus ();
         }
 
-        _cachedRunStateToplevel = runState.Toplevel;
+        CachedRunStateToplevel = runState.Toplevel;
 
         runState.Toplevel = null;
         runState.Dispose ();

+ 8 - 20
Terminal.Gui/App/Application.Screen.cs

@@ -19,38 +19,26 @@ public static partial class Application // Screen related stuff; intended to hid
     }
 
     /// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
-    /// <remarks>
-    ///     Event handlers can set <see cref="SizeChangedEventArgs.Cancel"/> to <see langword="true"/> to prevent
-    ///     <see cref="Application"/> from changing it's size to match the new terminal size.
-    /// </remarks>
-    public static event EventHandler<SizeChangedEventArgs>? SizeChanging;
+    public static event EventHandler<EventArgs<Rectangle>>? ScreenChanged;
 
     /// <summary>
-    ///     Called when the application's size changes. Sets the size of all <see cref="Toplevel"/>s and fires the
-    ///     <see cref="SizeChanging"/> event.
+    ///     Called when the application's size has changed. Sets the size of all <see cref="Toplevel"/>s and fires the
+    ///     <see cref="ScreenChanged"/> event.
     /// </summary>
-    /// <param name="args">The new size.</param>
-    /// <returns><see lanword="true"/>if the size was changed.</returns>
-    public static bool OnSizeChanging (SizeChangedEventArgs args)
+    /// <param name="screen">The new screen size and position.</param>
+    public static void RaiseScreenChangedEvent (Rectangle screen)
     {
-        SizeChanging?.Invoke (null, args);
-
-        if (args.Cancel || args.Size is null)
-        {
-            return false;
-        }
+        Screen = new (Point.Empty, screen.Size);
 
-        Screen = new (Point.Empty, args.Size.Value);
+        ScreenChanged?.Invoke (ApplicationImpl.Instance, new (screen));
 
         foreach (Toplevel t in TopLevels)
         {
-            t.OnSizeChanging (new (args.Size));
+            t.OnSizeChanging (new (screen.Size));
             t.SetNeedsLayout ();
         }
 
         LayoutAndDraw (true);
-
-        return true;
     }
 
     /// <summary>

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

@@ -17,4 +17,12 @@ public static partial class Application // Toplevel handling
         get => ApplicationImpl.Instance.Top;
         internal set => ApplicationImpl.Instance.Top = value;
     }
+
+    internal static Toplevel? CachedRunStateToplevel
+    {
+        get => ApplicationImpl.Instance.CachedRunStateToplevel;
+        private set => ApplicationImpl.Instance.CachedRunStateToplevel = value;
+    }
+
+
 }

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

@@ -206,15 +206,15 @@ public static partial class Application
             Debug.Assert (Top.WasDisposed, $"Title = {Top.Title}, Id = {Top.Id}");
 
             // If End wasn't called _cachedRunStateToplevel may be null
-            if (_cachedRunStateToplevel is { })
+            if (CachedRunStateToplevel is { })
             {
-                Debug.Assert (_cachedRunStateToplevel.WasDisposed);
-                Debug.Assert (_cachedRunStateToplevel == Top);
+                Debug.Assert (CachedRunStateToplevel.WasDisposed);
+                Debug.Assert (CachedRunStateToplevel == Top);
             }
         }
 #endif
         Top = null;
-        _cachedRunStateToplevel = null;
+        CachedRunStateToplevel = null;
 
         MainThreadId = -1;
         Iteration = null;
@@ -257,7 +257,7 @@ public static partial class Application
 
         // Keyboard events and bindings are now managed by the Keyboard instance
 
-        SizeChanging = null;
+        ScreenChanged = null;
 
         Navigation = null;
 

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

@@ -63,11 +63,6 @@ public class ApplicationImpl : IApplication
         set => _mouse = value ?? throw new ArgumentNullException (nameof (value));
     }
 
-    /// <summary>
-    /// Handles which <see cref="View"/> (if any) has captured the mouse
-    /// </summary>
-    public IMouseGrabHandler MouseGrabHandler { get; set; } = new MouseGrabHandler ();
-
     private IKeyboard? _keyboard;
 
     /// <summary>
@@ -134,7 +129,7 @@ public class ApplicationImpl : IApplication
         }
         set
         {
-            if (value is {} && (value.X != 0 || value.Y != 0))
+            if (value is { } && (value.X != 0 || value.Y != 0))
             {
                 throw new NotImplementedException ($"Screen locations other than 0, 0 are not yet supported");
             }
@@ -177,6 +172,11 @@ public class ApplicationImpl : IApplication
     /// <inheritdoc/>
     public ConcurrentStack<Toplevel> TopLevels => _topLevels;
 
+    // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`.
+    // This variable is set in `End` in this case so that `Begin` correctly sets `Top`.
+    /// <inheritdoc />
+    public Toplevel? CachedRunStateToplevel { get; set; }
+
     /// <summary>
     /// Gets or sets the main thread ID for the application.
     /// </summary>
@@ -231,10 +231,10 @@ public class ApplicationImpl : IApplication
 
         if (string.IsNullOrWhiteSpace (_driverName))
         {
-            _driverName = Application.ForceDriver;
+            _driverName = ForceDriver;
         }
 
-        Debug.Assert(_navigation is null);
+        Debug.Assert (_navigation is null);
         _navigation = new ();
 
         Debug.Assert (_popover is null);
@@ -264,7 +264,7 @@ public class ApplicationImpl : IApplication
         }
 
         CreateDriver (driverName ?? _driverName);
-
+        Screen = Driver!.Screen;
         _initialized = true;
 
         Application.OnInitializedChanged (this, new (true));
@@ -276,23 +276,6 @@ public class ApplicationImpl : IApplication
 
     private void CreateDriver (string? driverName)
     {
-        // When running unit tests, always use FakeDriver unless explicitly specified
-        if (ConsoleDriver.RunningUnitTests && 
-            string.IsNullOrEmpty (driverName) && 
-            _componentFactory is null)
-        {
-            Logging.Logger.LogDebug ("Unit test safeguard: forcing FakeDriver (RunningUnitTests=true, driverName=null, componentFactory=null)");
-            _coordinator = CreateSubcomponents (() => new FakeComponentFactory ());
-            _coordinator.StartAsync ().Wait ();
-
-            if (_driver == null)
-            {
-                throw new ("Driver was null even after booting MainLoopCoordinator");
-            }
-
-            return;
-        }
-
         PlatformID p = Environment.OSVersion.Platform;
 
         // Check component factory type first - this takes precedence over driverName
@@ -310,7 +293,10 @@ public class ApplicationImpl : IApplication
         // Decide which driver to use - component factory type takes priority
         if (factoryIsFake || (!factoryIsWindows && !factoryIsDotNet && !factoryIsUnix && nameIsFake))
         {
-            _coordinator = CreateSubcomponents (() => new FakeComponentFactory ());
+            FakeConsoleOutput fakeOutput = new ();
+            fakeOutput.SetConsoleSize (80, 25);
+
+            _coordinator = CreateSubcomponents (() => new FakeComponentFactory (null, fakeOutput));
         }
         else if (factoryIsWindows || (!factoryIsDotNet && !factoryIsUnix && nameIsWindows))
         {
@@ -410,7 +396,7 @@ public class ApplicationImpl : IApplication
 
         if (_driver == null)
         {
-            throw new  InvalidOperationException ("Driver was inexplicably null when trying to Run view");
+            throw new InvalidOperationException ("Driver was inexplicably null when trying to Run view");
         }
 
         _top = view;
@@ -437,17 +423,17 @@ public class ApplicationImpl : IApplication
     public void Shutdown ()
     {
         _coordinator?.Stop ();
-        
+
         bool wasInitialized = _initialized;
-        
+
         // Reset Screen before calling Application.ResetState to avoid circular reference
         ResetScreen ();
-        
+
         // Call ResetState FIRST so it can properly dispose Popover and other resources
         // that are accessed via Application.* static properties that now delegate to instance fields
         Application.ResetState ();
         ConfigurationManager.PrintJsonErrors ();
-        
+
         // Clear instance fields after ResetState has disposed everything
         _driver = null;
         _mouse = null;
@@ -455,6 +441,7 @@ public class ApplicationImpl : IApplication
         _initialized = false;
         _navigation = null;
         _popover = null;
+        CachedRunStateToplevel = null;
         _top = null;
         _topLevels.Clear ();
         _mainThreadId = -1;
@@ -475,7 +462,7 @@ public class ApplicationImpl : IApplication
     /// <inheritdoc />
     public void RequestStop (Toplevel? top)
     {
-        Logging.Logger.LogInformation ($"RequestStop '{(top is {} ? top : "null")}'");
+        Logging.Logger.LogInformation ($"RequestStop '{(top is { } ? top : "null")}'");
 
         top ??= _top;
 
@@ -499,7 +486,7 @@ public class ApplicationImpl : IApplication
     public void Invoke (Action action)
     {
         // If we are already on the main UI thread
-        if (Application.Top is { Running: true } && _mainThreadId == Thread.CurrentThread.ManagedThreadId)
+        if (Top is { Running: true } && _mainThreadId == Thread.CurrentThread.ManagedThreadId)
         {
             action ();
             return;

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

@@ -74,6 +74,11 @@ public interface IApplication
     /// <summary>Gets the stack of all Toplevels.</summary>
     System.Collections.Concurrent.ConcurrentStack<Toplevel> TopLevels { get; }
 
+    /// <summary>
+    /// Caches the Toplevel associated with the current RunState.
+    /// </summary>
+    Toplevel? CachedRunStateToplevel { get; set; }
+
     /// <summary>Requests that the application stop running.</summary>
     void RequestStop ();
 

+ 6 - 6
Terminal.Gui/App/MainLoop/ApplicationMainLoop.cs

@@ -27,7 +27,7 @@ public class ApplicationMainLoop<T> : IApplicationMainLoop<T>
     private IInputProcessor? _inputProcessor;
     private IConsoleOutput? _out;
     private AnsiRequestScheduler? _ansiRequestScheduler;
-    private IWindowSizeMonitor? _windowSizeMonitor;
+    private IConsoleSizeMonitor? _consoleSizeMonitor;
 
     /// <inheritdoc/>
     public ITimedEvents TimedEvents
@@ -74,10 +74,10 @@ public class ApplicationMainLoop<T> : IApplicationMainLoop<T>
     }
 
     /// <inheritdoc/>
-    public IWindowSizeMonitor WindowSizeMonitor
+    public IConsoleSizeMonitor ConsoleSizeMonitor
     {
-        get => _windowSizeMonitor ?? throw new NotInitializedException (nameof (WindowSizeMonitor));
-        private set => _windowSizeMonitor = value;
+        get => _consoleSizeMonitor ?? throw new NotInitializedException (nameof (ConsoleSizeMonitor));
+        private set => _consoleSizeMonitor = value;
     }
 
     /// <summary>
@@ -114,7 +114,7 @@ public class ApplicationMainLoop<T> : IApplicationMainLoop<T>
         TimedEvents = timedEvents;
         AnsiRequestScheduler = new (InputProcessor.GetParser ());
 
-        WindowSizeMonitor = componentFactory.CreateWindowSizeMonitor (Out, OutputBuffer);
+        ConsoleSizeMonitor = componentFactory.CreateConsoleSizeMonitor (Out, OutputBuffer);
     }
 
     /// <inheritdoc/>
@@ -152,7 +152,7 @@ public class ApplicationMainLoop<T> : IApplicationMainLoop<T>
                                      || AnySubViewsNeedDrawn (Application.Top)
                                      || (Application.Mouse.MouseGrabView != null && AnySubViewsNeedDrawn (Application.Mouse.MouseGrabView));
 
-            bool sizeChanged = WindowSizeMonitor.Poll ();
+            bool sizeChanged = ConsoleSizeMonitor.Poll ();
 
             if (needsDrawOrLayout || sizeChanged)
             {

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

@@ -48,7 +48,7 @@ public interface IApplicationMainLoop<T> : IDisposable
     /// <summary>
     ///     Gets the class responsible for determining the current console size
     /// </summary>
-    public IWindowSizeMonitor WindowSizeMonitor { get; }
+    public IConsoleSizeMonitor ConsoleSizeMonitor { get; }
 
     /// <summary>
     ///     Initializes the loop with a buffer from which data can be read

+ 1 - 1
Terminal.Gui/App/MainLoop/MainLoopCoordinator.cs

@@ -149,7 +149,7 @@ internal class MainLoopCoordinator<T> : IMainLoopCoordinator
                            _loop.OutputBuffer,
                            _output,
                            _loop.AnsiRequestScheduler,
-                           _loop.WindowSizeMonitor);
+                           _loop.ConsoleSizeMonitor);
 
             Application.Driver = _facade;
 

+ 0 - 12
Terminal.Gui/App/Timeout/ITimedEvents.cs

@@ -27,18 +27,6 @@ public interface ITimedEvents
     /// </summary>
     event EventHandler<TimeoutEventArgs>? Added;
 
-    /// <summary>
-    ///     Called from <see cref="IMainLoopDriver.EventsPending"/> to check if there are any outstanding timer handlers.
-    /// </summary>
-    /// <param name="waitTimeout">
-    ///     Returns the number of milliseconds remaining in the current timer (if any). Will be -1 if
-    ///     there are no active timers.
-    /// </param>
-    /// <returns>
-    ///     <see langword="true"/> if there is a timer active; otherwise, <see langword="false"/>.
-    /// </returns>
-    bool CheckTimers (out int waitTimeout);
-
     /// <summary>
     ///     Removes a previously scheduled timeout.
     /// </summary>

+ 8 - 5
Terminal.Gui/Drawing/Ruler.cs

@@ -23,7 +23,8 @@ internal class Ruler
     /// <summary>Draws the <see cref="Ruler"/>.</summary>
     /// <param name="location">The location to start drawing the ruler, in screen-relative coordinates.</param>
     /// <param name="start">The start value of the ruler.</param>
-    public void Draw (Point location, int start = 0)
+    /// <param name="driver">Optional Driver. If not provided, driver will be used.</param>
+    public void Draw (Point location, int start = 0, IConsoleDriver? driver = null)
     {
         if (start < 0)
         {
@@ -35,14 +36,16 @@ internal class Ruler
             return;
         }
 
+        driver ??= driver;
+
         if (Orientation == Orientation.Horizontal)
         {
             string hrule =
                 _hTemplate.Repeat ((int)Math.Ceiling (Length + 2 / (double)_hTemplate.Length))! [start..(Length + start)];
 
             // Top
-            Application.Driver?.Move (location.X, location.Y);
-            Application.Driver?.AddStr (hrule);
+            driver?.Move (location.X, location.Y);
+            driver?.AddStr (hrule);
         }
         else
         {
@@ -52,8 +55,8 @@ internal class Ruler
 
             for (int r = location.Y; r < location.Y + Length; r++)
             {
-                Application.Driver?.Move (location.X, r);
-                Application.Driver?.AddRune ((Rune)vrule [r - location.Y]);
+                driver?.Move (location.X, r);
+                driver?.AddRune ((Rune)vrule [r - location.Y]);
             }
         }
     }

+ 6 - 6
Terminal.Gui/Drawing/Sixel/SixelSupportDetector.cs

@@ -53,21 +53,21 @@ public class SixelSupportDetector
 
     private void TryComputeResolution (SixelSupportResult result, Action<SixelSupportResult> resultCallback)
     {
-        string windowSize;
+        string consoleSize;
         string sizeInChars;
 
         QueueRequest (
                       EscSeqUtils.CSI_RequestWindowSizeInPixels,
                       r1 =>
                       {
-                          windowSize = r1;
+                          consoleSize = r1;
 
                           QueueRequest (
-                                        EscSeqUtils.CSI_ReportTerminalSizeInChars,
+                                        EscSeqUtils.CSI_ReportWindowSizeInChars,
                                         r2 =>
                                         {
                                             sizeInChars = r2;
-                                            ComputeResolution (result, windowSize, sizeInChars);
+                                            ComputeResolution (result, consoleSize, sizeInChars);
                                             resultCallback (result);
                                         },
                                         () => resultCallback (result));
@@ -75,11 +75,11 @@ public class SixelSupportDetector
                       () => resultCallback (result));
     }
 
-    private void ComputeResolution (SixelSupportResult result, string windowSize, string sizeInChars)
+    private void ComputeResolution (SixelSupportResult result, string consoleSize, string sizeInChars)
     {
         // Fallback to window size in pixels and characters
         // Example [4;600;1200t
-        Match pixelMatch = Regex.Match (windowSize, @"\[\d+;(\d+);(\d+)t$");
+        Match pixelMatch = Regex.Match (consoleSize, @"\[\d+;(\d+);(\d+)t$");
 
         // Example [8;30;120t
         Match charMatch = Regex.Match (sizeInChars, @"\[\d+;(\d+);(\d+)t$");

+ 32 - 29
Terminal.Gui/Drawing/Thickness.cs

@@ -88,14 +88,17 @@ public record struct Thickness
     /// <param name="rect">The location and size of the rectangle that bounds the thickness rectangle, in screen coordinates.</param>
     /// <param name="diagnosticFlags"></param>
     /// <param name="label">The diagnostics label to draw on the bottom of the <see cref="Bottom"/>.</param>
+    /// <param name="driver">Optional driver. If not specified, <see cref="Application.Driver"/> will be used.</param>
     /// <returns>The inner rectangle remaining to be drawn.</returns>
-    public Rectangle Draw (Rectangle rect, ViewDiagnosticFlags diagnosticFlags = ViewDiagnosticFlags.Off, string? label = null)
+    public Rectangle Draw (Rectangle rect, ViewDiagnosticFlags diagnosticFlags = ViewDiagnosticFlags.Off, string? label = null, IConsoleDriver? driver = null)
     {
         if (rect.Size.Width < 1 || rect.Size.Height < 1)
         {
             return Rectangle.Empty;
         }
 
+        driver ??= Application.Driver;
+
         var clearChar = (Rune)' ';
         Rune leftChar = clearChar;
         Rune rightChar = clearChar;
@@ -118,71 +121,71 @@ public record struct Thickness
         // Draw the Top side
         if (Top > 0)
         {
-            Application.Driver?.FillRect (rect with { Height = Math.Min (rect.Height, Top) }, topChar);
+            driver?.FillRect (rect with { Height = Math.Min (rect.Height, Top) }, topChar);
         }
 
         // Draw the Left side
         // Draw the Left side
         if (Left > 0)
         {
-            Application.Driver?.FillRect (rect with { Width = Math.Min (rect.Width, Left) }, leftChar);
+            driver?.FillRect (rect with { Width = Math.Min (rect.Width, Left) }, leftChar);
         }
 
         // Draw the Right side
         if (Right > 0)
         {
-            Application.Driver?.FillRect (
-                                          rect with
-                                          {
-                                              X = Math.Max (0, rect.X + rect.Width - Right),
-                                              Width = Math.Min (rect.Width, Right)
-                                          },
-                                          rightChar
-                                         );
+            driver?.FillRect (
+                              rect with
+                              {
+                                  X = Math.Max (0, rect.X + rect.Width - Right),
+                                  Width = Math.Min (rect.Width, Right)
+                              },
+                              rightChar
+                             );
         }
 
         // Draw the Bottom side
         if (Bottom > 0)
         {
-            Application.Driver?.FillRect (
-                                          rect with
-                                          {
-                                              Y = rect.Y + Math.Max (0, rect.Height - Bottom),
-                                              Height = Bottom
-                                          },
-                                          bottomChar
-                                         );
+            driver?.FillRect (
+                              rect with
+                              {
+                                  Y = rect.Y + Math.Max (0, rect.Height - Bottom),
+                                  Height = Bottom
+                              },
+                              bottomChar
+                             );
         }
 
         if (diagnosticFlags.HasFlag (ViewDiagnosticFlags.Ruler))
         {
             // PERF: This can almost certainly be simplified down to a single point offset and fewer calls to Draw
             // Top
-            var hruler = new Ruler { Length = rect.Width, Orientation = Orientation.Horizontal };
+            Ruler hRuler = new () { Length = rect.Width, Orientation = Orientation.Horizontal };
 
             if (Top > 0)
             {
-                hruler.Draw (rect.Location);
+                hRuler.Draw (rect.Location, driver: driver);
             }
 
             //Left
-            var vruler = new Ruler { Length = rect.Height - 2, Orientation = Orientation.Vertical };
+            Ruler vRuler = new () { Length = rect.Height - 2, Orientation = Orientation.Vertical };
 
             if (Left > 0)
             {
-                vruler.Draw (rect.Location with { Y = rect.Y + 1 }, 1);
+                vRuler.Draw (rect.Location with { Y = rect.Y + 1 }, 1, driver);
             }
 
             // Bottom
             if (Bottom > 0)
             {
-                hruler.Draw (rect.Location with { Y = rect.Y + rect.Height - 1 });
+                hRuler.Draw (rect.Location with { Y = rect.Y + rect.Height - 1 }, driver: driver);
             }
 
             // Right
             if (Right > 0)
             {
-                vruler.Draw (new (rect.X + rect.Width - 1, rect.Y + 1), 1);
+                vRuler.Draw (new (rect.X + rect.Width - 1, rect.Y + 1), 1, driver);
             }
         }
 
@@ -191,7 +194,7 @@ public record struct Thickness
             // Draw the diagnostics label on the bottom
             string text = label is null ? string.Empty : $"{label} {this}";
 
-            var tf = new TextFormatter
+            TextFormatter tf = new ()
             {
                 Text = text,
                 Alignment = Alignment.Center,
@@ -200,9 +203,9 @@ public record struct Thickness
                 ConstrainToHeight = 1
             };
 
-            if (Application.Driver?.CurrentAttribute is { })
+            if (driver?.CurrentAttribute is { })
             {
-                tf.Draw (rect, Application.Driver!.CurrentAttribute, Application.Driver!.CurrentAttribute, rect);
+                tf.Draw (rect, driver!.CurrentAttribute, driver!.CurrentAttribute, rect, driver);
             }
         }
 
@@ -242,7 +245,7 @@ public record struct Thickness
     /// <returns></returns>
     public Region AsRegion (Rectangle rect)
     {
-        Region region = new Region (rect);
+        var region = new Region (rect);
         region.Exclude (GetInside (rect));
 
         return region;

Plik diff jest za duży
+ 55 - 925
Terminal.Gui/Drivers/AnsiHandling/EscSeqUtils/EscSeqUtils.cs


+ 1 - 1
Terminal.Gui/Drivers/AnsiHandling/Osc8UrlLinker.cs

@@ -33,7 +33,7 @@ internal static class Osc8UrlLinker
 
     internal static StringBuilder WrapOsc8 (StringBuilder input, Options options)
     {
-        if (input is null || input.Length == 0)
+        if (input.Length == 0)
         {
             return input;
         }

+ 2 - 2
Terminal.Gui/Drivers/ComponentFactory.cs

@@ -16,9 +16,9 @@ public abstract class ComponentFactory<T> : IComponentFactory<T>
     public abstract IInputProcessor CreateInputProcessor (ConcurrentQueue<T> inputBuffer);
 
     /// <inheritdoc />
-    public virtual IWindowSizeMonitor CreateWindowSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
+    public virtual IConsoleSizeMonitor CreateConsoleSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
     {
-        return new WindowSizeMonitor (consoleOutput, outputBuffer);
+        return new ConsoleSizeMonitor (consoleOutput, outputBuffer);
     }
 
     /// <inheritdoc />

+ 31 - 19
Terminal.Gui/Drivers/ConsoleDriver.cs

@@ -60,6 +60,19 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// <summary>Gets the location and size of the terminal screen.</summary>
     public Rectangle Screen => new (0, 0, Cols, Rows);
 
+    /// <summary>
+    /// Sets the screen size for testing purposes. Only supported by FakeDriver.
+    /// <see cref="Screen"/> is the source of truth for screen dimensions.
+    /// <see cref="Cols"/> and <see cref="Rows"/> are read-only and derived from <see cref="Screen"/>.
+    /// </summary>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    /// <exception cref="NotSupportedException">Thrown when called on non-FakeDriver instances.</exception>
+    public virtual void SetScreenSize (int width, int height)
+    {
+        throw new NotSupportedException ("SetScreenSize is only supported by FakeDriver for test scenarios.");
+    }
+
     private Region? _clip;
 
     /// <summary>
@@ -508,9 +521,17 @@ public abstract class ConsoleDriver : IConsoleDriver
         }
     }
 
-    /// <summary>Called when the terminal size changes. Fires the <see cref="SizeChanged"/> event.</summary>
-    /// <param name="args"></param>
-    public void OnSizeChanged (SizeChangedEventArgs args) { SizeChanged?.Invoke (this, args); }
+    /// <summary>
+    /// Called when the terminal screen changes (size, position, etc.). Fires the <see cref="SizeChanged"/> event.
+    /// <see cref="Screen"/> reflects the source of truth for screen dimensions.
+    /// <see cref="Cols"/> and <see cref="Rows"/> are derived from <see cref="Screen"/> and are read-only.
+    /// </summary>
+    /// <param name="args">Event arguments containing the new screen size.</param>
+    public void OnSizeChanged (SizeChangedEventArgs args) 
+    { 
+        SizeChanged?.Invoke (this, args);
+    }
+
 
     /// <summary>Updates the screen to reflect all the changes that have been done to the display buffer</summary>
     public void Refresh ()
@@ -531,13 +552,17 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// <returns><see langword="true"/> upon success</returns>
     public abstract bool SetCursorVisibility (CursorVisibility visibility);
 
-    /// <summary>The event fired when the terminal is resized.</summary>
+    /// <summary>
+    /// The event fired when the screen changes (size, position, etc.).
+    /// <see cref="Screen"/> is the source of truth for screen dimensions.
+    /// <see cref="Cols"/> and <see cref="Rows"/> are read-only and derived from <see cref="Screen"/>.
+    /// </summary>
     public event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     #endregion Cursor Handling
 
     /// <summary>Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver.</summary>
-    /// <remarks>This is only implemented in <see cref="UnixDriver"/>.</remarks>
+    /// <remarks>This is only implemented in the Unix driver.</remarks>
     public abstract void Suspend ();
 
     /// <summary>Sets the position of the terminal cursor to <see cref="Col"/> and <see cref="Row"/>.</summary>
@@ -603,20 +628,7 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// <summary>Gets the current <see cref="Attribute"/>.</summary>
     /// <returns>The current attribute.</returns>
     public Attribute GetAttribute () { return CurrentAttribute; }
-
-    /// <summary>Makes an <see cref="Attribute"/>.</summary>
-    /// <param name="foreground">The foreground color.</param>
-    /// <param name="background">The background color.</param>
-    /// <returns>The attribute for the foreground and background colors.</returns>
-    public virtual Attribute MakeColor (in Color foreground, in Color background)
-    {
-        // Encode the colors into the int value.
-        return new (
-                    foreground,
-                    background
-                   );
-    }
-
+    
     #endregion Color Handling
 
     #region Mouse Handling

+ 37 - 25
Terminal.Gui/Drivers/ConsoleDriverFacade.cs

@@ -10,13 +10,15 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
     private readonly AnsiRequestScheduler _ansiRequestScheduler;
     private CursorVisibility _lastCursor = CursorVisibility.Default;
 
-    /// <summary>The event fired when the terminal is resized.</summary>
+    /// <summary>
+    /// The event fired when the screen changes (size, position, etc.).
+    /// </summary>
     public event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     public IInputProcessor InputProcessor { get; }
     public IOutputBuffer OutputBuffer => _outputBuffer;
 
-    public IWindowSizeMonitor WindowSizeMonitor { get; }
+    public IConsoleSizeMonitor ConsoleSizeMonitor { get; }
 
 
     public ConsoleDriverFacade (
@@ -24,7 +26,7 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
         IOutputBuffer outputBuffer,
         IConsoleOutput output,
         AnsiRequestScheduler ansiRequestScheduler,
-        IWindowSizeMonitor windowSizeMonitor
+        IConsoleSizeMonitor sizeMonitor
     )
     {
         InputProcessor = inputProcessor;
@@ -40,8 +42,12 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
                                          MouseEvent?.Invoke (s, e);
                                      };
 
-        WindowSizeMonitor = windowSizeMonitor;
-        windowSizeMonitor.SizeChanging += (_,e) => SizeChanged?.Invoke (this, e);
+        ConsoleSizeMonitor = sizeMonitor;
+        sizeMonitor.SizeChanged += (_, e) =>
+        {
+            SetScreenSize(e.Size!.Value.Width, e.Size.Value.Height);
+            //SizeChanged?.Invoke (this, e);
+        };
 
         CreateClipboard ();
     }
@@ -50,7 +56,7 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
     {
         if (FakeDriver.FakeBehaviors.UseFakeClipboard)
         {
-            Clipboard = new FakeDriver.FakeClipboard (
+            Clipboard = new FakeClipboard (
                 FakeDriver.FakeBehaviors.FakeClipboardAlwaysThrowsNotSupportedException,
                 FakeDriver.FakeBehaviors.FakeClipboardIsSupportedAlwaysFalse);
 
@@ -73,7 +79,7 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
         }
         else
         {
-            Clipboard = new FakeDriver.FakeClipboard ();
+            Clipboard = new FakeClipboard ();
         }
     }
 
@@ -88,10 +94,23 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
                 return Rectangle.Empty;
             }
 
-            return new (new (0, 0), _output.GetWindowSize ());
+            return new (0, 0, _outputBuffer.Cols, _outputBuffer.Rows);
         }
     }
 
+    /// <summary>
+    /// Sets the screen size for testing purposes. Only supported by FakeDriver.
+    /// </summary>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    /// <exception cref="NotSupportedException">Thrown when called on non-FakeDriver instances.</exception>
+    public virtual void SetScreenSize (int width, int height)
+    {
+        _outputBuffer.SetSize (width, height);
+        _output.SetSize (width, height);
+        SizeChanged?.Invoke(this, new (new (width, height)));
+    }
+
     /// <summary>
     ///     Gets or sets the clip rectangle that <see cref="AddRune(Rune)"/> and <see cref="AddStr(string)"/> are subject
     ///     to.
@@ -104,7 +123,7 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
     }
 
     /// <summary>Get the operating system clipboard.</summary>
-    public IClipboard Clipboard { get; private set; } = new FakeDriver.FakeClipboard ();
+    public IClipboard Clipboard { get; private set; } = new FakeClipboard ();
 
     /// <summary>
     ///     Gets the column last set by <see cref="Move"/>. <see cref="Col"/> and <see cref="Row"/> are used by
@@ -364,7 +383,6 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
     public void UpdateCursor () { _output.SetCursorPosition (Col, Row); }
 
     /// <summary>Initializes the driver</summary>
-    /// <returns>Returns an instance of <see cref="MainLoop"/> using the <see cref="IMainLoopDriver"/> for the driver.</returns>
     public void Init () { throw new NotSupportedException (); }
 
     /// <summary>Ends the execution of the console driver.</summary>
@@ -375,26 +393,20 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
 
     /// <summary>Selects the specified attribute as the attribute to use for future calls to AddRune and AddString.</summary>
     /// <remarks>Implementations should call <c>base.SetAttribute(c)</c>.</remarks>
-    /// <param name="c">C.</param>
-    public Attribute SetAttribute (Attribute c) { return _outputBuffer.CurrentAttribute = c; }
+    /// <param name="newAttribute">C.</param>
+    /// <returns>The previously set Attribute.</returns>
+    public Attribute SetAttribute (Attribute newAttribute)
+    {
+        Attribute currentAttribute = _outputBuffer.CurrentAttribute;
+        _outputBuffer.CurrentAttribute = newAttribute;
+
+        return currentAttribute;
+    }
 
     /// <summary>Gets the current <see cref="Attribute"/>.</summary>
     /// <returns>The current attribute.</returns>
     public Attribute GetAttribute () { return _outputBuffer.CurrentAttribute; }
 
-    /// <summary>Makes an <see cref="Attribute"/>.</summary>
-    /// <param name="foreground">The foreground color.</param>
-    /// <param name="background">The background color.</param>
-    /// <returns>The attribute for the foreground and background colors.</returns>
-    public Attribute MakeColor (in Color foreground, in Color background)
-    {
-        // TODO: what even is this? why Attribute constructor wants to call Driver method which must return an instance of Attribute? ?!?!?!
-        return new (
-                    foreground,
-                    background
-                   );
-    }
-
     /// <summary>Event fired when a key is pressed down. This is a precursor to <see cref="ConsoleDriver.KeyUp"/>.</summary>
     public event EventHandler<Key>? KeyDown;
 

+ 1 - 1
Terminal.Gui/Drivers/ConsoleKeyMapping.cs

@@ -533,7 +533,7 @@ public static class ConsoleKeyMapping
 
     /// <summary>
     ///     Get the output character from the <see cref="GetConsoleKeyInfoFromKeyCode"/>, with the correct
-    ///     <see cref="ConsoleKey"/> and the scan code used on <see cref="WindowsDriver"/>.
+    ///     <see cref="ConsoleKey"/> and the scan code used on Windows.
     /// </summary>
     /// <param name="unicodeChar">The unicode character.</param>
     /// <param name="modifiers">The modifiers keys.</param>

+ 35 - 0
Terminal.Gui/Drivers/ConsoleSizeMonitor.cs

@@ -0,0 +1,35 @@
+#nullable enable
+using Microsoft.Extensions.Logging;
+
+namespace Terminal.Gui.Drivers;
+
+/// <inheritdoc />
+internal class ConsoleSizeMonitor (IConsoleOutput consoleOut, IOutputBuffer _) : IConsoleSizeMonitor
+{
+    private Size _lastSize = Size.Empty;
+
+    /// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
+    public event EventHandler<SizeChangedEventArgs>? SizeChanged;
+
+    /// <inheritdoc/>
+    public bool Poll ()
+    {
+        if (ConsoleDriver.RunningUnitTests)
+        {
+            return false;
+        }
+
+        Size size = consoleOut.GetSize ();
+
+        if (size != _lastSize)
+        {
+            Logging.Logger.LogInformation ($"Console size changes from '{_lastSize}' to {size}");
+            _lastSize = size;
+            SizeChanged?.Invoke (this, new (size));
+
+            return true;
+        }
+
+        return false;
+    }
+}

+ 7 - 1
Terminal.Gui/Drivers/DotNetDriver/NetOutput.cs

@@ -35,7 +35,7 @@ public class NetOutput : OutputBase, IConsoleOutput
 
 
     /// <inheritdoc/>
-    public Size GetWindowSize ()
+    public Size GetSize ()
     {
         if (ConsoleDriver.RunningUnitTests)
         {
@@ -49,6 +49,12 @@ public class NetOutput : OutputBase, IConsoleOutput
     /// <inheritdoc/>
     public void SetCursorPosition (int col, int row) { SetCursorPositionImpl (col, row); }
 
+    /// <inheritdoc />
+    public void SetSize (int width, int height)
+    {
+        // Do Nothing.
+    }
+
     private Point? _lastCursorPosition;
 
     /// <inheritdoc/>

+ 59 - 0
Terminal.Gui/Drivers/FakeDriver/FakeClipboard.cs

@@ -0,0 +1,59 @@
+#nullable enable
+namespace Terminal.Gui.Drivers;
+
+/// <summary>
+///     Implements a fake clipboard for testing purposes.
+/// </summary>
+public class FakeClipboard : ClipboardBase
+{
+    /// <summary>
+    ///     Gets or sets an exception to be thrown by clipboard operations.
+    /// </summary>
+    public Exception? FakeException { get; set; }
+
+    private readonly bool _isSupportedAlwaysFalse;
+    private string _contents = string.Empty;
+
+    /// <summary>
+    ///     Constructs a new instance of <see cref="FakeClipboard"/>.
+    /// </summary>
+    /// <param name="fakeClipboardThrowsNotSupportedException"></param>
+    /// <param name="isSupportedAlwaysFalse"></param>
+    public FakeClipboard (
+        bool fakeClipboardThrowsNotSupportedException = false,
+        bool isSupportedAlwaysFalse = false
+    )
+    {
+        _isSupportedAlwaysFalse = isSupportedAlwaysFalse;
+
+        if (fakeClipboardThrowsNotSupportedException)
+        {
+            FakeException = new NotSupportedException ("Fake clipboard exception");
+        }
+    }
+
+    /// <inheritdoc />
+    public override bool IsSupported => !_isSupportedAlwaysFalse;
+
+    /// <inheritdoc />
+    protected override string GetClipboardDataImpl ()
+    {
+        if (FakeException is { })
+        {
+            throw FakeException;
+        }
+
+        return _contents;
+    }
+
+    /// <inheritdoc />
+    protected override void SetClipboardDataImpl (string? text)
+    {
+        if (FakeException is { })
+        {
+            throw FakeException;
+        }
+
+        _contents = text ?? throw new ArgumentNullException (nameof (text));
+    }
+}

+ 3 - 2
Terminal.Gui/Drivers/FakeDriver/FakeComponentFactory.cs

@@ -42,8 +42,9 @@ public class FakeComponentFactory : ComponentFactory<ConsoleKeyInfo>
     }
 
     /// <inheritdoc />
-    public override IWindowSizeMonitor CreateWindowSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
+    public override IConsoleSizeMonitor CreateConsoleSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
     {
-        return new FakeWindowSizeMonitor(consoleOutput, outputBuffer);
+        outputBuffer.SetSize(consoleOutput.GetSize().Width, consoleOutput.GetSize().Height);
+        return new ConsoleSizeMonitor (consoleOutput, outputBuffer);
     }
 }

+ 3 - 3
Terminal.Gui/Drivers/FakeDriver/FakeConsole.cs

@@ -32,10 +32,10 @@ public static class FakeConsole
 #pragma warning disable RCS1138 // Add summary to documentation comment.
 
     /// <summary>Specifies the initial console width.</summary>
-    public const int WIDTH = 80;
+    public const int WIDTH = 0;
 
     /// <summary>Specifies the initial console height.</summary>
-    public const int HEIGHT = 25;
+    public const int HEIGHT = 0;
 
     /// <summary></summary>
     public static int WindowWidth { get; set; } = WIDTH;
@@ -971,7 +971,7 @@ public static class FakeConsole
     /// <summary></summary>
     /// <param name="width"></param>
     /// <param name="height"></param>
-    public static void SetWindowSize (int width, int height)
+    public static void SetConsoleSize (int width, int height)
     {
         WindowWidth = width;
         WindowHeight = height;

+ 16 - 30
Terminal.Gui/Drivers/FakeDriver/FakeConsoleOutput.cs

@@ -1,33 +1,28 @@
 #nullable enable
-using System;
-using System.Text;
-
 namespace Terminal.Gui.Drivers;
 
 /// <summary>
-/// Fake console output for testing that captures what would be written to the console.
+///     Fake console output for testing that captures what would be written to the console.
 /// </summary>
 public class FakeConsoleOutput : OutputBase, IConsoleOutput
 {
     private readonly StringBuilder _output = new ();
     private int _cursorLeft;
     private int _cursorTop;
-    private Size _windowSize = new (80, 25);
+    private Size _consoleSize = new (80, 25);
 
     /// <summary>
-    /// Gets the captured output as a string.
+    ///     Gets the captured output as a string.
     /// </summary>
     public string Output => _output.ToString ();
 
-    /// <summary>
-    /// Clears the captured output.
-    /// </summary>
-    public void ClearOutput () => _output.Clear ();
-
     /// <inheritdoc/>
-    public void SetCursorPosition (int col, int row)
+    public void SetCursorPosition (int col, int row) { SetCursorPositionImpl (col, row); }
+
+    /// <inheritdoc />
+    public void SetSize (int width, int height)
     {
-        SetCursorPositionImpl (col, row);
+        _consoleSize = new (width, height);
     }
 
     /// <inheritdoc/>
@@ -35,30 +30,25 @@ public class FakeConsoleOutput : OutputBase, IConsoleOutput
     {
         _cursorLeft = col;
         _cursorTop = row;
+
         return true;
     }
 
     /// <summary>
-    /// Sets the fake window size.
+    ///     Sets the fake window size.
     /// </summary>
-    public void SetWindowSize (int width, int height)
-    {
-        _windowSize = new Size (width, height);
-    }
+    public void SetConsoleSize (int width, int height) { _consoleSize = new (width, height); }
 
     /// <summary>
-    /// Gets the current cursor position.
+    ///     Gets the current cursor position.
     /// </summary>
-    public (int left, int top) GetCursorPosition () => (_cursorLeft, _cursorTop);
+    public (int left, int top) GetCursorPosition () { return (_cursorLeft, _cursorTop); }
 
     /// <inheritdoc/>
-    public Size GetWindowSize () => _windowSize;
+    public Size GetSize () { return _consoleSize; }
 
     /// <inheritdoc/>
-    public void Write (ReadOnlySpan<char> text)
-    {
-        _output.Append (text);
-    }
+    public void Write (ReadOnlySpan<char> text) { _output.Append (text); }
 
     /// <inheritdoc/>
     public override void SetCursorVisibility (CursorVisibility visibility)
@@ -80,9 +70,5 @@ public class FakeConsoleOutput : OutputBase, IConsoleOutput
     }
 
     /// <inheritdoc/>
-    protected override void Write (StringBuilder output)
-    {
-        _output.Append (output);
-    }
-
+    protected override void Write (StringBuilder output) { _output.Append (output); }
 }

+ 33 - 177
Terminal.Gui/Drivers/FakeDriver/FakeDriver.cs

@@ -1,4 +1,5 @@
 #nullable enable
+
 //
 // FakeDriver.cs: A fake IConsoleDriver for unit tests. 
 //
@@ -6,8 +7,6 @@
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
-// Alias Console to MockConsole so we don't accidentally use Console
-
 namespace Terminal.Gui.Drivers;
 
 /// <summary>Implements a mock IConsoleDriver for unit testing</summary>
@@ -28,8 +27,8 @@ public class FakeDriver : ConsoleDriver
             FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue;
 
             // double check usage is correct
-            Debug.Assert (useFakeClipboard == false && fakeClipboardAlwaysThrowsNotSupportedException == false);
-            Debug.Assert (useFakeClipboard == false && fakeClipboardIsSupportedAlwaysTrue == false);
+            Debug.Assert (!useFakeClipboard && !fakeClipboardAlwaysThrowsNotSupportedException);
+            Debug.Assert (!useFakeClipboard && !fakeClipboardIsSupportedAlwaysTrue);
         }
 
         public bool FakeClipboardAlwaysThrowsNotSupportedException { get; internal set; }
@@ -40,19 +39,16 @@ public class FakeDriver : ConsoleDriver
     public static Behaviors FakeBehaviors { get; } = new ();
     public override bool SupportsTrueColor => false;
 
-    /// <inheritdoc />
-    public override void WriteRaw (string ansi)
-    {
-
-    }
+    /// <inheritdoc/>
+    public override void WriteRaw (string ansi) { }
 
     public FakeDriver ()
     {
         // FakeDriver implies UnitTests
         RunningUnitTests = true;
 
-        base.Cols = FakeConsole.WindowWidth = FakeConsole.BufferWidth = FakeConsole.WIDTH;
-        base.Rows = FakeConsole.WindowHeight = FakeConsole.BufferHeight = FakeConsole.HEIGHT;
+        //base.Cols = FakeConsole.WindowWidth = FakeConsole.BufferWidth = FakeConsole.WIDTH;
+        //base.Rows = FakeConsole.WindowHeight = FakeConsole.BufferHeight = FakeConsole.HEIGHT;
 
         if (FakeBehaviors.UseFakeClipboard)
         {
@@ -95,16 +91,19 @@ public class FakeDriver : ConsoleDriver
     {
         FakeConsole.MockKeyPresses.Clear ();
 
-        Cols = FakeConsole.WindowWidth = FakeConsole.BufferWidth = FakeConsole.WIDTH;
-        Rows = FakeConsole.WindowHeight = FakeConsole.BufferHeight = FakeConsole.HEIGHT;
+        //Cols = FakeConsole.WindowWidth = FakeConsole.BufferWidth = FakeConsole.WIDTH;
+        //Rows = FakeConsole.WindowHeight = FakeConsole.BufferHeight = FakeConsole.HEIGHT;
         FakeConsole.Clear ();
+
+        SetScreenSize (80,25);
         ResizeScreen ();
-        CurrentAttribute = new Attribute (Color.White, Color.Black);
+        ClearContents ();
+        CurrentAttribute = new (Color.White, Color.Black);
     }
 
     public override bool UpdateScreen ()
     {
-        bool updated = false;
+        var updated = false;
 
         int savedRow = FakeConsole.CursorTop;
         int savedCol = FakeConsole.CursorLeft;
@@ -223,117 +222,8 @@ public class FakeDriver : ConsoleDriver
         FakeConsole.CursorTop = savedRow;
         FakeConsole.CursorLeft = savedCol;
         FakeConsole.CursorVisible = savedCursorVisible;
-        return updated;
-    }
-
-
-    #region Color Handling
-
-    ///// <remarks>
-    ///// In the FakeDriver, colors are encoded as an int; same as DotNetDriver
-    ///// However, the foreground color is stored in the most significant 16 bits, 
-    ///// and the background color is stored in the least significant 16 bits.
-    ///// </remarks>
-    //public override Attribute MakeColor (Color foreground, Color background)
-    //{
-    //	// Encode the colors into the int value.
-    //	return new Attribute (
-    //		foreground: foreground,
-    //		background: background
-    //	);
-    //}
-
-    #endregion
-
-    private KeyCode MapKey (ConsoleKeyInfo keyInfo)
-    {
-        switch (keyInfo.Key)
-        {
-            case ConsoleKey.Escape:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Esc);
-            case ConsoleKey.Tab:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Tab);
-            case ConsoleKey.Clear:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Clear);
-            case ConsoleKey.Home:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Home);
-            case ConsoleKey.End:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.End);
-            case ConsoleKey.LeftArrow:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.CursorLeft);
-            case ConsoleKey.RightArrow:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.CursorRight);
-            case ConsoleKey.UpArrow:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.CursorUp);
-            case ConsoleKey.DownArrow:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.CursorDown);
-            case ConsoleKey.PageUp:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.PageUp);
-            case ConsoleKey.PageDown:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.PageDown);
-            case ConsoleKey.Enter:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Enter);
-            case ConsoleKey.Spacebar:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (
-                                                                keyInfo.Modifiers,
-                                                                keyInfo.KeyChar == 0
-                                                                    ? KeyCode.Space
-                                                                    : (KeyCode)keyInfo.KeyChar
-                                                               );
-            case ConsoleKey.Backspace:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Backspace);
-            case ConsoleKey.Delete:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Delete);
-            case ConsoleKey.Insert:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.Insert);
-            case ConsoleKey.PrintScreen:
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, KeyCode.PrintScreen);
-
-            case ConsoleKey.Oem1:
-            case ConsoleKey.Oem2:
-            case ConsoleKey.Oem3:
-            case ConsoleKey.Oem4:
-            case ConsoleKey.Oem5:
-            case ConsoleKey.Oem6:
-            case ConsoleKey.Oem7:
-            case ConsoleKey.Oem8:
-            case ConsoleKey.Oem102:
-            case ConsoleKey.OemPeriod:
-            case ConsoleKey.OemComma:
-            case ConsoleKey.OemPlus:
-            case ConsoleKey.OemMinus:
-                if (keyInfo.KeyChar == 0)
-                {
-                    return KeyCode.Null;
-                }
-
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
-        }
-
-        ConsoleKey key = keyInfo.Key;
-
-        if (key >= ConsoleKey.A && key <= ConsoleKey.Z)
-        {
-            int delta = key - ConsoleKey.A;
-
-            if (keyInfo.KeyChar != (uint)key)
-            {
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.Key);
-            }
-
-            if (keyInfo.Modifiers.HasFlag (ConsoleModifiers.Control)
-                || keyInfo.Modifiers.HasFlag (ConsoleModifiers.Alt)
-                || keyInfo.Modifiers.HasFlag (ConsoleModifiers.Shift))
-            {
-                return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)KeyCode.A + delta));
-            }
 
-            char alphaBase = keyInfo.Modifiers != ConsoleModifiers.Shift ? 'A' : 'a';
-
-            return (KeyCode)((uint)alphaBase + delta);
-        }
-
-        return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
+        return updated;
     }
 
     private CursorVisibility _savedCursorVisibility;
@@ -356,7 +246,6 @@ public class FakeDriver : ConsoleDriver
         return FakeConsole.CursorVisible = visibility == CursorVisibility.Default;
     }
 
-    /// <inheritdoc/>
     private bool EnsureCursorVisibility ()
     {
         if (!(Col >= 0 && Row >= 0 && Col < Cols && Row < Rows))
@@ -373,23 +262,32 @@ public class FakeDriver : ConsoleDriver
         return FakeConsole.CursorVisible;
     }
 
-    private AnsiResponseParser _parser = new ();
+    private readonly AnsiResponseParser _parser = new ();
+
+    /// <inheritdoc/>
+    internal override IAnsiResponseParser GetParser () { return _parser; }
 
-    /// <inheritdoc />
-    internal override IAnsiResponseParser GetParser () => _parser;
+    /// <summary>
+    ///     Sets the screen size for testing purposes. Only available in FakeDriver.
+    ///     This method updates the driver's dimensions and triggers the ScreenChanged event.
+    /// </summary>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    public override void SetScreenSize (int width, int height) { SetBufferSize (width, height); }
 
     public void SetBufferSize (int width, int height)
     {
         FakeConsole.SetBufferSize (width, height);
         Cols = width;
         Rows = height;
-        SetWindowSize (width, height);
+        SetConsoleSize (width, height);
         ProcessResize ();
     }
 
-    public void SetWindowSize (int width, int height)
+    public void SetConsoleSize (int width, int height)
     {
-        FakeConsole.SetWindowSize (width, height);
+        FakeConsole.SetConsoleSize (width, height);
+        FakeConsole.SetBufferSize (width, height);
 
         if (width != Cols || height != Rows)
         {
@@ -416,7 +314,7 @@ public class FakeDriver : ConsoleDriver
     {
         ResizeScreen ();
         ClearContents ();
-        OnSizeChanged (new SizeChangedEventArgs (new (Cols, Rows)));
+        OnSizeChanged (new (new (Cols, Rows)));
     }
 
     public virtual void ResizeScreen ()
@@ -452,7 +350,7 @@ public class FakeDriver : ConsoleDriver
             return;
         }
 
-        // Prevents the exception of size changing during resizing.
+        // Prevents the exception to size changing during resizing.
         try
         {
             // BUGBUG: Why is this using BufferWidth/Height and now Cols/Rows?
@@ -476,48 +374,6 @@ public class FakeDriver : ConsoleDriver
 
     #endregion
 
-    public class FakeClipboard : ClipboardBase
-    {
-        public Exception? FakeException { get; set; }
-
-        private readonly bool _isSupportedAlwaysFalse;
-        private string _contents = string.Empty;
-
-        public FakeClipboard (
-            bool fakeClipboardThrowsNotSupportedException = false,
-            bool isSupportedAlwaysFalse = false
-        )
-        {
-            _isSupportedAlwaysFalse = isSupportedAlwaysFalse;
-
-            if (fakeClipboardThrowsNotSupportedException)
-            {
-                FakeException = new NotSupportedException ("Fake clipboard exception");
-            }
-        }
-
-        public override bool IsSupported => !_isSupportedAlwaysFalse;
-
-        protected override string GetClipboardDataImpl ()
-        {
-            if (FakeException is { })
-            {
-                throw FakeException;
-            }
-
-            return _contents;
-        }
-
-        protected override void SetClipboardDataImpl (string? text)
-        {
-            if (FakeException is { })
-            {
-                throw FakeException;
-            }
-
-            _contents = text ?? throw new ArgumentNullException (nameof (text));
-        }
-    }
 
 #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
-}
+}

+ 0 - 41
Terminal.Gui/Drivers/FakeDriver/FakeWindowSizeMonitor.cs

@@ -1,41 +0,0 @@
-using Microsoft.Extensions.Logging;
-
-namespace Terminal.Gui.Drivers;
-
-internal class FakeWindowSizeMonitor (IConsoleOutput consoleOut, IOutputBuffer outputBuffer) : IWindowSizeMonitor
-{
-    private Size _lastSize = new (0, 0);
-
-    /// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
-    public event EventHandler<SizeChangedEventArgs> SizeChanging;
-
-    /// <summary>Raises the <see cref="SizeChanging"/> event with the specified size. Used for testing.</summary>
-    /// <param name="newSize">The new size to report.</param>
-    public void RaiseSizeChanging (Size newSize)
-    {
-        SizeChanging?.Invoke (this, new (newSize));
-    }
-
-    /// <inheritdoc/>
-    public bool Poll ()
-    {
-        if (ConsoleDriver.RunningUnitTests)
-        {
-            return false;
-        }
-
-        Size size = consoleOut.GetWindowSize ();
-
-        if (size != _lastSize)
-        {
-            Logging.Logger.LogInformation ($"Console size changes from '{_lastSize}' to {size}");
-            outputBuffer.SetWindowSize (size.Width, size.Height);
-            _lastSize = size;
-            SizeChanging?.Invoke (this, new (size));
-
-            return true;
-        }
-
-        return false;
-    }
-}

+ 3 - 3
Terminal.Gui/Drivers/IComponentFactory.cs

@@ -41,11 +41,11 @@ public interface IComponentFactory<T> : IComponentFactory
     IInputProcessor CreateInputProcessor (ConcurrentQueue<T> inputBuffer);
 
     /// <summary>
-    /// Creates <see cref="IWindowSizeMonitor"/> class for the current driver implementation i.e. the class responsible for
-    /// reporting the current size of the terminal window.
+    /// Creates <see cref="IConsoleSizeMonitor"/> class for the current driver implementation i.e. the class responsible for
+    /// reporting the current size of the terminal.
     /// </summary>
     /// <param name="consoleOutput"></param>
     /// <param name="outputBuffer"></param>
     /// <returns></returns>
-    IWindowSizeMonitor CreateWindowSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer);
+    IConsoleSizeMonitor CreateConsoleSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer);
 }

+ 14 - 8
Terminal.Gui/Drivers/IConsoleDriver.cs

@@ -14,6 +14,15 @@ public interface IConsoleDriver
     /// <summary>Gets the location and size of the terminal screen.</summary>
     Rectangle Screen { get; }
 
+    /// <summary>
+    /// Sets the screen size for testing purposes. Only supported by FakeDriver.
+    /// <see cref="Screen"/> is the source of truth for screen dimensions.
+    /// </summary>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    /// <exception cref="NotSupportedException">Thrown when called on non-FakeDriver instances.</exception>
+    void SetScreenSize (int width, int height);
+
     /// <summary>
     ///     Gets or sets the clip rectangle that <see cref="AddRune(Rune)"/> and <see cref="AddStr(string)"/> are subject
     ///     to.
@@ -200,11 +209,14 @@ public interface IConsoleDriver
     /// <returns><see langword="true"/> upon success</returns>
     bool SetCursorVisibility (CursorVisibility visibility);
 
-    /// <summary>The event fired when the terminal is resized.</summary>
+    /// <summary>
+    /// The event fired when the screen changes (size, position, etc.).
+    /// <see cref="Screen"/> is the source of truth for screen dimensions.
+    /// </summary>
     event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     /// <summary>Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver.</summary>
-    /// <remarks>This is only implemented in <see cref="UnixDriver"/>.</remarks>
+    /// <remarks>This is only implemented in UnixDriver.</remarks>
     void Suspend ();
 
     /// <summary>
@@ -228,12 +240,6 @@ public interface IConsoleDriver
     /// <returns>The current attribute.</returns>
     Attribute GetAttribute ();
 
-    /// <summary>Makes an <see cref="Attribute"/>.</summary>
-    /// <param name="foreground">The foreground color.</param>
-    /// <param name="background">The background color.</param>
-    /// <returns>The attribute for the foreground and background colors.</returns>
-    Attribute MakeColor (in Color foreground, in Color background);
-
     /// <summary>Event fired when a mouse event occurs.</summary>
     event EventHandler<MouseEventArgs>? MouseEvent;
 

+ 1 - 1
Terminal.Gui/Drivers/IConsoleDriverFacade.cs

@@ -22,5 +22,5 @@ public interface IConsoleDriverFacade
     ///     Interface for classes responsible for reporting the current
     ///     size of the terminal window.
     /// </summary>
-    IWindowSizeMonitor WindowSizeMonitor { get; }
+    IConsoleSizeMonitor ConsoleSizeMonitor { get; }
 }

+ 9 - 2
Terminal.Gui/Drivers/IConsoleOutput.cs

@@ -20,11 +20,11 @@ public interface IConsoleOutput : IDisposable
     void Write (IOutputBuffer buffer);
 
     /// <summary>
-    ///     Returns the current size of the console window in rows/columns (i.e.
+    ///     Returns the current size of the console in rows/columns (i.e.
     ///     of characters not pixels).
     /// </summary>
     /// <returns></returns>
-    public Size GetWindowSize ();
+    public Size GetSize ();
 
     /// <summary>
     ///     Updates the console cursor (the blinking underscore) to be hidden,
@@ -39,4 +39,11 @@ public interface IConsoleOutput : IDisposable
     /// <param name="col"></param>
     /// <param name="row"></param>
     void SetCursorPosition (int col, int row);
+
+    /// <summary>
+    ///     Sets the size of the console..
+    /// </summary>
+    /// <param name="width"></param>
+    /// <param name="height"></param>
+    void SetSize (int width, int height);
 }

+ 3 - 3
Terminal.Gui/Drivers/IWindowSizeMonitor.cs → Terminal.Gui/Drivers/IConsoleSizeMonitor.cs

@@ -6,13 +6,13 @@ namespace Terminal.Gui.Drivers;
 ///     Interface for classes responsible for reporting the current
 ///     size of the terminal window.
 /// </summary>
-public interface IWindowSizeMonitor
+public interface IConsoleSizeMonitor
 {
     /// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
-    event EventHandler<SizeChangedEventArgs>? SizeChanging;
+    event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     /// <summary>
-    ///     Examines the current size of the terminal and raises <see cref="SizeChanging"/> if it is different
+    ///     Examines the current size of the terminal and raises <see cref="SizeChanged"/> if it is different
     ///     from last inspection.
     /// </summary>
     /// <returns></returns>

+ 1 - 1
Terminal.Gui/Drivers/IInputProcessor.cs

@@ -28,7 +28,7 @@ public interface IInputProcessor
     /// <summary>
     /// Gets the name of the driver associated with this input processor.
     /// </summary>
-    string DriverName { get; init; }
+    string? DriverName { get; init; }
 
     /// <summary>
     ///     Called when a key is pressed down. Fires the <see cref="KeyDown"/> event. This is a precursor to

+ 1 - 1
Terminal.Gui/Drivers/IOutputBuffer.cs

@@ -97,7 +97,7 @@ public interface IOutputBuffer
     /// </summary>
     /// <param name="cols"></param>
     /// <param name="rows"></param>
-    void SetWindowSize (int cols, int rows);
+    void SetSize (int cols, int rows);
 
     /// <summary>
     ///     Fills the given <paramref name="rect"/> with the given

+ 2 - 2
Terminal.Gui/Drivers/InputProcessor.cs

@@ -31,7 +31,7 @@ public abstract class InputProcessor<T> : IInputProcessor
     public ConcurrentQueue<T> InputBuffer { get; }
 
     /// <inheritdoc />
-    public string DriverName { get; init; }
+    public string? DriverName { get; init; }
 
     /// <inheritdoc/>
     public IAnsiResponseParser GetParser () { return Parser; }
@@ -166,7 +166,7 @@ public abstract class InputProcessor<T> : IInputProcessor
     /// <param name="input"></param>
     protected abstract void ProcessAfterParsing (T input);
 
-    internal char _highSurrogate = '\0';
+    private char _highSurrogate = '\0';
 
     /// <inheritdoc />
     public bool IsValidInput (Key key, out Key result)

+ 1 - 1
Terminal.Gui/Drivers/MouseButtonStateEx.cs

@@ -3,7 +3,7 @@
 namespace Terminal.Gui.Drivers;
 
 /// <summary>
-///     Not to be confused with <see cref="NetEvents.MouseButtonState"/>
+///     Not to be confused with NetEvents.MouseButtonState
 /// </summary>
 internal class MouseButtonStateEx
 {

+ 1 - 1
Terminal.Gui/Drivers/OutputBase.cs

@@ -56,7 +56,7 @@ public abstract class OutputBase
 
                 for (; col < cols; col++)
                 {
-                    if (!buffer.Contents [row, col].IsDirty)
+                    if (!buffer.Contents! [row, col].IsDirty)
                     {
                         if (output.Length > 0)
                         {

+ 3 - 3
Terminal.Gui/Drivers/OutputBuffer.cs

@@ -5,7 +5,7 @@ namespace Terminal.Gui.Drivers;
 
 /// <summary>
 ///     Stores the desired output state for the whole application. This is updated during
-///     draw operations before being flushed to the console as part of <see cref="MainLoop{T}"/>
+///     draw operations before being flushed to the console as part of the main loop.
 ///     operation
 /// </summary>
 public class OutputBuffer : IOutputBuffer
@@ -15,7 +15,7 @@ public class OutputBuffer : IOutputBuffer
     ///     UpdateScreen is called.
     ///     <remarks>The format of the array is rows, columns. The first index is the row, the second index is the column.</remarks>
     /// </summary>
-    public Cell [,] Contents { get; set; } = new Cell[0, 0];
+    public Cell [,]? Contents { get; set; } = new Cell[0, 0];
 
     private int _cols;
     private int _rows;
@@ -365,7 +365,7 @@ public class OutputBuffer : IOutputBuffer
     }
 
     /// <inheritdoc/>
-    public void SetWindowSize (int cols, int rows)
+    public void SetSize (int cols, int rows)
     {
         Cols = cols;
         Rows = rows;

+ 7 - 1
Terminal.Gui/Drivers/UnixDriver/UnixOutput.cs

@@ -121,7 +121,7 @@ internal class UnixOutput : OutputBase, IConsoleOutput
     }
 
     /// <inheritdoc />
-    public Size GetWindowSize ()
+    public Size GetSize ()
     {
         if (ConsoleDriver.RunningUnitTests)
         {
@@ -168,6 +168,12 @@ internal class UnixOutput : OutputBase, IConsoleOutput
         SetCursorPositionImpl (col, row);
     }
 
+    /// <inheritdoc />
+    public void SetSize (int width, int height)
+    {
+        // Do nothing
+    }
+
     /// <inheritdoc />
     public void Dispose ()
     {

+ 0 - 42
Terminal.Gui/Drivers/WindowSizeMonitor.cs

@@ -1,42 +0,0 @@
-using Microsoft.Extensions.Logging;
-
-namespace Terminal.Gui.Drivers;
-
-internal class WindowSizeMonitor : IWindowSizeMonitor
-{
-    private readonly IConsoleOutput _consoleOut;
-    private readonly IOutputBuffer _outputBuffer;
-    private Size _lastSize = new (0, 0);
-
-    /// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
-    public event EventHandler<SizeChangedEventArgs> SizeChanging;
-
-    public WindowSizeMonitor (IConsoleOutput consoleOut, IOutputBuffer outputBuffer)
-    {
-        _consoleOut = consoleOut;
-        _outputBuffer = outputBuffer;
-    }
-
-    /// <inheritdoc/>
-    public bool Poll ()
-    {
-        if (ConsoleDriver.RunningUnitTests)
-        {
-            return false;
-        }
-
-        Size size = _consoleOut.GetWindowSize ();
-
-        if (size != _lastSize)
-        {
-            Logging.Logger.LogInformation ($"Console size changes from '{_lastSize}' to {size}");
-            _outputBuffer.SetWindowSize (size.Width, size.Height);
-            _lastSize = size;
-            SizeChanging?.Invoke (this, new (size));
-
-            return true;
-        }
-
-        return false;
-    }
-}

+ 31 - 908
Terminal.Gui/Drivers/WindowsDriver/WindowsConsole.cs

@@ -1,719 +1,25 @@
 #nullable enable
-using System.Collections.Concurrent;
-using System.ComponentModel;
 using System.Runtime.InteropServices;
-#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
-#pragma warning disable IDE1006// Naming rule violation: Prefix '_' is not expected
+
+// ReSharper disable InconsistentNaming
 
 namespace Terminal.Gui.Drivers;
 
-public partial class WindowsConsole
-{
-    private CancellationTokenSource? _inputReadyCancellationTokenSource;
-    private readonly BlockingCollection<InputRecord> _inputQueue = new (new ConcurrentQueue<InputRecord> ());
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
 
-    public const int STD_OUTPUT_HANDLE = -11;
+/// <summary>
+///     Definitions for Windows Console API structures and constants.
+/// </summary>
+public class WindowsConsole
+{
+    /// <summary>
+    ///     Standard input handle constant.
+    /// </summary>
     public const int STD_INPUT_HANDLE = -10;
 
-    private readonly nint _inputHandle;
-    private nint _outputHandle;
-    private nint _screenBuffer;
-    private readonly uint _originalConsoleMode;
-    private CursorVisibility? _initialCursorVisibility;
-    private CursorVisibility? _currentCursorVisibility;
-    private CursorVisibility? _pendingCursorVisibility;
-    private readonly StringBuilder _stringBuilder = new (256 * 1024);
-    private string _lastWrite = string.Empty;
-
-    public WindowsConsole ()
-    {
-        _inputHandle = GetStdHandle (STD_INPUT_HANDLE);
-        _outputHandle = GetStdHandle (STD_OUTPUT_HANDLE);
-        _originalConsoleMode = ConsoleMode;
-        uint newConsoleMode = _originalConsoleMode;
-        newConsoleMode |= (uint)(ConsoleModes.EnableMouseInput | ConsoleModes.EnableExtendedFlags);
-        newConsoleMode &= ~(uint)ConsoleModes.EnableQuickEditMode;
-        newConsoleMode &= ~(uint)ConsoleModes.EnableProcessedInput;
-        ConsoleMode = newConsoleMode;
-
-        IsVirtualTerminal = GetConsoleMode (_outputHandle, out uint mode) && (mode & (uint)ConsoleModes.EnableVirtualTerminalProcessing) != 0;
-
-        if (!IsVirtualTerminal)
-        {
-            CreateConsoleScreenBuffer ();
-            Size bufferSize = GetConsoleBufferWindow (out _);
-            SmallRect window = new ()
-            {
-                Top = 0,
-                Left = 0,
-                Bottom = (short)bufferSize.Height,
-                Right = (short)bufferSize.Width
-            };
-
-            ReadFromConsoleOutput (bufferSize, new ((short)bufferSize.Width, (short)bufferSize.Height), ref window);
-
-            if (!GetConsoleMode (_screenBuffer, out mode))
-            {
-                throw new ApplicationException ($"Failed to get screenBuffer console mode, error code: {Marshal.GetLastWin32Error ()}.");
-            }
-
-            const uint ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002;
-
-            mode &= ~ENABLE_WRAP_AT_EOL_OUTPUT; // Disable wrap
-
-            if (!SetConsoleMode (_screenBuffer, mode))
-            {
-                throw new ApplicationException ($"Failed to set screenBuffer console mode, error code: {Marshal.GetLastWin32Error ()}.");
-            }
-        }
-
-        SetInitialCursorVisibility ();
-
-        _inputReadyCancellationTokenSource = new ();
-        Task.Run (ProcessInputQueue, _inputReadyCancellationTokenSource.Token);
-    }
-
-    private void CreateConsoleScreenBuffer ()
-    {
-        _screenBuffer = CreateConsoleScreenBuffer (
-                                                   DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
-                                                   ShareMode.FileShareRead | ShareMode.FileShareWrite,
-                                                   nint.Zero,
-                                                   1,
-                                                   nint.Zero
-                                                  );
-
-        if (_screenBuffer == INVALID_HANDLE_VALUE)
-        {
-            int err = Marshal.GetLastWin32Error ();
-
-            if (err != 0)
-            {
-                throw new Win32Exception (err);
-            }
-        }
-
-        if (!SetConsoleActiveScreenBuffer (_screenBuffer))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-    }
-
-    public InputRecord? DequeueInput ()
-    {
-        while (_inputReadyCancellationTokenSource is { })
-        {
-            try
-            {
-                return _inputQueue.Take (_inputReadyCancellationTokenSource.Token);
-            }
-            catch (OperationCanceledException)
-            {
-                return null;
-            }
-        }
-
-        return null;
-    }
-
-    public InputRecord? ReadConsoleInput ()
-    {
-        const int BUFFER_SIZE = 1;
-        InputRecord inputRecord = default;
-        uint numberEventsRead = 0;
-
-        while (_inputReadyCancellationTokenSource is { IsCancellationRequested: false })
-        {
-            try
-            {
-                // Peek to check if there is any input available
-                if (PeekConsoleInput (_inputHandle, out _, BUFFER_SIZE, out uint eventsRead) && eventsRead > 0)
-                {
-                    // Read the input since it is available
-                    ReadConsoleInput (
-                                      _inputHandle,
-                                      out inputRecord,
-                                      BUFFER_SIZE,
-                                      out numberEventsRead);
-                }
-
-                if (numberEventsRead > 0)
-                {
-                    return inputRecord;
-                }
-
-                try
-                {
-                    Task.Delay (100, _inputReadyCancellationTokenSource.Token).Wait (_inputReadyCancellationTokenSource.Token);
-                }
-                catch (OperationCanceledException)
-                {
-                    return null;
-                }
-            }
-            catch (Exception ex)
-            {
-                if (ex is OperationCanceledException or ObjectDisposedException)
-                {
-                    return null;
-                }
-
-                throw;
-            }
-        }
-
-        return null;
-    }
-
-    private void ProcessInputQueue ()
-    {
-        while (_inputReadyCancellationTokenSource is { IsCancellationRequested: false })
-        {
-            try
-            {
-                if (_inputQueue.Count == 0)
-                {
-                    while (_inputReadyCancellationTokenSource is { IsCancellationRequested: false })
-                    {
-                        try
-                        {
-                            InputRecord? inpRec = ReadConsoleInput ();
-
-                            if (inpRec is { })
-                            {
-                                _inputQueue.Add (inpRec.Value);
-
-                                break;
-                            }
-                        }
-                        catch (OperationCanceledException)
-                        {
-                            return;
-                        }
-                    }
-                }
-            }
-            catch (OperationCanceledException)
-            {
-                return;
-            }
-        }
-    }
-
-
-    // Last text style used, for updating style with EscSeqUtils.CSI_AppendTextStyleChange().
-    private TextStyle _redrawTextStyle = TextStyle.None;
-
-    private CharInfo []? _originalStdOutChars;
-
-    private struct Run
-    {
-        public ushort attr;
-        public string text;
-
-        public Run (ushort attr, string text)
-        {
-            this.attr = attr;
-            this.text = text;
-        }
-    }
-
-    public bool WriteToConsole (Size size, ExtendedCharInfo [] charInfoBuffer, Coord bufferSize, SmallRect window, bool force16Colors)
-    {
-        //Debug.WriteLine ("WriteToConsole");
-
-        Attribute? prev = null;
-        var result = false;
-
-        if (force16Colors)
-        {
-            _stringBuilder.Clear ();
-
-            var i = 0;
-            List<Run> runs = [];
-            Run? current = null;
-            SetCursorPosition (new Coord (0, 0));
-
-            foreach (ExtendedCharInfo info in charInfoBuffer)
-            {
-                if (IsVirtualTerminal)
-                {
-                    Attribute attr = info.Attribute;
-                    AnsiColorCode fgColor = info.Attribute.Foreground.GetAnsiColorCode ();
-                    AnsiColorCode bgColor = info.Attribute.Background.GetAnsiColorCode ();
-
-                    if (attr != prev)
-                    {
-                        prev = attr;
-                        _stringBuilder.Append (EscSeqUtils.CSI_SetForegroundColor (fgColor));
-                        _stringBuilder.Append (EscSeqUtils.CSI_SetBackgroundColor (bgColor));
-
-                        EscSeqUtils.CSI_AppendTextStyleChange (_stringBuilder, _redrawTextStyle, attr.Style);
-                        _redrawTextStyle = attr.Style;
-                    }
-
-                    if (info.Char [0] != '\x1b')
-                    {
-                        if (!info.Empty)
-                        {
-                            _stringBuilder.Append (info.Char);
-                        }
-                    }
-                    else
-                    {
-                        _stringBuilder.Append (' ');
-                    }
-                }
-                else
-                {
-                    if (info.Empty)
-                    {
-                        i++;
-                        continue;
-                    }
-
-                    if (!info.Empty)
-                    {
-                        var attr = (ushort)((int)info.Attribute.Foreground.GetClosestNamedColor16 ()
-                                            | ((int)info.Attribute.Background.GetClosestNamedColor16 () << 4));
-
-                        // Start new run if needed
-                        if (current == null || attr != current.Value.attr)
-                        {
-                            if (current != null)
-                            {
-                                runs.Add (new (current.Value.attr, _stringBuilder.ToString ()));
-                            }
-
-                            _stringBuilder.Clear ();
-                            current = new Run (attr, "");
-                        }
-
-                        _stringBuilder!.Append (info.Char);
-                    }
-
-                    i++;
-
-                    if (i > 0 && i <= charInfoBuffer.Length && i % bufferSize.X == 0)
-                    {
-                        if (i < charInfoBuffer.Length)
-                        {
-                            _stringBuilder.AppendLine ();
-                        }
-
-                        runs.Add (new (current!.Value.attr, _stringBuilder.ToString ()));
-                        _stringBuilder.Clear ();
-                    }
-                }
-            }
-
-            if (IsVirtualTerminal)
-            {
-                _stringBuilder.Append (EscSeqUtils.CSI_RestoreCursorPosition);
-                _stringBuilder.Append (EscSeqUtils.CSI_HideCursor);
-
-                var s = _stringBuilder.ToString ();
-
-                // TODO: requires extensive testing if we go down this route
-                // If console output has changed
-                if (s != _lastWrite)
-                {
-                    // supply console with the new content
-                    result = WriteConsole (_outputHandle, s, (uint)s.Length, out uint _, nint.Zero);
-                }
-
-                _lastWrite = s;
-
-                foreach (var sixel in Application.Sixel)
-                {
-                    SetCursorPosition (new Coord ((short)sixel.ScreenPosition.X, (short)sixel.ScreenPosition.Y));
-                    WriteConsole (IsVirtualTerminal ? _outputHandle : _screenBuffer, sixel.SixelData, (uint)sixel.SixelData.Length, out uint _, nint.Zero);
-                }
-            }
-            else
-            {
-                foreach (var run in runs)
-                {
-                    SetConsoleTextAttribute (IsVirtualTerminal ? _outputHandle : _screenBuffer, run.attr);
-                    result = WriteConsole (IsVirtualTerminal ? _outputHandle : _screenBuffer, run.text, (uint)run.text.Length, out _, nint.Zero);
-                }
-            }
-        }
-        else
-        {
-            _stringBuilder.Clear ();
-
-            _stringBuilder.Append (EscSeqUtils.CSI_SaveCursorPosition);
-            EscSeqUtils.CSI_AppendCursorPosition (_stringBuilder, 0, 0);
-
-            foreach (ExtendedCharInfo info in charInfoBuffer)
-            {
-                Attribute attr = info.Attribute;
-
-                if (attr != prev)
-                {
-                    prev = attr;
-                    EscSeqUtils.CSI_AppendForegroundColorRGB (_stringBuilder, attr.Foreground.R, attr.Foreground.G, attr.Foreground.B);
-                    EscSeqUtils.CSI_AppendBackgroundColorRGB (_stringBuilder, attr.Background.R, attr.Background.G, attr.Background.B);
-                    EscSeqUtils.CSI_AppendTextStyleChange (_stringBuilder, _redrawTextStyle, attr.Style);
-                    _redrawTextStyle = attr.Style;
-                }
-
-                if (info.Char [0] != '\x1b')
-                {
-                    if (!info.Empty)
-                    {
-                        _stringBuilder.Append (info.Char);
-                    }
-                }
-                else
-                {
-                    _stringBuilder.Append (' ');
-                }
-            }
-
-            _stringBuilder.Append (EscSeqUtils.CSI_RestoreCursorPosition);
-            _stringBuilder.Append (EscSeqUtils.CSI_HideCursor);
-
-            var s = _stringBuilder.ToString ();
-
-            // TODO: requires extensive testing if we go down this route
-            // If console output has changed
-            if (s != _lastWrite)
-            {
-                // supply console with the new content
-                result = WriteConsole (_outputHandle, s, (uint)s.Length, out uint _, nint.Zero);
-            }
-
-            _lastWrite = s;
-
-            foreach (var sixel in Application.Sixel)
-            {
-                SetCursorPosition (new Coord ((short)sixel.ScreenPosition.X, (short)sixel.ScreenPosition.Y));
-                WriteConsole (IsVirtualTerminal ? _outputHandle : _screenBuffer, sixel.SixelData, (uint)sixel.SixelData.Length, out uint _, nint.Zero);
-            }
-        }
-
-        if (!result)
-        {
-            int err = Marshal.GetLastWin32Error ();
-
-            if (err != 0)
-            {
-                throw new Win32Exception (err);
-            }
-        }
-
-        return result;
-    }
-
-    internal bool WriteANSI (string ansi)
-    {
-        if (WriteConsole (_outputHandle, ansi, (uint)ansi.Length, out uint _, nint.Zero))
-        {
-            // Flush the output to make sure it's sent immediately
-            return FlushFileBuffers (_outputHandle);
-        }
-
-        return false;
-    }
-
-    public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
-    {
-        _originalStdOutChars = new CharInfo [size.Height * size.Width];
-
-        if (!ReadConsoleOutput (_screenBuffer, _originalStdOutChars, coords, new Coord { X = 0, Y = 0 }, ref window))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-    }
-
-    public bool SetCursorPosition (Coord position)
-    {
-        return SetConsoleCursorPosition (IsVirtualTerminal ? _outputHandle : _screenBuffer, position);
-    }
-
-    public void SetInitialCursorVisibility ()
-    {
-        if (_initialCursorVisibility.HasValue == false && GetCursorVisibility (out CursorVisibility visibility))
-        {
-            _initialCursorVisibility = visibility;
-        }
-    }
-
-    public bool GetCursorVisibility (out CursorVisibility visibility)
-    {
-        if ((IsVirtualTerminal ? _outputHandle : _screenBuffer) == nint.Zero)
-        {
-            visibility = CursorVisibility.Invisible;
-
-            return false;
-        }
-
-        if (!GetConsoleCursorInfo (IsVirtualTerminal ? _outputHandle : _screenBuffer, out ConsoleCursorInfo info))
-        {
-            int err = Marshal.GetLastWin32Error ();
-
-            if (err != 0)
-            {
-                throw new Win32Exception (err);
-            }
-
-            visibility = CursorVisibility.Default;
-
-            return false;
-        }
-
-        if (!info.bVisible)
-        {
-            visibility = CursorVisibility.Invisible;
-        }
-        else if (info.dwSize > 50)
-        {
-            visibility = CursorVisibility.Default;
-        }
-        else
-        {
-            visibility = CursorVisibility.Default;
-        }
-
-        return visibility != CursorVisibility.Invisible;
-    }
-
-    public bool EnsureCursorVisibility ()
-    {
-        if (_initialCursorVisibility.HasValue && _pendingCursorVisibility.HasValue && SetCursorVisibility (_pendingCursorVisibility.Value))
-        {
-            _pendingCursorVisibility = null;
-
-            return true;
-        }
-
-        return false;
-    }
-
-    public void ForceRefreshCursorVisibility ()
-    {
-        if (_currentCursorVisibility.HasValue)
-        {
-            _pendingCursorVisibility = _currentCursorVisibility;
-            _currentCursorVisibility = null;
-        }
-    }
-
-    public bool SetCursorVisibility (CursorVisibility visibility)
-    {
-        if (_initialCursorVisibility.HasValue == false)
-        {
-            _pendingCursorVisibility = visibility;
-
-            return false;
-        }
-
-        if (_currentCursorVisibility.HasValue == false || _currentCursorVisibility.Value != visibility)
-        {
-            var info = new ConsoleCursorInfo
-            {
-                dwSize = (uint)visibility & 0x00FF,
-                bVisible = ((uint)visibility & 0xFF00) != 0
-            };
-
-            if (!SetConsoleCursorInfo (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref info))
-            {
-                return false;
-            }
-
-            _currentCursorVisibility = visibility;
-        }
-
-        return true;
-    }
-
-    public void Cleanup ()
-    {
-        if (_initialCursorVisibility.HasValue)
-        {
-            SetCursorVisibility (_initialCursorVisibility.Value);
-        }
-
-        //SetConsoleOutputWindow (out _);
-
-        ConsoleMode = _originalConsoleMode;
-
-        _outputHandle = CreateConsoleScreenBuffer (
-                                                   DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
-                                                   ShareMode.FileShareRead | ShareMode.FileShareWrite,
-                                                   nint.Zero,
-                                                   1,
-                                                   nint.Zero
-                                                  );
-
-        if (!SetConsoleActiveScreenBuffer (_outputHandle))
-        {
-            int err = Marshal.GetLastWin32Error ();
-            Console.WriteLine ("Error: {0}", err);
-        }
-
-        if (_screenBuffer != nint.Zero)
-        {
-            CloseHandle (_screenBuffer);
-        }
-
-        _screenBuffer = nint.Zero;
-
-        _inputReadyCancellationTokenSource?.Cancel ();
-        _inputReadyCancellationTokenSource?.Dispose ();
-        _inputReadyCancellationTokenSource = null;
-    }
-
-    internal Size GetConsoleBufferWindow (out Point position)
-    {
-        if ((IsVirtualTerminal ? _outputHandle : _screenBuffer) == nint.Zero)
-        {
-            position = Point.Empty;
-
-            return Size.Empty;
-        }
-
-        var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-        csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-
-        if (!GetConsoleScreenBufferInfoEx (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref csbi))
-        {
-            //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-            position = Point.Empty;
-
-            return Size.Empty;
-        }
-
-        Size sz = new (
-                       csbi.srWindow.Right - csbi.srWindow.Left + 1,
-                       csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
-        position = new (csbi.srWindow.Left, csbi.srWindow.Top);
-
-        return sz;
-    }
-
-    internal Size GetConsoleOutputWindow (out Point position)
-    {
-        var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-        csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-
-        if (!GetConsoleScreenBufferInfoEx (_outputHandle, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        Size sz = new (
-                       csbi.srWindow.Right - csbi.srWindow.Left + 1,
-                       csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
-        position = new (csbi.srWindow.Left, csbi.srWindow.Top);
-
-        return sz;
-    }
-
-    internal Size SetConsoleWindow (short cols, short rows)
-    {
-        var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-        csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-
-        if (!GetConsoleScreenBufferInfoEx (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        Coord maxWinSize = GetLargestConsoleWindowSize (IsVirtualTerminal ? _outputHandle : _screenBuffer);
-        short newCols = Math.Min (cols, maxWinSize.X);
-        short newRows = Math.Min (rows, maxWinSize.Y);
-        csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
-        csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
-        csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
-
-        if (!SetConsoleScreenBufferInfoEx (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
-
-        if (!SetConsoleWindowInfo (_outputHandle, true, ref winRect))
-        {
-            //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-            return new (cols, rows);
-        }
-
-        SetConsoleOutputWindow (csbi);
-
-        return new (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
-    }
-
-    internal Size GetLargestConsoleWindowSize ()
-    {
-        Coord maxWinSize = GetLargestConsoleWindowSize (IsVirtualTerminal ? _outputHandle : _screenBuffer);
-
-        return new (maxWinSize.X, maxWinSize.Y);
-    }
-
-    private void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
-    {
-        if ((IsVirtualTerminal
-                ? _outputHandle
-                : _screenBuffer) != nint.Zero && !SetConsoleScreenBufferInfoEx (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-    }
-
-    internal Size SetConsoleOutputWindow (out Point position)
-    {
-        if ((IsVirtualTerminal ? _outputHandle : _screenBuffer) == nint.Zero)
-        {
-            position = Point.Empty;
-
-            return Size.Empty;
-        }
-
-        var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-        csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-
-        if (!GetConsoleScreenBufferInfoEx (IsVirtualTerminal ? _outputHandle : _screenBuffer, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        Size sz = new (
-                           csbi.srWindow.Right - csbi.srWindow.Left + 1,
-                           Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
-        position = new (csbi.srWindow.Left, csbi.srWindow.Top);
-        SetConsoleOutputWindow (csbi);
-        var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
-
-        if (!SetConsoleScreenBufferInfoEx (_outputHandle, ref csbi))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        if (!SetConsoleWindowInfo (_outputHandle, true, ref winRect))
-        {
-            throw new Win32Exception (Marshal.GetLastWin32Error ());
-        }
-
-        return sz;
-    }
-
-    internal bool IsVirtualTerminal { get; init; }
-
-    private uint ConsoleMode
-    {
-        get
-        {
-            GetConsoleMode (_inputHandle, out uint v);
-
-            return v;
-        }
-        set => SetConsoleMode (_inputHandle, value);
-    }
-
+    /// <summary>
+    ///     Windows Console mode flags.
+    /// </summary>
     [Flags]
     public enum ConsoleModes : uint
     {
@@ -724,6 +30,9 @@ public partial class WindowsConsole
         EnableExtendedFlags = 128
     }
 
+    /// <summary>
+    ///     Key event record structure.
+    /// </summary>
     [StructLayout (LayoutKind.Explicit, CharSet = CharSet.Unicode)]
     public struct KeyEventRecord
     {
@@ -811,11 +120,9 @@ public partial class WindowsConsole
         public readonly override string ToString () { return $"[Mouse{MousePosition},{ButtonState},{ControlKeyState},{EventFlags}]"; }
     }
 
-    public struct WindowBufferSizeRecord
+    public struct WindowBufferSizeRecord (short x, short y)
     {
-        public Coord _size;
-
-        public WindowBufferSizeRecord (short x, short y) { _size = new Coord (x, y); }
+        public Coord _size = new (x, y);
 
         public readonly override string ToString () { return $"[WindowBufferSize{_size}"; }
     }
@@ -865,41 +172,17 @@ public partial class WindowsConsole
         public readonly override string ToString ()
         {
             return (EventType switch
-            {
-                EventType.Focus => FocusEvent.ToString (),
-                EventType.Key => KeyEvent.ToString (),
-                EventType.Menu => MenuEvent.ToString (),
-                EventType.Mouse => MouseEvent.ToString (),
-                EventType.WindowBufferSize => WindowBufferSizeEvent.ToString (),
-                _ => "Unknown event type: " + EventType
-            })!;
+                    {
+                        EventType.Focus => FocusEvent.ToString (),
+                        EventType.Key => KeyEvent.ToString (),
+                        EventType.Menu => MenuEvent.ToString (),
+                        EventType.Mouse => MouseEvent.ToString (),
+                        EventType.WindowBufferSize => WindowBufferSizeEvent.ToString (),
+                        _ => "Unknown event type: " + EventType
+                    })!;
         }
     }
 
-    [Flags]
-    private enum ShareMode : uint
-    {
-        FileShareRead = 1,
-        FileShareWrite = 2
-    }
-
-    [Flags]
-    private enum DesiredAccess : uint
-    {
-        GenericRead = 2147483648,
-        GenericWrite = 1073741824
-    }
-
-    [StructLayout (LayoutKind.Sequential)]
-    public struct ConsoleScreenBufferInfo
-    {
-        public Coord dwSize;
-        public Coord dwCursorPosition;
-        public ushort wAttributes;
-        public SmallRect srWindow;
-        public Coord dwMaximumWindowSize;
-    }
-
     [StructLayout (LayoutKind.Sequential)]
     public struct Coord
     {
@@ -935,20 +218,6 @@ public partial class WindowsConsole
         public ushort Attributes;
     }
 
-    public struct ExtendedCharInfo
-    {
-        public char [] Char { get; set; }
-        public Attribute Attribute { get; set; }
-        public bool Empty { get; set; } // TODO: Temp hack until virtual terminal sequences
-
-        public ExtendedCharInfo (char [] character, Attribute attribute)
-        {
-            Char = character;
-            Attribute = attribute;
-            Empty = false;
-        }
-    }
-
     [StructLayout (LayoutKind.Sequential)]
     public struct SmallRect
     {
@@ -1045,147 +314,19 @@ public partial class WindowsConsole
         }
     }
 
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern nint GetStdHandle (int nStdHandle);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool CloseHandle (nint handle);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    public static extern bool PeekConsoleInput (nint hConsoleInput, out InputRecord lpBuffer, uint nLength, out uint lpNumberOfEventsRead);
-
-    [DllImport ("kernel32.dll", EntryPoint = "ReadConsoleInputW", CharSet = CharSet.Unicode)]
-    public static extern bool ReadConsoleInput (
-        nint hConsoleInput,
-        out InputRecord lpBuffer,
-        uint nLength,
-        out uint lpNumberOfEventsRead
-    );
-
-    [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
-    private static extern bool ReadConsoleOutput (
-        nint hConsoleOutput,
-        [Out] CharInfo [] lpBuffer,
-        Coord dwBufferSize,
-        Coord dwBufferCoord,
-        ref SmallRect lpReadRegion
-    );
-
-    // TODO: This API is obsolete. See https://learn.microsoft.com/en-us/windows/console/writeconsoleoutput
-    [DllImport ("kernel32.dll", EntryPoint = "WriteConsoleOutputW", SetLastError = true, CharSet = CharSet.Unicode)]
-    public static extern bool WriteConsoleOutput (
-        nint hConsoleOutput,
-        CharInfo [] lpBuffer,
-        Coord dwBufferSize,
-        Coord dwBufferCoord,
-        ref SmallRect lpWriteRegion
-    );
-
-    [LibraryImport ("kernel32.dll", EntryPoint = "WriteConsoleW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
-    [return: MarshalAs (UnmanagedType.Bool)]
-    private static partial bool WriteConsole (
-        nint hConsoleOutput,
-        ReadOnlySpan<char> lpbufer,
-        uint NumberOfCharsToWriten,
-        out uint lpNumberOfCharsWritten,
-        nint lpReserved
-    );
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool SetConsoleTextAttribute (
-        nint hConsoleOutput,
-        ushort wAttributes
-    );
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool FlushFileBuffers (nint hFile);
-
-    [DllImport ("kernel32.dll")]
-    private static extern bool SetConsoleCursorPosition (nint hConsoleOutput, Coord dwCursorPosition);
-
     [StructLayout (LayoutKind.Sequential)]
     public struct ConsoleCursorInfo
     {
         /// <summary>
-        /// The percentage of the character cell that is filled by the cursor.This value is between 1 and 100.
-        /// The cursor appearance varies, ranging from completely filling the cell to showing up as a horizontal
-        /// line at the bottom of the cell.
+        ///     The percentage of the character cell that is filled by the cursor.This value is between 1 and 100.
+        ///     The cursor appearance varies, ranging from completely filling the cell to showing up as a horizontal
+        ///     line at the bottom of the cell.
         /// </summary>
         public uint dwSize;
-        public bool bVisible;
-    }
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool SetConsoleCursorInfo (nint hConsoleOutput, [In] ref ConsoleCursorInfo lpConsoleCursorInfo);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool GetConsoleCursorInfo (nint hConsoleOutput, out ConsoleCursorInfo lpConsoleCursorInfo);
-
-    [DllImport ("kernel32.dll")]
-    private static extern bool GetConsoleMode (nint hConsoleHandle, out uint lpMode);
-
-    [DllImport ("kernel32.dll")]
-    private static extern bool SetConsoleMode (nint hConsoleHandle, uint dwMode);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern nint CreateConsoleScreenBuffer (
-        DesiredAccess dwDesiredAccess,
-        ShareMode dwShareMode,
-        nint secutiryAttributes,
-        uint flags,
-        nint screenBufferData
-    );
-
-    internal static nint INVALID_HANDLE_VALUE = new (-1);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool SetConsoleActiveScreenBuffer (nint handle);
 
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool GetNumberOfConsoleInputEvents (nint handle, out uint lpcNumberOfEvents);
-
-    internal uint GetNumberOfConsoleInputEvents ()
-    {
-        if (!GetNumberOfConsoleInputEvents (_inputHandle, out uint numOfEvents))
-        {
-            Console.WriteLine ($"Error: {Marshal.GetLastWin32Error ()}");
-
-            return 0;
-        }
-
-        return numOfEvents;
-    }
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool FlushConsoleInputBuffer (nint handle);
-
-    internal void FlushConsoleInputBuffer ()
-    {
-        if (!FlushConsoleInputBuffer (_inputHandle))
-        {
-            Console.WriteLine ($"Error: {Marshal.GetLastWin32Error ()}");
-        }
+        public bool bVisible;
     }
 
-#if false // Not needed on the constructor. Perhaps could be used on resizing. To study.
-		[DllImport ("kernel32.dll", ExactSpelling = true)]
-		static extern IntPtr GetConsoleWindow ();
-
-		[DllImport ("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
-		static extern bool ShowWindow (IntPtr hWnd, int nCmdShow);
-
-		public const int HIDE = 0;
-		public const int MAXIMIZE = 3;
-		public const int MINIMIZE = 6;
-		public const int RESTORE = 9;
-
-		internal void ShowWindow (int state)
-		{
-			IntPtr thisConsole = GetConsoleWindow ();
-			ShowWindow (thisConsole, state);
-		}
-#endif
-
     // See: https://github.com/gui-cs/Terminal.Gui/issues/357
 
     [StructLayout (LayoutKind.Sequential)]
@@ -1235,22 +376,4 @@ public partial class WindowsConsole
         [FieldOffset (0)]
         public uint Value;
     }
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool GetConsoleScreenBufferInfoEx (nint hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX csbi);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool SetConsoleScreenBufferInfoEx (nint hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX consoleScreenBufferInfo);
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern bool SetConsoleWindowInfo (
-        nint hConsoleOutput,
-        bool bAbsolute,
-        [In] ref SmallRect lpConsoleWindow
-    );
-
-    [DllImport ("kernel32.dll", SetLastError = true)]
-    private static extern Coord GetLargestConsoleWindowSize (
-        nint hConsoleOutput
-    );
 }

+ 9 - 8
Terminal.Gui/Drivers/WindowsDriver/WindowsInput.cs

@@ -1,4 +1,5 @@
-using System.Runtime.InteropServices;
+#nullable enable
+using System.Runtime.InteropServices;
 using Microsoft.Extensions.Logging;
 using static Terminal.Gui.Drivers.WindowsConsole;
 
@@ -66,13 +67,13 @@ internal class WindowsInput : ConsoleInput<InputRecord>, IWindowsInput
             return false;
         }
 
-        const int bufferSize = 1; // We only need to check if there's at least one event
-        nint pRecord = Marshal.AllocHGlobal (Marshal.SizeOf<InputRecord> () * bufferSize);
+        const int BUFFER_SIZE = 1; // We only need to check if there's at least one event
+        nint pRecord = Marshal.AllocHGlobal (Marshal.SizeOf<InputRecord> () * BUFFER_SIZE);
 
         try
         {
             // Use PeekConsoleInput to inspect the input buffer without removing events
-            if (PeekConsoleInput (_inputHandle, pRecord, bufferSize, out uint numberOfEventsRead))
+            if (PeekConsoleInput (_inputHandle, pRecord, BUFFER_SIZE, out uint numberOfEventsRead))
             {
                 // Return true if there's at least one event in the buffer
                 return numberOfEventsRead > 0;
@@ -86,7 +87,7 @@ internal class WindowsInput : ConsoleInput<InputRecord>, IWindowsInput
         catch (Exception ex)
         {
             // Optionally log the exception
-            Console.WriteLine ($"Error in Peek: {ex.Message}");
+            Console.WriteLine (@$"Error in Peek: {ex.Message}");
 
             return false;
         }
@@ -99,15 +100,15 @@ internal class WindowsInput : ConsoleInput<InputRecord>, IWindowsInput
 
     protected override IEnumerable<InputRecord> Read ()
     {
-        const int bufferSize = 1;
-        nint pRecord = Marshal.AllocHGlobal (Marshal.SizeOf<InputRecord> () * bufferSize);
+        const int BUFFER_SIZE = 1;
+        nint pRecord = Marshal.AllocHGlobal (Marshal.SizeOf<InputRecord> () * BUFFER_SIZE);
 
         try
         {
             ReadConsoleInput (
                               _inputHandle,
                               pRecord,
-                              bufferSize,
+                              BUFFER_SIZE,
                               out uint numberEventsRead);
 
             return numberEventsRead == 0

+ 7 - 1
Terminal.Gui/Drivers/WindowsDriver/WindowsOutput.cs

@@ -356,7 +356,7 @@ internal partial class WindowsOutput : OutputBase, IConsoleOutput
     private Size? _lastWindowSizeBeforeMaximized;
     private bool _lockResize;
 
-    public Size GetWindowSize ()
+    public Size GetSize ()
     {
         if (_lockResize)
         {
@@ -497,6 +497,12 @@ internal partial class WindowsOutput : OutputBase, IConsoleOutput
         }
     }
 
+    /// <inheritdoc />
+    public void SetSize (int width, int height)
+    {
+        // Do Nothing.
+    }
+
     private bool _isDisposed;
     private bool _force16Colors;
     private nint _consoleBuffer;

+ 6 - 6
Terminal.Gui/ViewBase/Adornment/Border.Arrangment.cs

@@ -688,7 +688,7 @@ public partial class Border
                 break;
 
             case ViewArrangement.BottomResizable:
-                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin.Thickness.Bottom + 1);
+                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin!.Thickness.Bottom + 1);
                 break;
 
             case ViewArrangement.LeftResizable:
@@ -705,12 +705,12 @@ public partial class Border
                 break;
 
             case ViewArrangement.RightResizable:
-                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin.Thickness.Right + 1);
+                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin!.Thickness.Right + 1);
                 break;
 
             case ViewArrangement.BottomResizable | ViewArrangement.RightResizable:
-                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin.Thickness.Right + 1);
-                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin.Thickness.Bottom + 1);
+                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin!.Thickness.Right + 1);
+                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin!.Thickness.Bottom + 1);
                 break;
 
             case ViewArrangement.BottomResizable | ViewArrangement.LeftResizable:
@@ -723,7 +723,7 @@ public partial class Border
                     Parent.X = parentLoc.X - _startGrabPoint.X;
                 }
 
-                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin.Thickness.Bottom + 1);
+                Parent.Height = Math.Max (minHeight, parentLoc.Y - Parent.Frame.Y + Parent!.Margin!.Thickness.Bottom + 1);
                 break;
 
             case ViewArrangement.TopResizable | ViewArrangement.RightResizable:
@@ -736,7 +736,7 @@ public partial class Border
                     Parent.Y = parentLoc.Y - _startGrabPoint.Y;
                 }
 
-                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin.Thickness.Right + 1);
+                Parent.Width = Math.Max (minWidth, parentLoc.X - Parent.Frame.X + Parent!.Margin!.Thickness.Right + 1);
                 break;
 
             case ViewArrangement.TopResizable | ViewArrangement.LeftResizable:

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

@@ -152,7 +152,7 @@ public partial class Border : Adornment
 #if SUBVIEW_BASED_BORDER
     private void OnLayoutStarted (object sender, LayoutEventArgs e)
     {
-        _left.Border.LineStyle = LineStyle;
+        _left.Border!.LineStyle = LineStyle;
 
         _left.X = Thickness.Left - 1;
         _left.Y = Thickness.Top - 1;

+ 7 - 7
Terminal.Gui/ViewBase/Adornment/Margin.cs

@@ -79,12 +79,12 @@ public class Margin : Adornment
 
             if (view.Margin?.GetCachedClip () != null)
             {
-                view.Margin.NeedsDraw = true;
+                view.Margin!.NeedsDraw = true;
                 Region? saved = GetClip ();
-                View.SetClip (view.Margin.GetCachedClip ());
-                view.Margin.Draw ();
+                View.SetClip (view.Margin!.GetCachedClip ());
+                view.Margin!.Draw ();
                 View.SetClip (saved);
-                view.Margin.ClearCachedClip ();
+                view.Margin!.ClearCachedClip ();
             }
 
             view.NeedsDraw = false;
@@ -292,14 +292,14 @@ public class Margin : Adornment
             {
                 case ShadowStyle.Transparent:
                     // BUGBUG: This doesn't work right for all Border.Top sizes - Need an API on Border that gives top-right location of line corner.
-                    _rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
+                    _rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border!.GetBorderRectangle ().Location).Y + 1 : 0;
 
                     break;
 
                 case ShadowStyle.Opaque:
                     // BUGBUG: This doesn't work right for all Border.Top sizes - Need an API on Border that gives top-right location of line corner.
-                    _rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
-                    _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).X + 1 : 0;
+                    _rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border!.GetBorderRectangle ().Location).Y + 1 : 0;
+                    _bottomShadow.X = Parent.Border!.Thickness.Left > 0 ? ScreenToViewport (Parent.Border!.GetBorderRectangle ().Location).X + 1 : 0;
 
                     break;
 

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

@@ -95,7 +95,7 @@ internal class ShadowView : View
         {
             for (int c = Math.Max (0, screen.X + 1); c < screen.X + screen.Width; c++)
             {
-                Driver.Move (c, r);
+                Driver?.Move (c, r);
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
 
                 if (c < ScreenContents?.GetLength (1) && r < ScreenContents?.GetLength (0))
@@ -129,7 +129,7 @@ internal class ShadowView : View
         {
             for (int r = Math.Max (0, screen.Y); r < screen.Y + viewport.Height; r++)
             {
-                Driver.Move (c, r);
+                Driver?.Move (c, r);
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
 
                 if (ScreenContents is { } && screen.X < ScreenContents.GetLength (1) && r < ScreenContents.GetLength (0))

+ 1 - 1
Terminal.Gui/ViewBase/Layout/DimAuto.cs

@@ -35,7 +35,7 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt
         int screenX4 = dimension == Dimension.Width ? Application.Screen.Width * 4 : Application.Screen.Height * 4;
         int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? screenX4;
 
-        Debug.WriteLineIf (autoMin > autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
+        //Debug.WriteLineIf (autoMin > autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
 
         if (Style.FastHasFlags (DimAutoStyle.Text))
         {

+ 8 - 8
Terminal.Gui/ViewBase/View.Layout.cs

@@ -37,7 +37,7 @@ public partial class View // Layout APIs
     ///     <para>
     ///         Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
     ///         resulting in the
-    ///         view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
+    ///         view being laid out and redrawn as appropriate in the next iteration.
     ///     </para>
     /// </remarks>
     public Rectangle Frame
@@ -219,7 +219,7 @@ public partial class View // Layout APIs
     ///     <para>
     ///         Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
     ///         resulting in the
-    ///         view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
+    ///         view being laid out and redrawn as appropriate in the next iteration.
     ///     </para>
     ///     <para>
     ///         Changing this property will cause <see cref="Frame"/> to be updated.
@@ -264,7 +264,7 @@ public partial class View // Layout APIs
     ///     <para>
     ///         Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
     ///         resulting in the
-    ///         view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
+    ///         view being laid out and redrawn as appropriate in the next iteration.
     ///     </para>
     ///     <para>
     ///         Changing this property will cause <see cref="Frame"/> to be updated.
@@ -308,7 +308,7 @@ public partial class View // Layout APIs
     ///     <para>
     ///         Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
     ///         resulting in the
-    ///         view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
+    ///         view being laid out and redrawn as appropriate in the next iteration.
     ///     </para>
     ///     <para>
     ///         Changing this property will cause <see cref="Frame"/> to be updated.
@@ -396,7 +396,7 @@ public partial class View // Layout APIs
     ///     <para>
     ///         Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
     ///         resulting in the
-    ///         view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
+    ///         view being laid out and redrawn as appropriate in the next iteration.
     ///     </para>
     ///     <para>
     ///         Changing this property will cause <see cref="Frame"/> to be updated.
@@ -843,7 +843,7 @@ public partial class View // Layout APIs
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         The <see cref="MainLoop"/> will cause <see cref="Layout()"/> to be called on the next
+    ///         The next iteration will cause <see cref="Layout()"/> to be called on the next
     ///         <see cref="Application.Iteration"/> so there is normally no reason to call see <see cref="Layout()"/>.
     ///     </para>
     /// </remarks>
@@ -882,12 +882,12 @@ public partial class View // Layout APIs
 
                 if (current.Margin is { SubViews.Count: > 0 })
                 {
-                    current.Margin.SetNeedsLayout ();
+                    current.Margin!.SetNeedsLayout ();
                 }
 
                 if (current.Border is { SubViews.Count: > 0 })
                 {
-                    current.Border.SetNeedsLayout ();
+                    current.Border!.SetNeedsLayout ();
                 }
 
                 if (current.Padding is { SubViews.Count: > 0 })

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

@@ -1441,8 +1441,8 @@ public class MenuBar : View, IDesignable
 
             if (SuperView is { })
             {
-                locationOffset.X += SuperView.Border.Thickness.Left;
-                locationOffset.Y += SuperView.Border.Thickness.Top;
+                locationOffset.X += SuperView.Border!.Thickness.Left;
+                locationOffset.Y += SuperView.Border!.Thickness.Top;
             }
 
             int cx = me.Position.X - locationOffset.X;

+ 9 - 9
Terminal.Gui/Views/Shortcut.cs

@@ -210,14 +210,14 @@ public class Shortcut : View, IOrientation, IDesignable
                 case 0:
                 case 1:
                     // Scrunch it by removing both margins
-                    HelpView.Margin.Thickness = new (t.Right - 1, t.Top, t.Left - 1, t.Bottom);
+                    HelpView.Margin!.Thickness = new (t.Right - 1, t.Top, t.Left - 1, t.Bottom);
 
                     break;
 
                 case 2:
 
                     // Scrunch just the right margin
-                    HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom);
+                    HelpView.Margin!.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom);
 
                     break;
             }
@@ -225,7 +225,7 @@ public class Shortcut : View, IOrientation, IDesignable
         else
         {
             // Reset to default
-            HelpView.Margin.Thickness = GetMarginThickness ();
+            HelpView.Margin!.Thickness = GetMarginThickness ();
         }
     }
 
@@ -471,9 +471,9 @@ public class Shortcut : View, IOrientation, IDesignable
     {
         if (CommandView.Margin is { })
         {
-            CommandView.Margin.Thickness = GetMarginThickness ();
+            CommandView.Margin!.Thickness = GetMarginThickness ();
             // strip off ViewportSettings.TransparentMouse
-            CommandView.Margin.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
+            CommandView.Margin!.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
         }
 
         CommandView.X = Pos.Align (Alignment.End, AlignmentModes);
@@ -533,9 +533,9 @@ public class Shortcut : View, IOrientation, IDesignable
     {
         if (HelpView.Margin is { })
         {
-            HelpView.Margin.Thickness = GetMarginThickness ();
+            HelpView.Margin!.Thickness = GetMarginThickness ();
             // strip off ViewportSettings.TransparentMouse
-            HelpView.Margin.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
+            HelpView.Margin!.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
         }
 
         HelpView.X = Pos.Align (Alignment.End, AlignmentModes);
@@ -666,9 +666,9 @@ public class Shortcut : View, IOrientation, IDesignable
     {
         if (KeyView.Margin is { })
         {
-            KeyView.Margin.Thickness = GetMarginThickness ();
+            KeyView.Margin!.Thickness = GetMarginThickness ();
             // strip off ViewportSettings.TransparentMouse
-            KeyView.Margin.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
+            KeyView.Margin!.ViewportSettings &= ~ViewportSettingsFlags.TransparentMouse;
         }
 
         KeyView.X = Pos.Align (Alignment.End, AlignmentModes);

+ 1 - 1
Terminal.Gui/Views/StatusBar.cs

@@ -71,7 +71,7 @@ public class StatusBar : Bar, IDesignable
 
             if (barItem.Border is { })
             {
-                barItem.Border.Thickness = index == SubViews.Count - 1 ? new Thickness (0, 0, 0, 0) : new Thickness (0, 0, 1, 0);
+                barItem.Border!.Thickness = index == SubViews.Count - 1 ? new Thickness (0, 0, 0, 0) : new Thickness (0, 0, 1, 0);
             }
 
             if (barItem is Shortcut shortcut)

+ 1 - 1
Terminal.Gui/Views/TextInput/NetMaskedTextProvider.cs

@@ -61,7 +61,7 @@ public class NetMaskedTextProvider : ITextValidateProvider
     public bool Fixed => true;
 
     /// <inheritdoc/>
-    public string DisplayText => _provider.ToDisplayString ();
+    public string DisplayText => _provider!.ToDisplayString ();
 
     /// <inheritdoc/>
     public int Cursor (int pos)

+ 0 - 1
Terminal.Gui/Views/TreeView/Branch.cs

@@ -451,7 +451,6 @@ internal class Branch<T> where T : class
     ///     Returns true if the given x offset on the branch line is the +/- symbol.  Returns false if not showing
     ///     expansion symbols or leaf node etc.
     /// </summary>
-    /// <param name="driver"></param>
     /// <param name="x"></param>
     /// <returns></returns>
     internal bool IsHitOnExpandableSymbol (int x)

+ 4 - 4
Tests/TerminalGuiFluentTesting/FakeDriver/FakeApplicationFactory.cs

@@ -16,11 +16,11 @@ public class FakeApplicationFactory
         var cts = new CancellationTokenSource ();
         var fakeInput = new FakeNetInput (cts.Token);
         FakeOutput output = new ();
-        output.Size = new (25, 25);
+        output.Size = new (80, 25);
 
         IApplication origApp = ApplicationImpl.Instance;
 
-        var sizeMonitor = new FakeSizeMonitor ();
+        var sizeMonitor = new FakeSizeMonitor (output, output.LastBuffer!);
 
         var impl = new ApplicationImpl (new FakeNetComponentFactory (fakeInput, output, sizeMonitor));
 
@@ -32,13 +32,13 @@ public class FakeApplicationFactory
         // Handle different facade types - cast to common interface instead
         var d = (IConsoleDriverFacade)Application.Driver!;
 
-        sizeMonitor.SizeChanging += (_, e) =>
+        sizeMonitor.SizeChanged += (_, e) =>
                                     {
                                         if (e.Size != null)
                                         {
                                             Size s = e.Size.Value;
                                             output.Size = s;
-                                            d.OutputBuffer.SetWindowSize (s.Width, s.Height);
+                                            d.OutputBuffer.SetSize (s.Width, s.Height);
                                         }
                                     };
 

+ 0 - 58
Tests/TerminalGuiFluentTesting/FakeDriver/FakeConsoleDriver.cs

@@ -1,58 +0,0 @@
-#nullable enable
-using System.Collections.Concurrent;
-using System.Drawing;
-using TerminalGuiFluentTesting;
-
-#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
-
-namespace Terminal.Gui.Drivers;
-
-/// <summary>
-///     Implementation of <see cref="IConsoleDriver"/> that uses fake input/output.
-///     This is a lightweight alternative to <see cref="GuiTestContext"/> (if you don't
-///     need the entire application main loop running).
-/// </summary>
-internal class FakeConsoleDriver : ConsoleDriverFacade<ConsoleKeyInfo>, IFakeConsoleDriver
-{
-    internal FakeConsoleDriver (
-        ConcurrentQueue<ConsoleKeyInfo> inputBuffer,
-        OutputBuffer outputBuffer,
-        FakeOutput fakeOutput,
-        Func<DateTime> datetimeFunc,
-        FakeSizeMonitor sizeMonitor
-    ) :
-        base (
-              new NetInputProcessor (inputBuffer),
-              outputBuffer,
-              fakeOutput,
-              new (new AnsiResponseParser (), datetimeFunc),
-              sizeMonitor)
-    {
-        FakeOutput fakeOutput1;
-        InputBuffer = inputBuffer;
-        SizeMonitor = sizeMonitor;
-        OutputBuffer = outputBuffer;
-        ConsoleOutput = fakeOutput1 = fakeOutput;
-
-        SizeChanged += (_, e) =>
-                       {
-                           if (e.Size != null)
-                           {
-                               Size s = e.Size.Value;
-                               fakeOutput1.Size = s;
-                               OutputBuffer.SetWindowSize (s.Width, s.Height);
-                           }
-                       };
-    }
-
-    public void SetBufferSize (int width, int height)
-    {
-        SizeMonitor.RaiseSizeChanging (new (width, height));
-        OutputBuffer.SetWindowSize (width, height);
-    }
-
-    public IConsoleOutput ConsoleOutput { get; }
-    public ConcurrentQueue<ConsoleKeyInfo> InputBuffer { get; }
-    public new OutputBuffer OutputBuffer { get; }
-    public FakeSizeMonitor SizeMonitor { get; }
-}

+ 0 - 20
Tests/TerminalGuiFluentTesting/FakeDriver/FakeDriverFactory.cs

@@ -1,20 +0,0 @@
-#nullable enable
-namespace Terminal.Gui.Drivers;
-
-#pragma warning disable CS1591
-public class FakeDriverFactory
-{
-    /// <summary>
-    ///     Creates a new instance of <see cref="FakeConsoleDriver"/> using default options
-    /// </summary>
-    /// <returns></returns>
-    public IFakeConsoleDriver Create ()
-    {
-        return new FakeConsoleDriver (
-                                 new (),
-                                 new (),
-                                 new (),
-                                 () => DateTime.Now,
-                                 new ());
-    }
-}

+ 0 - 0
Tests/TerminalGuiFluentTesting/FakeInput.cs → Tests/TerminalGuiFluentTesting/FakeDriver/FakeInput.cs


+ 7 - 1
Tests/TerminalGuiFluentTesting/FakeOutput.cs → Tests/TerminalGuiFluentTesting/FakeDriver/FakeOutput.cs

@@ -17,7 +17,7 @@ internal class FakeOutput : IConsoleOutput
     public void Write (IOutputBuffer buffer) { LastBuffer = buffer; }
 
     /// <inheritdoc/>
-    public Size GetWindowSize () { return Size; }
+    public Size GetSize () { return Size; }
 
     /// <inheritdoc/>
     public void SetCursorVisibility (CursorVisibility visibility) { }
@@ -25,6 +25,12 @@ internal class FakeOutput : IConsoleOutput
     /// <inheritdoc/>
     public void SetCursorPosition (int col, int row) { CursorPosition = new Point (col, row); }
 
+    /// <inheritdoc />
+    public void SetSize (int width, int height)
+    {
+        Size = new (width, height);
+    }
+
     /// <summary>
     /// The last value set by calling <see cref="SetCursorPosition"/>
     /// </summary>

+ 6 - 6
Tests/TerminalGuiFluentTesting/FakeDriver/FakeSizeMonitor.cs

@@ -4,17 +4,17 @@ using System.Drawing;
 namespace Terminal.Gui.Drivers;
 
 #pragma warning disable CS1591
-public class FakeSizeMonitor : IWindowSizeMonitor
+public class FakeSizeMonitor (IConsoleOutput consoleOut, IOutputBuffer _) : IConsoleSizeMonitor
 {
-    /// <inheritdoc/>
-    public event EventHandler<SizeChangedEventArgs>? SizeChanging;
+    /// <inheritdoc />
+    public event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     /// <inheritdoc/>
     public bool Poll () { return false; }
 
     /// <summary>
-    ///     Raises the <see cref="SizeChanging"/> event.
+    ///     Raises the <see cref="SizeChanged"/> event.
     /// </summary>
     /// <param name="newSize"></param>
-    public void RaiseSizeChanging (Size newSize) { SizeChanging?.Invoke (this, new (newSize)); }
-}
+    public void RaiseSizeChanged (Size newSize) { SizeChanged?.Invoke (this, new (newSize)); }
+}

+ 0 - 0
Tests/TerminalGuiFluentTesting/FakeWindowsInput.cs → Tests/TerminalGuiFluentTesting/FakeDriver/FakeWindowsInput.cs


+ 0 - 8
Tests/TerminalGuiFluentTesting/FakeDriver/IFakeConsoleDriver.cs

@@ -1,8 +0,0 @@
-#nullable enable
-namespace Terminal.Gui.Drivers;
-
-#pragma warning disable CS1591
-public interface IFakeConsoleDriver : IConsoleDriver, IConsoleDriverFacade
-{
-    void SetBufferSize (int width, int height);
-}

+ 19 - 36
Tests/TerminalGuiFluentTesting/GuiTestContext.cs

@@ -43,7 +43,7 @@ public class GuiTestContext : IDisposable
         _winInput = new (_cts.Token);
 
         _output.Size = new (width, height);
-        _fakeSizeMonitor = new ();
+        _fakeSizeMonitor = new (_output, _output.LastBuffer!);
 
         IComponentFactory cf = driver == TestDriver.DotNet
                                    ? new FakeNetComponentFactory (_netInput, _output, _fakeSizeMonitor)
@@ -238,11 +238,7 @@ public class GuiTestContext : IDisposable
         return WaitIteration (
                               () =>
                               {
-                                  _output.Size = new (width, height);
-                                  _fakeSizeMonitor.RaiseSizeChanging (_output.Size);
-
-                                  var d = (IConsoleDriverFacade)Application.Driver!;
-                                  d.OutputBuffer.SetWindowSize (width, height);
+                                  Application.Driver!.SetScreenSize(width, height);
                               });
     }
 
@@ -938,48 +934,35 @@ public class GuiTestContext : IDisposable
     public Point GetCursorPosition () { return _output.CursorPosition; }
 }
 
-internal class FakeWindowsComponentFactory : WindowsComponentFactory
+internal class FakeWindowsComponentFactory (FakeWindowsInput winInput, FakeOutput output, FakeSizeMonitor fakeSizeMonitor)
+    : WindowsComponentFactory
 {
-    private readonly FakeWindowsInput _winInput;
-    private readonly FakeOutput _output;
-    private readonly FakeSizeMonitor _fakeSizeMonitor;
-
-    public FakeWindowsComponentFactory (FakeWindowsInput winInput, FakeOutput output, FakeSizeMonitor fakeSizeMonitor)
-    {
-        _winInput = winInput;
-        _output = output;
-        _fakeSizeMonitor = fakeSizeMonitor;
-    }
-
     /// <inheritdoc/>
-    public override IConsoleInput<WindowsConsole.InputRecord> CreateInput () { return _winInput; }
+    public override IConsoleInput<WindowsConsole.InputRecord> CreateInput () { return winInput; }
 
     /// <inheritdoc/>
-    public override IConsoleOutput CreateOutput () { return _output; }
+    public override IConsoleOutput CreateOutput () { return output; }
 
     /// <inheritdoc/>
-    public override IWindowSizeMonitor CreateWindowSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer) { return _fakeSizeMonitor; }
-}
-
-internal class FakeNetComponentFactory : NetComponentFactory
-{
-    private readonly FakeNetInput _netInput;
-    private readonly FakeOutput _output;
-    private readonly FakeSizeMonitor _fakeSizeMonitor;
-
-    public FakeNetComponentFactory (FakeNetInput netInput, FakeOutput output, FakeSizeMonitor fakeSizeMonitor)
+    public override IConsoleSizeMonitor CreateConsoleSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
     {
-        _netInput = netInput;
-        _output = output;
-        _fakeSizeMonitor = fakeSizeMonitor;
+        outputBuffer.SetSize (consoleOutput.GetSize ().Width, consoleOutput.GetSize ().Height);
+        return fakeSizeMonitor;
     }
+}
 
+internal class FakeNetComponentFactory (FakeNetInput netInput, FakeOutput output, FakeSizeMonitor fakeSizeMonitor) : NetComponentFactory
+{
     /// <inheritdoc/>
-    public override IConsoleInput<ConsoleKeyInfo> CreateInput () { return _netInput; }
+    public override IConsoleInput<ConsoleKeyInfo> CreateInput () { return netInput; }
 
     /// <inheritdoc/>
-    public override IConsoleOutput CreateOutput () { return _output; }
+    public override IConsoleOutput CreateOutput () { return output; }
 
     /// <inheritdoc/>
-    public override IWindowSizeMonitor CreateWindowSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer) { return _fakeSizeMonitor; }
+    public override IConsoleSizeMonitor CreateConsoleSizeMonitor (IConsoleOutput consoleOutput, IOutputBuffer outputBuffer)
+    {
+        outputBuffer.SetSize (consoleOutput.GetSize ().Width, consoleOutput.GetSize ().Height);
+        return fakeSizeMonitor;
+    }
 }

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

@@ -1,7 +1,7 @@
 using UnitTests;
 using Xunit.Abstractions;
 
-namespace UnitTests.ApplicationTests.NavigationTests;
+namespace UnitTests.ApplicationTests;
 
 public class ApplicationNavigationTests (ITestOutputHelper output)
 {

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

@@ -25,7 +25,7 @@ public class ApplicationImplTests
             m.Setup (f => f.CreateInput ()).Returns (netInput.Object);
             m.Setup (f => f.CreateInputProcessor (It.IsAny<ConcurrentQueue<ConsoleKeyInfo>> ())).Returns (Mock.Of <IInputProcessor> ());
             m.Setup (f => f.CreateOutput ()).Returns (Mock.Of<IConsoleOutput> ());
-            m.Setup (f => f.CreateWindowSizeMonitor (It.IsAny<IConsoleOutput> (),It.IsAny<IOutputBuffer> ())).Returns (Mock.Of<IWindowSizeMonitor> ());
+            m.Setup (f => f.CreateConsoleSizeMonitor (It.IsAny<IConsoleOutput> (),It.IsAny<IOutputBuffer> ())).Returns (Mock.Of<IConsoleSizeMonitor> ());
 
             return new (m.Object);
         }
@@ -38,7 +38,7 @@ public class ApplicationImplTests
             m.Setup (f => f.CreateInput ()).Returns (winInput.Object);
             m.Setup (f => f.CreateInputProcessor (It.IsAny<ConcurrentQueue<WindowsConsole.InputRecord>> ())).Returns (Mock.Of<IInputProcessor> ());
             m.Setup (f => f.CreateOutput ()).Returns (Mock.Of<IConsoleOutput> ());
-            m.Setup (f => f.CreateWindowSizeMonitor (It.IsAny<IConsoleOutput> (), It.IsAny<IOutputBuffer> ())).Returns (Mock.Of<IWindowSizeMonitor> ());
+            m.Setup (f => f.CreateConsoleSizeMonitor (It.IsAny<IConsoleOutput> (), It.IsAny<IOutputBuffer> ())).Returns (Mock.Of<IConsoleSizeMonitor> ());
             return new (m.Object);
         }
     }

+ 3 - 2
Tests/UnitTests/Application/ApplicationPopoverTests.cs

@@ -1,4 +1,5 @@
-namespace UnitTests.ApplicationTests;
+#nullable enable
+namespace UnitTests.ApplicationTests;
 
 public class ApplicationPopoverTests
 {
@@ -276,7 +277,7 @@ public class ApplicationPopoverTests
         public PopoverTestClass ()
         {
             CanFocus = true;
-            AddCommand (Command.New, NewCommandHandler);
+            AddCommand (Command.New, NewCommandHandler!);
             HotKeyBindings.Add (Key.N.WithCtrl, Command.New);
 
             return;

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

@@ -89,7 +89,7 @@ public class ApplicationScreenTests
     }
 
     [Fact]
-    public void Screen_Changes_OnSizeChanged_Without_Call_Application_Init ()
+    public void Screen_Changes_OnScreenChanged_Without_Call_Application_Init ()
     {
         // Arrange
         Application.ResetState (true);
@@ -99,7 +99,7 @@ public class ApplicationScreenTests
         Assert.Equal (new (0, 0, 25, 25), Application.Screen);
 
         // Act
-        ((FakeDriver)Application.Driver)!.SetBufferSize (120, 30);
+        Application.Driver.SetScreenSize(120,30);
 
         // Assert
         Assert.Equal (new (0, 0, 120, 30), Application.Screen);

+ 31 - 44
Tests/UnitTests/Application/ApplicationTests.cs

@@ -1,8 +1,4 @@
 using System.Diagnostics;
-using System.Reflection;
-using JetBrains.Annotations;
-using Terminal.Gui.Drivers;
-using UnitTests;
 using Xunit.Abstractions;
 using static Terminal.Gui.Configuration.ConfigurationManager;
 
@@ -81,8 +77,8 @@ public class ApplicationTests
             _timeoutLock = null;
         }
 
-
         a.After (null);
+
         return;
 
         void OnApplicationOnInitializedChanged (object s, EventArgs<bool> a)
@@ -167,11 +163,11 @@ public class ApplicationTests
     public void Begin_Sets_Application_Top_To_Console_Size ()
     {
         Assert.Null (Application.Top);
-        AutoInitShutdownAttribute.FakeResize (new Size (80, 25));
+        Application.Driver!.SetScreenSize (80, 25);
         Toplevel top = new ();
         Application.Begin (top);
         Assert.Equal (new (0, 0, 80, 25), Application.Top!.Frame);
-        AutoInitShutdownAttribute.FakeResize (new Size (5, 5));
+        Application.Driver!.SetScreenSize (5, 5);
         Assert.Equal (new (0, 0, 5, 5), Application.Top!.Frame);
         top.Dispose ();
     }
@@ -212,7 +208,7 @@ public class ApplicationTests
     public void Init_Begin_End_Cleans_Up ()
     {
         // Start stopwatch
-        Stopwatch stopwatch = new Stopwatch ();
+        var stopwatch = new Stopwatch ();
         stopwatch.Start ();
 
         // Begin will cause Run() to be called, which will call Begin(). Thus will block the tests
@@ -252,7 +248,6 @@ public class ApplicationTests
         stopwatch.Stop ();
 
         _output.WriteLine ($"Load took {stopwatch.ElapsedMilliseconds} ms");
-
     }
 
     // Legacy driver test - all InlineData commented out
@@ -284,6 +279,7 @@ public class ApplicationTests
 
     [Theory]
     [InlineData (typeof (FakeDriver))]
+
     //[InlineData (typeof (DotNetDriver))]
     //[InlineData (typeof (WindowsDriver))]
     //[InlineData (typeof (UnixDriver))]
@@ -422,6 +418,7 @@ public class ApplicationTests
 
     [Theory]
     [InlineData (typeof (FakeDriver))]
+
     //[InlineData (typeof (DotNetDriver))]
     //[InlineData (typeof (WindowsDriver))]
     //[InlineData (typeof (UnixDriver))]
@@ -461,11 +458,8 @@ public class ApplicationTests
     [AutoInitShutdown]
     public void Init_Unbalanced_Throws ()
     {
-        Assert.Throws<InvalidOperationException> (
-                                                  () =>
-                                                      Application.InternalInit (
-                                                                                new FakeDriver ()
-                                                                               )
+        Assert.Throws<InvalidOperationException> (() =>
+                                                      Application.Init (null, "fake")
                                                  );
         Application.Shutdown ();
 
@@ -473,7 +467,6 @@ public class ApplicationTests
         Assert.Null (Application.Driver);
     }
 
-
     [Fact]
     [AutoInitShutdown]
     public void Init_Unbalanced_Throws2 ()
@@ -496,7 +489,7 @@ public class ApplicationTests
         // NOTE: Run<T>, when called after Init has been called behaves differently than
         // when called if Init has not been called.
         Toplevel topLevel = new ();
-        Application.InternalInit (new FakeDriver ());
+        Application.Init (null, "fake");
 
         RunState runstate = null;
 
@@ -532,6 +525,7 @@ public class ApplicationTests
     {
         Application.ForceDriver = "Fake";
         Application.Init ();
+
         //Assert.IsType<FakeConsoleInput>(Application.Drive);
         //Assert.IsType<FakeDriver> (Application.Driver);
         Application.ResetState ();
@@ -556,7 +550,7 @@ public class ApplicationTests
         }
         finally
         {
-            Application.ResetState (false);
+            Application.ResetState ();
         }
     }
 
@@ -594,7 +588,7 @@ public class ApplicationTests
     {
         var iteration = 0;
 
-        Application.Init (null, driverName: "fake");
+        Application.Init (null, "fake");
 
         Application.Iteration += Application_Iteration;
         Application.Run<Toplevel> ().Dispose ();
@@ -620,9 +614,9 @@ public class ApplicationTests
     [AutoInitShutdown]
     public void Screen_Size_Changes ()
     {
-        var driver = Application.Driver;
+        IConsoleDriver driver = Application.Driver;
 
-        AutoInitShutdownAttribute.FakeResize (new Size (80,25));
+        Application.Driver!.SetScreenSize (80, 25);
 
         Assert.Equal (new (0, 0, 80, 25), driver.Screen);
         Assert.Equal (new (0, 0, 80, 25), Application.Screen);
@@ -630,13 +624,14 @@ public class ApplicationTests
         // TODO: Should not be possible to manually change these at whim!
         driver.Cols = 100;
         driver.Rows = 30;
+
         // IConsoleDriver.Screen isn't assignable
         //driver.Screen = new (0, 0, driver.Cols, Rows);
 
-        AutoInitShutdownAttribute.FakeResize (new Size (100, 30));
+        Application.Driver!.SetScreenSize (100, 30);
 
         Assert.Equal (new (0, 0, 100, 30), driver.Screen);
-        
+
         // Assert does not make sense
         // Assert.NotEqual (new (0, 0, 100, 30), Application.Screen);
         // Assert.Equal (new (0, 0, 80, 25), Application.Screen);
@@ -647,11 +642,7 @@ public class ApplicationTests
     }
 
     [Fact]
-    public void InitState_Throws_If_Driver_Is_Null ()
-    {
-        Assert.Throws<ArgumentNullException> (static () => Application.SubscribeDriverEvents ());
-    }
-
+    public void InitState_Throws_If_Driver_Is_Null () { Assert.Throws<ArgumentNullException> (static () => Application.SubscribeDriverEvents ()); }
 
     #region RunTests
 
@@ -701,7 +692,6 @@ public class ApplicationTests
     [TestRespondersDisposed]
     public void Run_T_After_Init_Does_Not_Disposes_Application_Top ()
     {
-
         // Init doesn't create a Toplevel and assigned it to Application.Top
         // but Begin does
         var initTop = new Toplevel ();
@@ -785,7 +775,7 @@ public class ApplicationTests
         Assert.Null (Application.Driver);
     }
 
-    [Fact(Skip = "FakeDriver is not allowed, use AutoInitShutdown attribute instead")]
+    [Fact (Skip = "FakeDriver is not allowed, use AutoInitShutdown attribute instead")]
     [TestRespondersDisposed]
     public void Run_T_NoInit_DoesNotThrow ()
     {
@@ -907,7 +897,7 @@ public class ApplicationTests
             Width = 5, Height = 5,
             Arrangement = ViewArrangement.Movable
         };
-        AutoInitShutdownAttribute.FakeResize (new Size (10, 10));
+        Application.Driver!.SetScreenSize (10, 10);
         RunState rs = Application.Begin (w);
 
         // Don't use visuals to test as style of border can change over time.
@@ -1075,7 +1065,8 @@ public class ApplicationTests
         Assert.Null (Application.Top);
     }
 
-    private class TestToplevel : Toplevel { }
+    private class TestToplevel : Toplevel
+    { }
 
     private readonly object _forceDriverLock = new ();
 
@@ -1155,19 +1146,15 @@ public class ApplicationTests
         Assert.False (Application.Initialized);
         Application.Init (null, "v2net");
         Assert.True (Application.Initialized);
-        Task.Run (() =>
-                  {
-                      Task.Delay (300).Wait ();
-                  }).ContinueWith (
-                                   (t, _) =>
-                                   {
-                                       // no longer loading
-                                       Application.Invoke (() =>
-                                                           {
-                                                               Application.RequestStop ();
-                                                           });
-                                   },
-                                   TaskScheduler.FromCurrentSynchronizationContext ());
+
+        Task.Run (() => { Task.Delay (300).Wait (); })
+            .ContinueWith (
+                           (t, _) =>
+                           {
+                               // no longer loading
+                               Application.Invoke (() => { Application.RequestStop (); });
+                           },
+                           TaskScheduler.FromCurrentSynchronizationContext ());
         Application.Run<TestToplevel> ();
         Assert.NotNull (Application.Driver);
         Assert.NotNull (Application.Top);

+ 60 - 48
Tests/UnitTests/Application/TimedEventsTests.cs

@@ -1,42 +1,50 @@
-using System.Diagnostics;
-
+#nullable enable
 namespace UnitTests.ApplicationTests;
 
 /// <summary>
-/// Tests for TimedEvents class, focusing on high-resolution timing with Stopwatch.
+///     Tests for TimedEvents class, focusing on high-resolution timing with Stopwatch.
 /// </summary>
 public class TimedEventsTests
 {
     [Fact]
     public void HighFrequency_Concurrent_Invocations_No_Lost_Timeouts ()
     {
-        var timedEvents = new Terminal.Gui.App.TimedEvents ();
+        var timedEvents = new TimedEvents ();
         var counter = 0;
         var expected = 1000;
         var completed = new ManualResetEventSlim (false);
 
         // Add many timeouts with TimeSpan.Zero concurrently
-        Parallel.For (0, expected, i =>
-        {
-            timedEvents.Add (TimeSpan.Zero, () =>
-            {
-                var current = Interlocked.Increment (ref counter);
-                if (current == expected)
-                {
-                    completed.Set ();
-                }
-                return false; // One-shot
-            });
-        });
+        Parallel.For (
+                      0,
+                      expected,
+                      i =>
+                      {
+                          timedEvents.Add (
+                                           TimeSpan.Zero,
+                                           () =>
+                                           {
+                                               int current = Interlocked.Increment (ref counter);
+
+                                               if (current == expected)
+                                               {
+                                                   completed.Set ();
+                                               }
+
+                                               return false; // One-shot
+                                           });
+                      });
 
         // Run timers multiple times to ensure all are processed
-        for (int i = 0; i < 10; i++)
+        for (var i = 0; i < 10; i++)
         {
             timedEvents.RunTimers ();
+
             if (completed.IsSet)
             {
                 break;
             }
+
             Thread.Sleep (10);
         }
 
@@ -46,51 +54,52 @@ public class TimedEventsTests
     [Fact]
     public void GetTimestampTicks_Provides_High_Resolution ()
     {
-        var timedEvents = new Terminal.Gui.App.TimedEvents ();
-        
+        var timedEvents = new TimedEvents ();
+
         // Add multiple timeouts with TimeSpan.Zero rapidly
-        var timestamps = new List<long> ();
-        
+        List<long> timestamps = new ();
+
         // Single event handler to capture all timestamps
-        EventHandler<Terminal.Gui.App.TimeoutEventArgs>? handler = null;
-        handler = (s, e) =>
-        {
-            timestamps.Add (e.Ticks);
-        };
-        
+        EventHandler<TimeoutEventArgs>? handler = null;
+        handler = (s, e) => { timestamps.Add (e.Ticks); };
+
         timedEvents.Added += handler;
-        
-        for (int i = 0; i < 100; i++)
+
+        for (var i = 0; i < 100; i++)
         {
             timedEvents.Add (TimeSpan.Zero, () => false);
         }
-        
+
         timedEvents.Added -= handler;
 
         // Verify that we got timestamps
         Assert.True (timestamps.Count > 0, $"Should have captured timestamps. Got {timestamps.Count}");
-        
+
         // Verify that we got unique timestamps (or very close)
         // With Stopwatch, we should have much better resolution than DateTime.UtcNow
-        var uniqueTimestamps = timestamps.Distinct ().Count ();
-        
+        int uniqueTimestamps = timestamps.Distinct ().Count ();
+
         // We should have mostly unique timestamps
         // Allow some duplicates due to extreme speed, but should be > 50% unique
-        Assert.True (uniqueTimestamps > timestamps.Count / 2, 
-            $"Expected more unique timestamps. Got {uniqueTimestamps} unique out of {timestamps.Count} total");
+        Assert.True (
+                     uniqueTimestamps > timestamps.Count / 2,
+                     $"Expected more unique timestamps. Got {uniqueTimestamps} unique out of {timestamps.Count} total");
     }
 
     [Fact]
     public void TimeSpan_Zero_Executes_Immediately ()
     {
-        var timedEvents = new Terminal.Gui.App.TimedEvents ();
+        var timedEvents = new TimedEvents ();
         var executed = false;
 
-        timedEvents.Add (TimeSpan.Zero, () =>
-        {
-            executed = true;
-            return false;
-        });
+        timedEvents.Add (
+                         TimeSpan.Zero,
+                         () =>
+                         {
+                             executed = true;
+
+                             return false;
+                         });
 
         Assert.True (timedEvents.Timeouts.Keys [0] > 0);
 
@@ -104,17 +113,20 @@ public class TimedEventsTests
     [Fact]
     public void Multiple_TimeSpan_Zero_Timeouts_All_Execute ()
     {
-        var timedEvents = new Terminal.Gui.App.TimedEvents ();
+        var timedEvents = new TimedEvents ();
         var executeCount = 0;
         var expected = 100;
 
-        for (int i = 0; i < expected; i++)
+        for (var i = 0; i < expected; i++)
         {
-            timedEvents.Add (TimeSpan.Zero, () =>
-            {
-                Interlocked.Increment (ref executeCount);
-                return false;
-            });
+            timedEvents.Add (
+                             TimeSpan.Zero,
+                             () =>
+                             {
+                                 Interlocked.Increment (ref executeCount);
+
+                                 return false;
+                             });
         }
 
         // Run timers once

+ 8 - 29
Tests/UnitTests/AutoInitShutdownAttribute.cs

@@ -26,7 +26,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
     ///     <paramref name="autoInit"/> is true.
     /// </param>
     /// <param name="useFakeClipboard">
-    ///     If true, will force the use of <see cref="FakeDriver.FakeClipboard"/>. Only valid if
+    ///     If true, will force the use of <see cref="FakeClipboard"/>. Only valid if
     ///     <see cref="IConsoleDriver"/> == <see cref="FakeDriver"/> and <paramref name="autoInit"/> is true.
     /// </param>
     /// <param name="fakeClipboardAlwaysThrowsNotSupportedException">
@@ -107,7 +107,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
         Debug.Assert (!CM.IsEnabled, "This test left ConfigurationManager enabled!");
 
         // Force the ConfigurationManager to reset to its hardcoded defaults
-        CM.Disable(true);
+        CM.Disable (true);
     }
 
     public override void Before (MethodInfo methodUnderTest)
@@ -138,12 +138,14 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
 #endif
             if (_driverType == null)
             {
-                Application.Top = null;
-                Application.TopLevels.Clear ();
+                //Application.Init (null, "fake");
+                //Application.Driver!.SetScreenSize (80, 25);
+                //Application.Top = null;
+                //Application.TopLevels.Clear ();
 
                 var fa = new FakeApplicationFactory ();
                 _v2Cleanup = fa.SetupFakeApplication ();
-                AutoInitShutdownAttribute.FakeResize (new Size (80,25));
+                //Application.Driver!.SetScreenSize (80,25));
             }
             else
             {
@@ -154,35 +156,12 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
 
     private bool AutoInit { get; }
 
-    /// <summary>
-    /// 'Resizes' the application and forces layout. Only works if your test uses <see cref="AutoInitShutdownAttribute"/>
-    /// </summary>
-    /// <param name="size"></param>
-    public static void FakeResize (Size size)
-    {
-        var d = (IConsoleDriverFacade)Application.Driver!;
-        d.OutputBuffer.SetWindowSize (size.Width, size.Height);
-        
-        // Handle both FakeSizeMonitor (from test project) and FakeWindowSizeMonitor (from main library)
-        if (d.WindowSizeMonitor is FakeSizeMonitor fakeSizeMonitor)
-        {
-            fakeSizeMonitor.RaiseSizeChanging (size);
-        }
-        else if (d.WindowSizeMonitor is FakeWindowSizeMonitor fakeWindowSizeMonitor)
-        {
-            // For FakeWindowSizeMonitor, use the RaiseSizeChanging method
-            fakeWindowSizeMonitor.RaiseSizeChanging (size);
-        }
-
-        Application.LayoutAndDraw (true);
-    }
-
     /// <summary>
     /// Runs a single iteration of the main loop (layout, draw, run timed events etc.)
     /// </summary>
     public static void RunIteration ()
     {
-        var a = (ApplicationImpl)ApplicationImpl.Instance;
+        ApplicationImpl a = (ApplicationImpl)ApplicationImpl.Instance;
         a.Coordinator?.RunIteration ();
     }
 }

+ 57 - 80
Tests/UnitTests/ConsoleDrivers/ClipRegionTests.cs

@@ -15,119 +15,96 @@ public class ClipRegionTests
         this._output = output;
     }
 
-    [Theory]
-    [InlineData (typeof (FakeDriver))]
-    //[InlineData (typeof (DotNetDriver))]
-
-    //[InlineData (typeof (ANSIDriver))]
-    //[InlineData (typeof (WindowsDriver))]
-    //[InlineData (typeof (UnixDriver))]
-    public void AddRune_Is_Clipped (Type driverType)
+    [Fact]
+    public void AddRune_Is_Clipped ()
     {
-        var driver = (IConsoleDriver)Activator.CreateInstance (driverType);
-        Application.Init (driver);
-        Application.Driver!.Rows = 25;
-        Application.Driver!.Cols = 80;
+        Application.Init (null, "fake");
 
-        driver.Move (0, 0);
-        driver.AddRune ('x');
-        Assert.Equal ((Rune)'x', driver.Contents [0, 0].Rune);
+        Application.Driver!.Move (0, 0);
+        Application.Driver!.AddRune ('x');
+        Assert.Equal ((Rune)'x', Application.Driver!.Contents! [0, 0].Rune);
 
-        driver.Move (5, 5);
-        driver.AddRune ('x');
-        Assert.Equal ((Rune)'x', driver.Contents [5, 5].Rune);
+        Application.Driver?.Move (5, 5);
+        Application.Driver?.AddRune ('x');
+        Assert.Equal ((Rune)'x', Application.Driver!.Contents [5, 5].Rune);
 
         // Clear the contents
-        driver.FillRect (new Rectangle (0, 0, driver.Rows, driver.Cols), ' ');
-        Assert.Equal ((Rune)' ', driver.Contents [0, 0].Rune);
+        Application.Driver?.FillRect (new Rectangle (0, 0, Application.Driver.Rows, Application.Driver.Cols), ' ');
+        Assert.Equal ((Rune)' ', Application.Driver?.Contents [0, 0].Rune);
 
         // Setup the region with a single rectangle, fill screen with 'x'
-        driver.Clip = new (new Rectangle (5, 5, 5, 5));
-        driver.FillRect (new Rectangle (0, 0, driver.Rows, driver.Cols), 'x');
-        Assert.Equal ((Rune)' ', driver.Contents [0, 0].Rune);
-        Assert.Equal ((Rune)' ', driver.Contents [4, 9].Rune);
-        Assert.Equal ((Rune)'x', driver.Contents [5, 5].Rune);
-        Assert.Equal ((Rune)'x', driver.Contents [9, 9].Rune);
-        Assert.Equal ((Rune)' ', driver.Contents [10, 10].Rune);
+        Application.Driver!.Clip = new (new Rectangle (5, 5, 5, 5));
+        Application.Driver.FillRect (new Rectangle (0, 0, Application.Driver.Rows, Application.Driver.Cols), 'x');
+        Assert.Equal ((Rune)' ', Application.Driver?.Contents [0, 0].Rune);
+        Assert.Equal ((Rune)' ', Application.Driver?.Contents [4, 9].Rune);
+        Assert.Equal ((Rune)'x', Application.Driver?.Contents [5, 5].Rune);
+        Assert.Equal ((Rune)'x', Application.Driver?.Contents [9, 9].Rune);
+        Assert.Equal ((Rune)' ', Application.Driver?.Contents [10, 10].Rune);
 
         Application.Shutdown ();
     }
 
-    [Theory]
-    [InlineData (typeof (FakeDriver))]
-    //[InlineData (typeof (DotNetDriver))]
-
-    //[InlineData (typeof (ANSIDriver))]
-    //[InlineData (typeof (WindowsDriver))]
-    //[InlineData (typeof (UnixDriver))]
-    public void Clip_Set_To_Empty_AllInvalid (Type driverType)
+    [Fact]
+    public void Clip_Set_To_Empty_AllInvalid ()
     {
-        var driver = (IConsoleDriver)Activator.CreateInstance (driverType);
-        Application.Init (driver);
+        Application.Init (null, "fake");
 
         // Define a clip rectangle
-        driver.Clip = new (Rectangle.Empty);
+        Application.Driver!.Clip = new (Rectangle.Empty);
 
         // negative
-        Assert.False (driver.IsValidLocation (default, 4, 5));
-        Assert.False (driver.IsValidLocation (default, 5, 4));
-        Assert.False (driver.IsValidLocation (default, 10, 9));
-        Assert.False (driver.IsValidLocation (default, 9, 10));
-        Assert.False (driver.IsValidLocation (default, -1, 0));
-        Assert.False (driver.IsValidLocation (default, 0, -1));
-        Assert.False (driver.IsValidLocation (default, -1, -1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows));
+        Assert.False (Application.Driver.IsValidLocation (default, 4, 5));
+        Assert.False (Application.Driver.IsValidLocation (default, 5, 4));
+        Assert.False (Application.Driver.IsValidLocation (default, 10, 9));
+        Assert.False (Application.Driver.IsValidLocation (default, 9, 10));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, 0));
+        Assert.False (Application.Driver.IsValidLocation (default, 0, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows));
 
         Application.Shutdown ();
     }
 
-    [Theory]
-    [InlineData (typeof (FakeDriver))]
-    //[InlineData (typeof (DotNetDriver))]
-
-    //[InlineData (typeof (ANSIDriver))]
-    //[InlineData (typeof (WindowsDriver))]
-    //[InlineData (typeof (UnixDriver))]
-    public void IsValidLocation (Type driverType)
+    [Fact]
+    public void IsValidLocation ()
     {
-        var driver = (IConsoleDriver)Activator.CreateInstance (driverType);
-        Application.Init (driver);
+        Application.Init (null, "fake");
         Application.Driver!.Rows = 10;
         Application.Driver!.Cols = 10;
 
         // positive
-        Assert.True (driver.IsValidLocation (default, 0, 0));
-        Assert.True (driver.IsValidLocation (default, 1, 1));
-        Assert.True (driver.IsValidLocation (default, driver.Cols - 1, driver.Rows - 1));
+        Assert.True (Application.Driver.IsValidLocation (default, 0, 0));
+        Assert.True (Application.Driver.IsValidLocation (default, 1, 1));
+        Assert.True (Application.Driver.IsValidLocation (default, Application.Driver.Cols - 1, Application.Driver.Rows - 1));
 
         // negative
-        Assert.False (driver.IsValidLocation (default, -1, 0));
-        Assert.False (driver.IsValidLocation (default, 0, -1));
-        Assert.False (driver.IsValidLocation (default, -1, -1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, 0));
+        Assert.False (Application.Driver.IsValidLocation (default, 0, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows));
 
         // Define a clip rectangle
-        driver.Clip = new(new Rectangle(5, 5, 5, 5));
+        Application.Driver.Clip = new (new Rectangle (5, 5, 5, 5));
 
         // positive
-        Assert.True (driver.IsValidLocation (default, 5, 5));
-        Assert.True (driver.IsValidLocation (default, 9, 9));
+        Assert.True (Application.Driver.IsValidLocation (default, 5, 5));
+        Assert.True (Application.Driver.IsValidLocation (default, 9, 9));
 
         // negative
-        Assert.False (driver.IsValidLocation (default, 4, 5));
-        Assert.False (driver.IsValidLocation (default, 5, 4));
-        Assert.False (driver.IsValidLocation (default, 10, 9));
-        Assert.False (driver.IsValidLocation (default, 9, 10));
-        Assert.False (driver.IsValidLocation (default, -1, 0));
-        Assert.False (driver.IsValidLocation (default, 0, -1));
-        Assert.False (driver.IsValidLocation (default, -1, -1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows - 1));
-        Assert.False (driver.IsValidLocation (default, driver.Cols, driver.Rows));
+        Assert.False (Application.Driver.IsValidLocation (default, 4, 5));
+        Assert.False (Application.Driver.IsValidLocation (default, 5, 4));
+        Assert.False (Application.Driver.IsValidLocation (default, 10, 9));
+        Assert.False (Application.Driver.IsValidLocation (default, 9, 10));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, 0));
+        Assert.False (Application.Driver.IsValidLocation (default, 0, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, -1, -1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows - 1));
+        Assert.False (Application.Driver.IsValidLocation (default, Application.Driver.Cols, Application.Driver.Rows));
 
         Application.Shutdown ();
     }

+ 1 - 1
Tests/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs

@@ -160,7 +160,7 @@ public class ConsoleDriverTests
     //		{
     //			var win = new Window ();
     //			Application.Begin (win);
-    //			AutoInitShutdownAttribute.FakeResize(new Size ( (20, 8);
+    //			Application.Driver!.SetScreenSize ( (20, 8);
 
     //			System.Threading.Tasks.Task.Run (() => {
     //				System.Threading.Tasks.Task.Delay (500).Wait ();

+ 106 - 0
Tests/UnitTests/ConsoleDrivers/EscSeqUtilsTests.cs

@@ -0,0 +1,106 @@
+using System.Text;
+
+// ReSharper disable HeuristicUnreachableCode
+
+namespace UnitTests.DriverTests;
+
+public class EscSeqUtilsTests
+{
+    [Fact]
+    public void Defaults_Values ()
+    {
+        Assert.Equal ('\x1b', EscSeqUtils.KeyEsc);
+        Assert.Equal ("\x1b[", EscSeqUtils.CSI);
+        Assert.Equal ("\x1b[?1003h", EscSeqUtils.CSI_EnableAnyEventMouse);
+        Assert.Equal ("\x1b[?1006h", EscSeqUtils.CSI_EnableSgrExtModeMouse);
+        Assert.Equal ("\x1b[?1015h", EscSeqUtils.CSI_EnableUrxvtExtModeMouse);
+        Assert.Equal ("\x1b[?1003l", EscSeqUtils.CSI_DisableAnyEventMouse);
+        Assert.Equal ("\x1b[?1006l", EscSeqUtils.CSI_DisableSgrExtModeMouse);
+        Assert.Equal ("\x1b[?1015l", EscSeqUtils.CSI_DisableUrxvtExtModeMouse);
+        Assert.Equal ("\x1b[?1003h\x1b[?1015h\u001b[?1006h", EscSeqUtils.CSI_EnableMouseEvents);
+        Assert.Equal ("\x1b[?1003l\x1b[?1015l\u001b[?1006l", EscSeqUtils.CSI_DisableMouseEvents);
+    }
+
+    [Fact]
+    public void GetConsoleInputKey_ConsoleKeyInfo ()
+    {
+        var cki = new ConsoleKeyInfo ('r', 0, false, false, false);
+        var expectedCki = new ConsoleKeyInfo ('r', ConsoleKey.R, false, false, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, true, false, false);
+        expectedCki = new ('r', ConsoleKey.R, true, false, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, false, true, false);
+        expectedCki = new ('r', ConsoleKey.R, false, true, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, false, false, true);
+        expectedCki = new ('r', ConsoleKey.R, false, false, true);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, true, true, false);
+        expectedCki = new ('r', ConsoleKey.R, true, true, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, false, true, true);
+        expectedCki = new ('r', ConsoleKey.R, false, true, true);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('r', 0, true, true, true);
+        expectedCki = new ('r', ConsoleKey.R, true, true, true);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('\u0012', 0, false, false, false);
+        expectedCki = new ('\u0012', ConsoleKey.R, false, false, true);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('\0', (ConsoleKey)64, false, false, true);
+        expectedCki = new ('\0', ConsoleKey.Spacebar, false, false, true);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('\r', 0, false, false, false);
+        expectedCki = new ('\r', ConsoleKey.Enter, false, false, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('\u007f', 0, false, false, false);
+        expectedCki = new ('\u007f', ConsoleKey.Backspace, false, false, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+
+        cki = new ('R', 0, false, false, false);
+        expectedCki = new ('R', ConsoleKey.R, true, false, false);
+        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
+    }
+
+    [Theory]
+    [InlineData (0, 0, $"{EscSeqUtils.CSI}0;0H")]
+    [InlineData (int.MaxValue, int.MaxValue, $"{EscSeqUtils.CSI}2147483647;2147483647H")]
+    [InlineData (int.MinValue, int.MinValue, $"{EscSeqUtils.CSI}-2147483648;-2147483648H")]
+    public void CSI_WriteCursorPosition_ReturnsCorrectEscSeq (int row, int col, string expected)
+    {
+        StringBuilder builder = new();
+        using StringWriter writer = new(builder);
+
+        EscSeqUtils.CSI_WriteCursorPosition (writer, row, col);
+
+        string actual = builder.ToString();
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ('\u001B', KeyCode.Esc)]
+    [InlineData ('\r', KeyCode.Enter)]
+    [InlineData ('1', KeyCode.D1)]
+    [InlineData ('!', (KeyCode)'!')]
+    [InlineData ('a', KeyCode.A)]
+    [InlineData ('A', KeyCode.A | KeyCode.ShiftMask)]
+    public void MapChar_Returns_Modifiers_If_Needed (char ch, KeyCode keyCode)
+    {
+        ConsoleKeyInfo cki = EscSeqUtils.MapChar (ch);
+        Key key = EscSeqUtils.MapKey (cki);
+        Key expectedKey = keyCode;
+
+        Assert.Equal (key, expectedKey);
+    }
+}

+ 223 - 86
Tests/UnitTests/ConsoleDrivers/FakeDriverTests.cs

@@ -1,12 +1,10 @@
-using UnitTests;
-using Xunit;
-
+using System.Text;
 using Xunit.Abstractions;
 
 namespace UnitTests.DriverTests;
 
 /// <summary>
-/// Tests for the FakeDriver to ensure it works properly with the modern component factory architecture.
+///     Tests for the FakeDriver to ensure it works properly with the modern component factory architecture.
 /// </summary>
 public class FakeDriverTests (ITestOutputHelper output)
 {
@@ -20,12 +18,13 @@ public class FakeDriverTests (ITestOutputHelper output)
     {
         // Verify Application was initialized
         Assert.True (Application.Initialized);
-     //   Assert.NotNull (Application.Top);
-        
+
+        //   Assert.NotNull (Application.Top);
+
         // Verify it's using a driver facade (modern architecture)
         Assert.IsAssignableFrom<IConsoleDriverFacade> (Application.Driver);
-        
-        _output.WriteLine ($"Driver type: {Application.Driver.GetType().Name}");
+
+        _output.WriteLine ($"Driver type: {Application.Driver.GetType ().Name}");
         _output.WriteLine ($"Screen size: {Application.Screen}");
     }
 
@@ -48,7 +47,7 @@ public class FakeDriverTests (ITestOutputHelper output)
         Assert.Equal (25, Application.Driver.Rows);
 
         // Resize to 100x30
-        AutoInitShutdownAttribute.FakeResize (new (100, 30));
+        Application.Driver?.SetScreenSize (100, 30);
 
         // Verify new size
         Assert.Equal (100, Application.Driver.Cols);
@@ -60,7 +59,7 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Top_Is_Created ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         Application.Begin (Application.Top);
 
@@ -73,7 +72,7 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Can_Add_View_To_Top ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var label = new Label { Text = "Hello World" };
         Application.Top!.Add (label);
@@ -86,12 +85,11 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_RunIteration_Works ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var label = new Label { Text = "Hello" };
         Application.Top!.Add (label);
 
-
         Application.Begin (Application.Top);
 
         // Run a single iteration - this should layout and draw
@@ -106,43 +104,43 @@ public class FakeDriverTests (ITestOutputHelper output)
 
     #region AutoInitShutdown Attribute Tests
 
-    [Theory]
-    [InlineData (true)]
-    [InlineData (false)]
-    public void AutoInitShutdown_Attribute_Respects_AutoInit_Parameter (bool autoInit)
-    {
-        // When autoInit is false, Application should not be initialized
-        // When autoInit is true, Application should be initialized
-        
-        // This test will be called twice - once with autoInit=true, once with false
-        // We can't use the attribute directly in the test body, but we can verify
-        // the behavior by checking Application.Initialized
-        
-        // For this test to work properly, we need to call Application.Init manually when autoInit=false
-        bool wasInitialized = Application.Initialized;
-        
-        try
-        {
-            if (!wasInitialized)
-            {
-                Application.ResetState ();
-                var fa = new FakeApplicationFactory ();
-                using var cleanup = fa.SetupFakeApplication ();
-                Assert.True (Application.Initialized);
-            }
-            else
-            {
-                Assert.True (Application.Initialized);
-            }
-        }
-        finally
-        {
-            if (!wasInitialized)
-            {
-                Application.Shutdown ();
-            }
-        }
-    }
+    //[Theory]
+    //[InlineData (true)]
+    //[InlineData (false)]
+    //public void AutoInitShutdown_Attribute_Respects_AutoInit_Parameter (bool autoInit)
+    //{
+    //    // When autoInit is false, Application should not be initialized
+    //    // When autoInit is true, Application should be initialized
+
+    //    // This test will be called twice - once with autoInit=true, once with false
+    //    // We can't use the attribute directly in the test body, but we can verify
+    //    // the behavior by checking Application.Initialized
+
+    //    // For this test to work properly, we need to call Application.Init manually when autoInit=false
+    //    bool wasInitialized = Application.Initialized;
+
+    //    try
+    //    {
+    //        if (!wasInitialized)
+    //        {
+    //            Application.ResetState ();
+    //            var fa = new FakeApplicationFactory ();
+    //            using IDisposable cleanup = fa.SetupFakeApplication ();
+    //            Assert.True (Application.Initialized);
+    //        }
+    //        else
+    //        {
+    //            Assert.True (Application.Initialized);
+    //        }
+    //    }
+    //    finally
+    //    {
+    //        if (!wasInitialized)
+    //        {
+    //            Application.Shutdown ();
+    //        }
+    //    }
+    //}
 
     [Fact]
     public void Without_AutoInitShutdown_Application_Is_Not_Initialized ()
@@ -180,24 +178,24 @@ public class FakeDriverTests (ITestOutputHelper output)
 
     [Fact]
     [SetupFakeDriver]
-    public void SetupFakeDriver_Driver_Is_FakeConsoleDriver ()
+    public void SetupFakeDriver_Driver_Is_IConsoleDriver ()
     {
         Assert.NotNull (Application.Driver);
-        
-        // Should be IFakeConsoleDriver
-        Assert.IsAssignableFrom<IFakeConsoleDriver> (Application.Driver);
-        
-        _output.WriteLine ($"Driver type: {Application.Driver.GetType().Name}");
+
+        // Should be IConsoleDriver
+        Assert.IsAssignableFrom<IConsoleDriver> (Application.Driver);
+
+        _output.WriteLine ($"Driver type: {Application.Driver.GetType ().Name}");
     }
 
     [Fact]
     [SetupFakeDriver]
-    public void SetupFakeDriver_Can_Set_Buffer_Size ()
+    public void SetupFakeDriver_Can_Set_Screen_Size ()
     {
-        var fakeDriver = Application.Driver as IFakeConsoleDriver;
+        IConsoleDriver fakeDriver = Application.Driver;
         Assert.NotNull (fakeDriver);
 
-        fakeDriver!.SetBufferSize (100, 50);
+        fakeDriver!.SetScreenSize (100, 50);
 
         Assert.Equal (100, Application.Driver!.Cols);
         Assert.Equal (50, Application.Driver.Rows);
@@ -211,10 +209,10 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Can_Draw_Simple_View ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
-        var window = new Window 
-        { 
+        var window = new Window
+        {
             Title = "Test Window",
             X = 0,
             Y = 0,
@@ -222,13 +220,13 @@ public class FakeDriverTests (ITestOutputHelper output)
             Height = 10
         };
 
-        var label = new Label 
-        { 
+        var label = new Label
+        {
             Text = "Hello World",
             X = 1,
             Y = 1
         };
-        
+
         window.Add (label);
         Application.Top!.Add (window);
 
@@ -248,13 +246,13 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Multiple_RunIterations_Work ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var label = new Label { Text = "Iteration Test" };
         Application.Top!.Add (label);
 
         // Run multiple iterations
-        for (int i = 0; i < 5; i++)
+        for (var i = 0; i < 5; i++)
         {
             AutoInitShutdownAttribute.RunIteration ();
         }
@@ -270,10 +268,10 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Resize_Triggers_Layout ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
-        var view = new View 
-        { 
+        var view = new View
+        {
             Width = Dim.Fill (),
             Height = Dim.Fill ()
         };
@@ -281,16 +279,15 @@ public class FakeDriverTests (ITestOutputHelper output)
 
         Application.Begin (Application.Top);
 
-        AutoInitShutdownAttribute.FakeResize (new Size (80,25));
         AutoInitShutdownAttribute.RunIteration ();
 
         // Check initial size
-        var initialFrame = view.Frame;
+        Rectangle initialFrame = view.Frame;
         Assert.Equal (80, initialFrame.Width);
         Assert.Equal (25, initialFrame.Height);
 
         // Resize
-        AutoInitShutdownAttribute.FakeResize (new (100, 40));
+        Application.Driver?.SetScreenSize (100, 40);
 
         // Check new size
         Assert.Equal (100, view.Frame.Width);
@@ -301,7 +298,7 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Window_Can_Be_Shown_And_Closed ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var window = new Window { Title = "Test" };
         Application.Top!.Add (window);
@@ -346,8 +343,8 @@ public class FakeDriverTests (ITestOutputHelper output)
         Assert.NotNull (Application.Driver!.Clipboard);
 
         // Should throw NotSupportedException
-        Assert.Throws<NotSupportedException> (() => 
-            Application.Driver.Clipboard.GetClipboardData ());
+        Assert.Throws<NotSupportedException> (() =>
+                                                  Application.Driver.Clipboard.GetClipboardData ());
     }
 
     #endregion
@@ -358,11 +355,11 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Handles_Invalid_Coordinates_Gracefully ()
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         // Try to add a view with invalid coordinates - should not crash
-        var view = new View 
-        { 
+        var view = new View
+        {
             X = -1000,
             Y = -1000,
             Width = 10,
@@ -370,10 +367,10 @@ public class FakeDriverTests (ITestOutputHelper output)
         };
 
         Application.Top!.Add (view);
-        
+
         // Should not throw
         AutoInitShutdownAttribute.RunIteration ();
-        
+
         Assert.True (Application.Initialized);
     }
 
@@ -381,8 +378,8 @@ public class FakeDriverTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void FakeDriver_Survives_Rapid_Resizes ()
     {
-        var sizes = new[] 
-        { 
+        Size [] sizes = new []
+        {
             new Size (80, 25),
             new Size (100, 30),
             new Size (60, 20),
@@ -390,15 +387,155 @@ public class FakeDriverTests (ITestOutputHelper output)
             new Size (80, 25)
         };
 
-        foreach (var size in sizes)
+        foreach (Size size in sizes)
         {
-            AutoInitShutdownAttribute.FakeResize (size);
+            Application.Driver!.SetScreenSize (size.Width, size.Height);
             AutoInitShutdownAttribute.RunIteration ();
-            
+
             Assert.Equal (size.Width, Application.Driver!.Cols);
             Assert.Equal (size.Height, Application.Driver.Rows);
         }
     }
 
     #endregion
+
+    #region Buffer and Fill Tests
+
+    [Fact]
+    [AutoInitShutdown]
+    public void FakeDriver_Can_Fill_Rectangle ()
+    {
+        // Verify driver is initialized with buffers
+        Assert.NotNull (Application.Driver);
+        Assert.NotNull (Application.Driver!.Contents);
+
+        // Fill a rectangle
+        var rect = new Rectangle (5, 5, 10, 5);
+        Application.Driver.FillRect (rect, (Rune)'X');
+
+        // Verify the rectangle was filled
+        for (int row = rect.Y; row < rect.Y + rect.Height; row++)
+        {
+            for (int col = rect.X; col < rect.X + rect.Width; col++)
+            {
+                Assert.Equal ((Rune)'X', Application.Driver.Contents [row, col].Rune);
+            }
+        }
+    }
+
+    [Fact]
+    [AutoInitShutdown]
+    public void FakeDriver_Buffer_Integrity_After_Multiple_Resizes ()
+    {
+        // Start with default size
+        Assert.Equal (80, Application.Driver!.Cols);
+        Assert.Equal (25, Application.Driver.Rows);
+
+        // Fill with a pattern
+        Application.Driver.FillRect (new (0, 0, 10, 5), (Rune)'A');
+
+        // Resize
+        Application.Driver?.SetScreenSize (100, 30);
+
+        // Verify new size
+        Assert.Equal (100, Application.Driver.Cols);
+        Assert.Equal (30, Application.Driver.Rows);
+
+        // Verify buffer is clean (no stale runes from previous size)
+        Assert.NotNull (Application.Driver.Contents);
+        Assert.Equal (30, Application.Driver.Contents!.GetLength (0));
+        Assert.Equal (100, Application.Driver.Contents.GetLength (1));
+
+        // Fill with new pattern
+        Application.Driver.FillRect (new (0, 0, 20, 10), (Rune)'B');
+
+        // Resize back
+        Application.Driver?.SetScreenSize (80, 25);
+
+        // Verify size is back
+        Assert.Equal (80, Application.Driver.Cols);
+        Assert.Equal (25, Application.Driver.Rows);
+
+        // Verify buffer dimensions match
+        Assert.Equal (25, Application.Driver.Contents.GetLength (0));
+        Assert.Equal (80, Application.Driver.Contents.GetLength (1));
+    }
+
+    #endregion
+
+    #region ScreenChanged Event Tests
+
+    [Fact]
+    [AutoInitShutdown]
+    public void ScreenChanged_Event_Fires_On_SetScreenSize ()
+    {
+        var screenChangedFired = false;
+        Size? newSize = null;
+
+        Application.Driver!.SizeChanged += (sender, args) =>
+                                           {
+                                               screenChangedFired = true;
+                                               newSize = args.Size;
+                                           };
+
+        // Trigger resize using FakeResize which uses SetScreenSize internally
+        Application.Driver?.SetScreenSize (100, 30);
+
+        // Verify event fired
+        Assert.True (screenChangedFired);
+        Assert.NotNull (newSize);
+        Assert.Equal (100, newSize!.Value.Width);
+        Assert.Equal (30, newSize.Value.Height);
+    }
+
+    [Fact]
+    [AutoInitShutdown]
+    public void FakeResize_Triggers_ScreenChanged_And_Updates_Application_Screen ()
+    {
+        var screenChangedFired = false;
+        Size? eventSize = null;
+
+        Application.Driver!.SizeChanged += (sender, args) =>
+                                           {
+                                               screenChangedFired = true;
+                                               eventSize = args.Size;
+                                           };
+
+        // Use FakeResize helper
+        Application.Driver?.SetScreenSize (120, 40);
+
+        // Verify event fired
+        Assert.True (screenChangedFired);
+        Assert.NotNull (eventSize);
+        Assert.Equal (120, eventSize!.Value.Width);
+        Assert.Equal (40, eventSize.Value.Height);
+
+        // Verify Application.Screen was updated
+        Assert.Equal (new (0, 0, 120, 40), Application.Screen);
+        Assert.Equal (120, Application.Driver.Cols);
+        Assert.Equal (40, Application.Driver.Rows);
+    }
+
+    [Fact]
+    [AutoInitShutdown]
+    public void SizeChanged_Event_Still_Fires_For_Compatibility ()
+    {
+        var sizeChangedFired = false;
+        var screenChangedFired = false;
+
+#pragma warning disable CS0618 // Type or member is obsolete
+        Application.Driver!.SizeChanged += (sender, args) => { sizeChangedFired = true; };
+#pragma warning restore CS0618 // Type or member is obsolete
+
+        Application.Driver.SizeChanged += (sender, args) => { screenChangedFired = true; };
+
+        // Trigger resize using FakeResize
+        Application.Driver?.SetScreenSize (90, 35);
+
+        // Both events should fire for compatibility
+        Assert.True (sizeChangedFired);
+        Assert.True (screenChangedFired);
+    }
+
+    #endregion
 }

+ 25 - 25
Tests/UnitTests/ConsoleDrivers/WindowSizeMonitorTests.cs

@@ -1,43 +1,41 @@
 using Moq;
 
 namespace UnitTests.DriverTests;
+
 public class WindowSizeMonitorTests
 {
-    public WindowSizeMonitorTests ()
-    {
-        ConsoleDriver.RunningUnitTests = false;
-    }
+    public WindowSizeMonitorTests () { ConsoleDriver.RunningUnitTests = false; }
 
     [Fact]
     public void TestWindowSizeMonitor_RaisesEventWhenChanges ()
     {
-        var consoleOutput = new Mock<IConsoleOutput> ();
+        Mock<IConsoleOutput> consoleOutput = new ();
 
-        var queue = new Queue<Size>(new []{
-            new Size (30, 20),
-            new Size (20, 20)
+        Queue<Size> queue = new (
+                                 [
+                                     new (30, 20),
+                                     new (20, 20)
+                                 ]);
 
-        });
-
-        consoleOutput.Setup (m => m.GetWindowSize ())
+        consoleOutput.Setup (m => m.GetSize ())
                      .Returns (queue.Dequeue);
 
         var outputBuffer = Mock.Of<IOutputBuffer> ();
 
-        var monitor = new WindowSizeMonitor (consoleOutput.Object, outputBuffer);
+        var monitor = new ConsoleSizeMonitor (consoleOutput.Object, outputBuffer);
 
-        var result = new List<SizeChangedEventArgs> ();
-        monitor.SizeChanging += (s, e) => { result.Add (e);};
+        List<SizeChangedEventArgs> result = new ();
+        monitor.SizeChanged += (s, e) => { result.Add (e); };
 
         Assert.Empty (result);
         monitor.Poll ();
 
         Assert.Single (result);
-        Assert.Equal (new Size (30,20),result [0].Size);
+        Assert.Equal (new Size (30, 20), result [0].Size);
 
         monitor.Poll ();
 
-        Assert.Equal (2,result.Count);
+        Assert.Equal (2, result.Count);
         Assert.Equal (new Size (30, 20), result [0].Size);
         Assert.Equal (new Size (20, 20), result [1].Size);
     }
@@ -45,22 +43,24 @@ public class WindowSizeMonitorTests
     [Fact]
     public void TestWindowSizeMonitor_DoesNotRaiseEventWhen_NoChanges ()
     {
-        var consoleOutput = new Mock<IConsoleOutput> ();
+        Mock<IConsoleOutput> consoleOutput = new ();
 
-        var queue = new Queue<Size> (new []{
-            new Size (30, 20),
-            new Size (30, 20),
-        });
+        Queue<Size> queue = new (
+                                 new []
+                                 {
+                                     new Size (30, 20),
+                                     new Size (30, 20)
+                                 });
 
-        consoleOutput.Setup (m => m.GetWindowSize ())
+        consoleOutput.Setup (m => m.GetSize ())
                      .Returns (queue.Dequeue);
 
         var outputBuffer = Mock.Of<IOutputBuffer> ();
 
-        var monitor = new WindowSizeMonitor (consoleOutput.Object, outputBuffer);
+        var monitor = new ConsoleSizeMonitor (consoleOutput.Object, outputBuffer);
 
-        var result = new List<SizeChangedEventArgs> ();
-        monitor.SizeChanging += (s, e) => { result.Add (e); };
+        List<SizeChangedEventArgs> result = new ();
+        monitor.SizeChanged += (s, e) => { result.Add (e); };
 
         // First poll always raises event because going from unknown size i.e. 0,0
         Assert.Empty (result);

+ 23 - 23
Tests/UnitTests/Dialogs/DialogTests.cs

@@ -20,7 +20,7 @@ public class DialogTests (ITestOutputHelper output)
 
         // We test with one button first, but do this to get the width right for 2
         int width = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}".Length;
-        AutoInitShutdownAttribute.FakeResize (new (width, 1));
+        Driver?.SetScreenSize (width, 1);
 
         // Override CM
         Dialog.DefaultButtonAlignment = Alignment.Center;
@@ -163,7 +163,7 @@ public class DialogTests (ITestOutputHelper output)
         var buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
         int width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 3));
+        Driver?.SetScreenSize (buttonRow.Length, 3);
 
         // Default - Center
         (runState, Dialog dlg) = BeginButtonTestDialog (
@@ -255,7 +255,7 @@ public class DialogTests (ITestOutputHelper output)
         var buttonRow = string.Empty;
 
         var width = 30;
-        AutoInitShutdownAttribute.FakeResize (new (width, 1));
+        Driver?.SetScreenSize (width, 1);
 
         // Default - Center
         buttonRow =
@@ -351,7 +351,7 @@ public class DialogTests (ITestOutputHelper output)
         //                         123456                          1234567
         var buttonRow = $"{Glyphs.VLine}      {btn1} {btn2} {btn3} {btn4}      {Glyphs.VLine}";
         int width = buttonRow.Length;
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 1));
+        Driver?.SetScreenSize (buttonRow.Length, 1);
 
         // Default - Center
         (runState, Dialog dlg) = BeginButtonTestDialog (
@@ -446,7 +446,7 @@ public class DialogTests (ITestOutputHelper output)
         //                         123456                           123456
         var buttonRow = $"{Glyphs.VLine}      {btn1} {btn2} {btn3} {btn4}      {Glyphs.VLine}";
         int width = buttonRow.GetColumns ();
-        AutoInitShutdownAttribute.FakeResize (new (width, 3));
+        Driver?.SetScreenSize (width, 3);
 
         // Default - Center
         (runState, Dialog dlg) = BeginButtonTestDialog (
@@ -531,7 +531,7 @@ public class DialogTests (ITestOutputHelper output)
             $"{Glyphs.VLine}  {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket}  {Glyphs.VLine}";
         int width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (width, 1));
+        Driver?.SetScreenSize (width, 1);
 
         (runState, Dialog dlg) = BeginButtonTestDialog (
                                                         title,
@@ -595,7 +595,7 @@ public class DialogTests (ITestOutputHelper output)
             $"{Glyphs.VLine}   {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket}   {Glyphs.VLine}";
         width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (width, 1));
+        Driver?.SetScreenSize (width, 1);
 
         (runState, dlg) = BeginButtonTestDialog (
                                                  title,
@@ -675,7 +675,7 @@ public class DialogTests (ITestOutputHelper output)
         var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {btn3} {Glyphs.VLine}";
         int width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 3));
+        Driver?.SetScreenSize (buttonRow.Length, 3);
 
         (runState, Dialog dlg) = BeginButtonTestDialog (
                                                         title,
@@ -758,7 +758,7 @@ public class DialogTests (ITestOutputHelper output)
         var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}";
         int width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 3));
+        Driver?.SetScreenSize (buttonRow.Length, 3);
 
         (runState, Dialog dlg) = BeginButtonTestDialog (
                                                         title,
@@ -837,7 +837,7 @@ public class DialogTests (ITestOutputHelper output)
         var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}";
         int width = buttonRow.Length;
 
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 3));
+        Driver?.SetScreenSize (buttonRow.Length, 3);
 
         // Default (Center)
         Button button1 = new () { Text = btn1Text };
@@ -957,7 +957,7 @@ public class DialogTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Dialog_In_Window_With_Size_One_Button_Aligns ()
     {
-        AutoInitShutdownAttribute.FakeResize (new (20, 5));
+        Driver?.SetScreenSize (20, 5);
 
         // Override CM
         Window.DefaultBorderStyle = LineStyle.Single;
@@ -1062,7 +1062,7 @@ public class DialogTests (ITestOutputHelper output)
                 )]
     public void Dialog_In_Window_Without_Size_One_Button_Aligns (int height, string expected)
     {
-        AutoInitShutdownAttribute.FakeResize (new (20, height));
+        Driver?.SetScreenSize (20, height);
         var win = new Window ();
 
         int iterations = -1;
@@ -1109,7 +1109,7 @@ public class DialogTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Dialog_Opened_From_Another_Dialog ()
     {
-        AutoInitShutdownAttribute.FakeResize (new (30, 10));
+        Driver?.SetScreenSize (30, 10);
 
         // Override CM
         Dialog.DefaultButtonAlignment = Alignment.Center;
@@ -1251,7 +1251,7 @@ public class DialogTests (ITestOutputHelper output)
             Height = Dim.Percent (85)
         };
         Begin (d);
-        AutoInitShutdownAttribute.FakeResize (new (100, 100));
+        Driver?.SetScreenSize (100, 100);
 
         // Default location is centered, so 100 / 2 - 85 / 2 = 7
         var expected = 7;
@@ -1265,7 +1265,7 @@ public class DialogTests (ITestOutputHelper output)
     {
         var d = new Dialog { X = 1, Y = 1 };
         Begin (d);
-        AutoInitShutdownAttribute.FakeResize (new (100, 100));
+        Driver?.SetScreenSize (100, 100);
 
         // Default location is centered, so 100 / 2 - 85 / 2 = 7
         var expected = 1;
@@ -1287,7 +1287,7 @@ public class DialogTests (ITestOutputHelper output)
         var expected = 5;
         var d = new Dialog { X = expected, Y = expected, Height = 5, Width = 5 };
         Begin (d);
-        AutoInitShutdownAttribute.FakeResize (new (20, 10));
+        Driver?.SetScreenSize (20, 10);
 
         // Default location is centered, so 100 / 2 - 85 / 2 = 7
         Assert.Equal (new (expected, expected), d.Frame.Location);
@@ -1321,7 +1321,7 @@ public class DialogTests (ITestOutputHelper output)
             Y = 1
         };
 
-        AutoInitShutdownAttribute.FakeResize (new (20, 20));
+        Driver?.SetScreenSize (20, 20);
 
         var iterations = 0;
 
@@ -1340,7 +1340,7 @@ public class DialogTests (ITestOutputHelper output)
                          else if (iterations == 2)
                          {
                              // Mouse click outside of dialog
-                             RaiseMouseEvent (new() { Flags = MouseFlags.Button1Clicked, ScreenPosition = new (0, 0) });
+                             RaiseMouseEvent (new () { Flags = MouseFlags.Button1Clicked, ScreenPosition = new (0, 0) });
                          }
                      };
 
@@ -1370,7 +1370,7 @@ public class DialogTests (ITestOutputHelper output)
             $"{Glyphs.VLine}   {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket}   {Glyphs.VLine}";
 
         int width = buttonRow.Length;
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 10));
+        Driver?.SetScreenSize (buttonRow.Length, 10);
 
         (runState, Dialog dlg) = BeginButtonTestDialog (
                                                         title,
@@ -1435,7 +1435,7 @@ public class DialogTests (ITestOutputHelper output)
         };
 
         Begin (d);
-        AutoInitShutdownAttribute.FakeResize (new (100, 100));
+        Driver?.SetScreenSize (100, 100);
 
         // Default size is Percent(85) 
         Assert.Equal (new ((int)(100 * .85), (int)(100 * .85)), d.Frame.Size);
@@ -1451,7 +1451,7 @@ public class DialogTests (ITestOutputHelper output)
         var d = new Dialog { Width = 50, Height = 50 };
 
         Begin (d);
-        AutoInitShutdownAttribute.FakeResize (new (100, 100));
+        Driver?.SetScreenSize (100, 100);
 
         // Default size is Percent(85) 
         Assert.Equal (new (50, 50), d.Frame.Size);
@@ -1468,9 +1468,9 @@ public class DialogTests (ITestOutputHelper output)
 
         var buttonRow = $"{Glyphs.VLine}        {Glyphs.VLine}";
         int width = buttonRow.Length;
-        AutoInitShutdownAttribute.FakeResize (new (buttonRow.Length, 3));
+        Driver?.SetScreenSize (buttonRow.Length, 3);
 
-        (runState, Dialog dlg) = BeginButtonTestDialog (title, width, Alignment.Center, []);
+        (runState, Dialog dlg) = BeginButtonTestDialog (title, width, Alignment.Center);
 
         DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 

+ 7 - 7
Tests/UnitTests/Dialogs/MessageBoxTests.cs

@@ -155,7 +155,7 @@ public class MessageBoxTests
     {
         int iterations = -1;
 
-        AutoInitShutdownAttribute.FakeResize(new Size(15, 15)); // 15 x 15 gives us enough room for a button with one char (9x1)
+        Application.Driver!.SetScreenSize(15, 15); // 15 x 15 gives us enough room for a button with one char (9x1)
         Dialog.DefaultShadow = ShadowStyle.None;
         Button.DefaultShadow = ShadowStyle.None;
 
@@ -189,7 +189,7 @@ public class MessageBoxTests
         int iterations = -1;
         var top = new Toplevel ();
         top.BorderStyle = LineStyle.None;
-        AutoInitShutdownAttribute.FakeResize(new Size(20, 10));
+        Application.Driver!.SetScreenSize(20, 10);
 
         var btn =
             $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} btn {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
@@ -259,7 +259,7 @@ public class MessageBoxTests
         int iterations = -1;
         var top = new Toplevel ();
         top.BorderStyle = LineStyle.None;
-        AutoInitShutdownAttribute.FakeResize(new Size(20, 10));
+        Application.Driver!.SetScreenSize (20, 10);
 
         var btn =
             $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} btn {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
@@ -343,7 +343,7 @@ public class MessageBoxTests
     public void Size_Not_Default_Message (int height, int width, string message)
     {
         int iterations = -1;
-        AutoInitShutdownAttribute.FakeResize(new Size(100, 100));
+        Application.Driver!.SetScreenSize(100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -380,7 +380,7 @@ public class MessageBoxTests
     public void Size_Not_Default_Message_Button (int height, int width, string message)
     {
         int iterations = -1;
-        AutoInitShutdownAttribute.FakeResize(new Size(100, 100));
+        Application.Driver?.SetScreenSize(100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -413,7 +413,7 @@ public class MessageBoxTests
     public void Size_Not_Default_No_Message (int height, int width)
     {
         int iterations = -1;
-        AutoInitShutdownAttribute.FakeResize(new Size(100, 100));
+        Application.Driver?.SetScreenSize(100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -442,7 +442,7 @@ public class MessageBoxTests
     public void UICatalog_AboutBox ()
     {
         int iterations = -1;
-        AutoInitShutdownAttribute.FakeResize (new Size (70, 15));
+        Application.Driver!.SetScreenSize (70, 15);
 
         // Override CM
         MessageBox.DefaultButtonAlignment = Alignment.End;

+ 23 - 125
Tests/UnitTests/Dialogs/WizardTests.cs

@@ -1,9 +1,6 @@
-using UnitTests;
-using Xunit.Abstractions;
+namespace UnitTests.DialogTests;
 
-namespace UnitTests.DialogTests;
-
-public class WizardTests ()
+public class WizardTests
 {
     // =========== Wizard Tests
     [Fact]
@@ -43,7 +40,7 @@ public class WizardTests ()
 
         // Same test, but with two steps
         wizard = new ();
-        step1 = new() { Title = "step1" };
+        step1 = new () { Title = "step1" };
         wizard.AddStep (step1);
         WizardStep step2 = new () { Title = "step2" };
         wizard.AddStep (step2);
@@ -75,9 +72,9 @@ public class WizardTests ()
 
         // Same test, but with two steps but the 1st one disabled
         wizard = new ();
-        step1 = new() { Title = "step1" };
+        step1 = new () { Title = "step1" };
         wizard.AddStep (step1);
-        step2 = new() { Title = "step2" };
+        step2 = new () { Title = "step2" };
         wizard.AddStep (step2);
         step1.Enabled = false;
 
@@ -389,43 +386,22 @@ public class WizardTests ()
     // and that the title is correct
     public void OneStepWizard_Shows ()
     {
-
         var title = "1234";
         var stepTitle = "ABCD";
 
         var width = 30;
         var height = 7;
-        AutoInitShutdownAttribute.FakeResize (new Size (width, height));
+        Application.Driver?.SetScreenSize (width, height);
 
         //	var btnBackText = "Back";
         var btnBack = string.Empty; // $"{Glyphs.LeftBracket} {btnBackText} {Glyphs.RightBracket}";
         var btnNextText = "Finish"; // "Next";
 
         var btnNext =
-            $"{
-                Glyphs.LeftBracket
-            }{
-                Glyphs.LeftDefaultIndicator
-            } {
-                btnNextText
-            } {
-                Glyphs.RightDefaultIndicator
-            }{
-                Glyphs.RightBracket
-            }";
+            $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
 
         var topRow =
-            $"{
-                Glyphs.ULCornerDbl
-            }╡{
-                title
-            } - {
-                stepTitle
-            }╞{
-                new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 7)
-            }{
-                Glyphs.URCornerDbl
-            }";
+            $"{Glyphs.ULCornerDbl}╡{title} - {stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 7)}{Glyphs.URCornerDbl}";
         var row2 = $"{Glyphs.VLineDbl}{new (' ', width - 2)}{Glyphs.VLineDbl}";
         string row3 = row2;
         string row4 = row3;
@@ -434,29 +410,13 @@ public class WizardTests ()
             $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
 
         var buttonRow =
-            $"{
-                Glyphs.VLineDbl
-            }{
-                btnBack
-            }{
-                new (' ', width - btnBack.Length - btnNext.Length - 2)
-            }{
-                btnNext
-            }{
-                Glyphs.VLineDbl
-            }";
+            $"{Glyphs.VLineDbl}{btnBack}{new (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{Glyphs.VLineDbl}";
 
         var bottomRow =
-            $"{
-                Glyphs.LLCornerDbl
-            }{
-                new (Glyphs.HLineDbl.ToString () [0], width - 2)
-            }{
-                Glyphs.LRCornerDbl
-            }";
+            $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
 
         Wizard wizard = new () { Title = title, Width = width, Height = height };
-        wizard.AddStep (new() { Title = stepTitle });
+        wizard.AddStep (new () { Title = stepTitle });
 
         //wizard.LayoutSubViews ();
         RunState runstate = Application.Begin (wizard);
@@ -477,42 +437,22 @@ public class WizardTests ()
     // this test is needed because Wizard overrides Dialog's title behavior ("Title - StepTitle")
     public void Setting_Title_Works ()
     {
-        var d = (IConsoleDriverFacade)Application.Driver;
-        
+        var d = Application.Driver;
+
         var title = "1234";
         var stepTitle = " - ABCD";
 
         var width = 40;
         var height = 4;
-        d.OutputBuffer.SetWindowSize (width,height);
+        d.SetScreenSize (width, height);
 
         var btnNextText = "Finish";
 
         var btnNext =
-            $"{
-                Glyphs.LeftBracket
-            }{
-                Glyphs.LeftDefaultIndicator
-            } {
-                btnNextText
-            } {
-                Glyphs.RightDefaultIndicator
-            }{
-                Glyphs.RightBracket
-            }";
+            $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
 
         var topRow =
-            $"{
-                Glyphs.ULCornerDbl
-            }╡{
-                title
-            }{
-                stepTitle
-            }╞{
-                new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)
-            }{
-                Glyphs.URCornerDbl
-            }";
+            $"{Glyphs.ULCornerDbl}╡{title}{stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)}{Glyphs.URCornerDbl}";
 
         var separatorRow =
             $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
@@ -523,16 +463,10 @@ public class WizardTests ()
 
         //var buttonRow = $"{Glyphs.VDLine}{new String (' ', width - btnNext.Length - 2)}{btnNext}{Glyphs.VDLine}";
         var bottomRow =
-            $"{
-                Glyphs.LLCornerDbl
-            }{
-                new (Glyphs.HLineDbl.ToString () [0], width - 2)
-            }{
-                Glyphs.LRCornerDbl
-            }";
+            $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
 
         var wizard = new Wizard { Title = title, Width = width, Height = height };
-        wizard.AddStep (new() { Title = "ABCD" });
+        wizard.AddStep (new () { Title = "ABCD" });
 
         Application.End (Application.Begin (wizard));
         wizard.Dispose ();
@@ -646,37 +580,17 @@ public class WizardTests ()
 
         var width = 30;
         var height = 6;
-        AutoInitShutdownAttribute.FakeResize (new Size (width, height));
+        Application.Driver?.SetScreenSize (width, height);
 
         var btnBackText = "Back";
         var btnBack = $"{Glyphs.LeftBracket} {btnBackText} {Glyphs.RightBracket}";
         var btnNextText = "Finish";
 
         var btnNext =
-            $"{
-                Glyphs.LeftBracket
-            }{
-                Glyphs.LeftDefaultIndicator
-            } {
-                btnNextText
-            } {
-                Glyphs.RightDefaultIndicator
-            }{
-                Glyphs.RightBracket
-            }";
+            $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
 
         var topRow =
-            $"{
-                Glyphs.ULCornerDbl
-            }╡{
-                title
-            }{
-                stepTitle
-            }╞{
-                new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)
-            }{
-                Glyphs.URCornerDbl
-            }";
+            $"{Glyphs.ULCornerDbl}╡{title}{stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)}{Glyphs.URCornerDbl}";
         var row2 = $"{Glyphs.VLineDbl}{new (' ', width - 2)}{Glyphs.VLineDbl}";
         string row3 = row2;
 
@@ -684,26 +598,10 @@ public class WizardTests ()
             $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
 
         var buttonRow =
-            $"{
-                Glyphs.VLineDbl
-            }{
-                btnBack
-            }{
-                new (' ', width - btnBack.Length - btnNext.Length - 2)
-            }{
-                btnNext
-            }{
-                Glyphs.VLineDbl
-            }";
+            $"{Glyphs.VLineDbl}{btnBack}{new (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{Glyphs.VLineDbl}";
 
         var bottomRow =
-            $"{
-                Glyphs.LLCornerDbl
-            }{
-                new (Glyphs.HLineDbl.ToString () [0], width - 2)
-            }{
-                Glyphs.LRCornerDbl
-            }";
+            $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
 
         var wizard = new Wizard { Title = title, Width = width, Height = height };
         RunState runstate = Application.Begin (wizard);

+ 0 - 1263
Tests/UnitTests/Drawing/LineCanvasTests.cs

@@ -1,1263 +0,0 @@
-using System.Text;
-using UnitTests;
-using Xunit.Abstractions;
-
-namespace UnitTests.DrawingTests;
-
-public class LineCanvasTests (ITestOutputHelper output)
-{
-    [Theory]
-
-    // Horizontal lines with a vertical zero-length
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    "╞"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    "╡"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    "╟"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    "╢"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    "├"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    "┤"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    "╠"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    "╣"
-                )]
-
-    // Vertical lines with a horizontal zero-length
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "╥"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "╨"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╤"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╧"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "┬"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "┴"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    1,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╦"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    -1,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╩"
-                )]
-
-    // Crosses (two zero-length)
-    [InlineData (
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "╫"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╪"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Single,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Single,
-                    "┼"
-                )]
-    [InlineData (
-                    0,
-                    0,
-                    0,
-                    Orientation.Vertical,
-                    LineStyle.Double,
-                    0,
-                    0,
-                    0,
-                    Orientation.Horizontal,
-                    LineStyle.Double,
-                    "╬"
-                )]
-    public void Add_2_Lines (
-        int x1,
-        int y1,
-        int len1,
-        Orientation o1,
-        LineStyle s1,
-        int x2,
-        int y2,
-        int len2,
-        Orientation o2,
-        LineStyle s2,
-        string expected
-    )
-    {
-        View v = GetCanvas (out LineCanvas lc);
-        v.Width = 10;
-        v.Height = 10;
-        v.Viewport = new (0, 0, 10, 10);
-
-        lc.AddLine (new (x1, y1), len1, o1, s1);
-        lc.AddLine (new (x2, y2), len2, o2, s2);
-
-        OutputAssert.AssertEqual (output, expected, lc.ToString ());
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Viewport_Specific ()
-    {
-        // Draw at 1,1 within client area of View (i.e. leave a top and left margin of 1)
-        // This proves we aren't drawing excess above
-        var x = 1;
-        var y = 2;
-        var width = 3;
-        var height = 2;
-
-        var lc = new LineCanvas ();
-
-        // 01230
-        // ╔╡╞╗1
-        // ║  ║2
-
-        // Add a short horiz line for ╔╡
-        lc.AddLine (new (x, y), 2, Orientation.Horizontal, LineStyle.Double);
-        Assert.Equal (new (x, y, 2, 1), lc.Bounds);
-
-        //LHS line down
-        lc.AddLine (new (x, y), height, Orientation.Vertical, LineStyle.Double);
-        Assert.Equal (new (x, y, 2, 2), lc.Bounds);
-
-        //Vertical line before Title, results in a ╡
-        lc.AddLine (new (x + 1, y), 0, Orientation.Vertical, LineStyle.Single);
-        Assert.Equal (new (x, y, 2, 2), lc.Bounds);
-
-        //Vertical line after Title, results in a ╞
-        lc.AddLine (new (x + 2, y), 0, Orientation.Vertical, LineStyle.Single);
-        Assert.Equal (new (x, y, 3, 2), lc.Bounds);
-
-        // remainder of top line
-        lc.AddLine (new (x + 2, y), width - 1, Orientation.Horizontal, LineStyle.Double);
-        Assert.Equal (new (x, y, 4, 2), lc.Bounds);
-
-        //RHS line down
-        lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double);
-        Assert.Equal (new (x, y, 4, 2), lc.Bounds);
-
-        OutputAssert.AssertEqual (
-                                  output,
-                                  @"
-╔╡╞╗
-║  ║",
-                                  $"{Environment.NewLine}{lc}"
-                                 );
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Viewport_Specific_With_Ustring ()
-    {
-        // Draw at 1,1 within client area of View (i.e. leave a top and left margin of 1)
-        // This proves we aren't drawing excess above
-        var x = 1;
-        var y = 2;
-        var width = 3;
-        var height = 2;
-
-        var lc = new LineCanvas ();
-
-        // 01230
-        // ╔╡╞╗1
-        // ║  ║2
-
-        // Add a short horiz line for ╔╡
-        lc.AddLine (new (x, y), 2, Orientation.Horizontal, LineStyle.Double);
-        Assert.Equal (new (x, y, 2, 1), lc.Bounds);
-
-        //LHS line down
-        lc.AddLine (new (x, y), height, Orientation.Vertical, LineStyle.Double);
-        Assert.Equal (new (x, y, 2, 2), lc.Bounds);
-
-        //Vertical line before Title, results in a ╡
-        lc.AddLine (new (x + 1, y), 0, Orientation.Vertical, LineStyle.Single);
-        Assert.Equal (new (x, y, 2, 2), lc.Bounds);
-
-        //Vertical line after Title, results in a ╞
-        lc.AddLine (new (x + 2, y), 0, Orientation.Vertical, LineStyle.Single);
-        Assert.Equal (new (x, y, 3, 2), lc.Bounds);
-
-        // remainder of top line
-        lc.AddLine (new (x + 2, y), width - 1, Orientation.Horizontal, LineStyle.Double);
-        Assert.Equal (new (x, y, 4, 2), lc.Bounds);
-
-        //RHS line down
-        lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double);
-        Assert.Equal (new (x, y, 4, 2), lc.Bounds);
-
-        OutputAssert.AssertEqual (
-                                  output,
-                                  @"
-╔╡╞╗
-║  ║",
-                                  $"{Environment.NewLine}{lc}"
-                                 );
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Canvas_Updates_On_Changes ()
-    {
-        var lc = new LineCanvas ();
-
-        Assert.Equal (Rectangle.Empty, lc.Bounds);
-
-        lc.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Double);
-        Assert.NotEqual (Rectangle.Empty, lc.Bounds);
-
-        lc.Clear ();
-        Assert.Equal (Rectangle.Empty, lc.Bounds);
-    }
-
-    [InlineData (0, 0, Orientation.Horizontal, "─")]
-    [InlineData (1, 0, Orientation.Horizontal, "─")]
-    [InlineData (0, 1, Orientation.Horizontal, "─")]
-    [InlineData (-1, 0, Orientation.Horizontal, "─")]
-    [InlineData (0, -1, Orientation.Horizontal, "─")]
-    [InlineData (-1, -1, Orientation.Horizontal, "─")]
-    [InlineData (0, 0, Orientation.Vertical, "│")]
-    [InlineData (1, 0, Orientation.Vertical, "│")]
-    [InlineData (0, 1, Orientation.Vertical, "│")]
-    [InlineData (0, -1, Orientation.Vertical, "│")]
-    [InlineData (-1, 0, Orientation.Vertical, "│")]
-    [InlineData (-1, -1, Orientation.Vertical, "│")]
-    [Theory]
-    [SetupFakeDriver]
-    public void Length_0_Is_1_Long (int x, int y, Orientation orientation, string expected)
-    {
-        var canvas = new LineCanvas ();
-
-        // Add a line at 5, 5 that's has length of 1
-        canvas.AddLine (new (x, y), 1, orientation, LineStyle.Single);
-        OutputAssert.AssertEqual (output, $"{expected}", $"{canvas}");
-    }
-
-    // X is offset by 2
-    [InlineData (0, 0, 1, Orientation.Horizontal, "─")]
-    [InlineData (1, 0, 1, Orientation.Horizontal, "─")]
-    [InlineData (0, 1, 1, Orientation.Horizontal, "─")]
-    [InlineData (0, 0, 1, Orientation.Vertical, "│")]
-    [InlineData (1, 0, 1, Orientation.Vertical, "│")]
-    [InlineData (0, 1, 1, Orientation.Vertical, "│")]
-    [InlineData (-1, 0, 1, Orientation.Horizontal, "─")]
-    [InlineData (0, -1, 1, Orientation.Horizontal, "─")]
-    [InlineData (-1, 0, 1, Orientation.Vertical, "│")]
-    [InlineData (0, -1, 1, Orientation.Vertical, "│")]
-    [InlineData (0, 0, -1, Orientation.Horizontal, "─")]
-    [InlineData (1, 0, -1, Orientation.Horizontal, "─")]
-    [InlineData (0, 1, -1, Orientation.Horizontal, "─")]
-    [InlineData (0, 0, -1, Orientation.Vertical, "│")]
-    [InlineData (1, 0, -1, Orientation.Vertical, "│")]
-    [InlineData (0, 1, -1, Orientation.Vertical, "│")]
-    [InlineData (-1, 0, -1, Orientation.Horizontal, "─")]
-    [InlineData (0, -1, -1, Orientation.Horizontal, "─")]
-    [InlineData (-1, 0, -1, Orientation.Vertical, "│")]
-    [InlineData (0, -1, -1, Orientation.Vertical, "│")]
-    [InlineData (0, 0, 2, Orientation.Horizontal, "──")]
-    [InlineData (1, 0, 2, Orientation.Horizontal, "──")]
-    [InlineData (0, 1, 2, Orientation.Horizontal, "──")]
-    [InlineData (1, 1, 2, Orientation.Horizontal, "──")]
-    [InlineData (0, 0, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (1, 0, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (0, 1, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (1, 1, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (-1, 0, 2, Orientation.Horizontal, "──")]
-    [InlineData (0, -1, 2, Orientation.Horizontal, "──")]
-    [InlineData (-1, 0, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (0, -1, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (-1, -1, 2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (0, 0, -2, Orientation.Horizontal, "──")]
-    [InlineData (1, 0, -2, Orientation.Horizontal, "──")]
-    [InlineData (0, 1, -2, Orientation.Horizontal, "──")]
-    [InlineData (0, 0, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (1, 0, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (0, 1, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (1, 1, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (-1, 0, -2, Orientation.Horizontal, "──")]
-    [InlineData (0, -1, -2, Orientation.Horizontal, "──")]
-    [InlineData (-1, 0, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (0, -1, -2, Orientation.Vertical, "│\r\n│")]
-    [InlineData (-1, -1, -2, Orientation.Vertical, "│\r\n│")]
-    [Theory]
-    [SetupFakeDriver]
-    public void Length_n_Is_n_Long (int x, int y, int length, Orientation orientation, string expected)
-    {
-        var canvas = new LineCanvas ();
-        canvas.AddLine (new (x, y), length, orientation, LineStyle.Single);
-
-        var result = canvas.ToString ();
-        OutputAssert.AssertEqual (output, expected, result);
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Length_Negative ()
-    {
-        var offset = new Point (5, 5);
-
-        var canvas = new LineCanvas ();
-        canvas.AddLine (offset, -3, Orientation.Horizontal, LineStyle.Single);
-
-        var looksLike = "───";
-
-        Assert.Equal (looksLike, $"{canvas}");
-    }
-
-    [InlineData (Orientation.Horizontal, "─")]
-    [InlineData (Orientation.Vertical, "│")]
-    [Theory]
-    [SetupFakeDriver]
-    public void Length_Zero_Alone_Is_Line (Orientation orientation, string expected)
-    {
-        var lc = new LineCanvas ();
-
-        // Add a line at 0, 0 that's has length of 0
-        lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        OutputAssert.AssertEqual (output, expected, $"{lc}");
-    }
-
-    [InlineData (Orientation.Horizontal, "┼")]
-    [InlineData (Orientation.Vertical, "┼")]
-    [Theory]
-    [SetupFakeDriver]
-    public void Length_Zero_Cross_Is_Cross (Orientation orientation, string expected)
-    {
-        var lc = new LineCanvas ();
-
-        // Add point at opposite orientation
-        lc.AddLine (
-                    Point.Empty,
-                    0,
-                    orientation == Orientation.Horizontal ? Orientation.Vertical : Orientation.Horizontal,
-                    LineStyle.Single
-                   );
-
-        // Add a line at 0, 0 that's has length of 0
-        lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        OutputAssert.AssertEqual (output, expected, $"{lc}");
-    }
-
-    [InlineData (Orientation.Horizontal, "╥")]
-    [InlineData (Orientation.Vertical, "╞")]
-    [Theory]
-    [SetupFakeDriver]
-    public void Length_Zero_NextTo_Opposite_Is_T (Orientation orientation, string expected)
-    {
-        var lc = new LineCanvas ();
-
-        // Add line with length of 1 in opposite orientation starting at same location
-        if (orientation == Orientation.Horizontal)
-        {
-            lc.AddLine (Point.Empty, 1, Orientation.Vertical, LineStyle.Double);
-        }
-        else
-        {
-            lc.AddLine (Point.Empty, 1, Orientation.Horizontal, LineStyle.Double);
-        }
-
-        // Add a line at 0, 0 that's has length of 0
-        lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        OutputAssert.AssertEqual (output, expected, $"{lc}");
-    }
-
-    [Fact]
-    public void TestLineCanvas_LeaveMargin_Top1_Left1 ()
-    {
-        var canvas = new LineCanvas ();
-
-        // Upper box
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (Point.Empty, 2, Orientation.Vertical, LineStyle.Single);
-
-        var looksLike =
-            @"
-┌─
-│ ";
-        OutputAssert.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void TestLineCanvas_Window_Heavy ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Heavy);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Heavy);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Heavy);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Heavy);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Heavy);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Heavy);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-┏━━━━┳━━━┓
-┃    ┃   ┃
-┣━━━━╋━━━┫
-┃    ┃   ┃
-┗━━━━┻━━━┛";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Theory]
-    [SetupFakeDriver]
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    public void TestLineCanvas_Window_HeavyTop_ThinSides (LineStyle thinStyle)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Heavy);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, thinStyle);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Heavy);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, thinStyle);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, thinStyle);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Heavy);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-┍━━━━┯━━━┑
-│    │   │
-┝━━━━┿━━━┥
-│    │   │
-┕━━━━┷━━━┙
-";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Theory]
-    [SetupFakeDriver]
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    public void TestLineCanvas_Window_ThinTop_HeavySides (LineStyle thinStyle)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, thinStyle);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Heavy);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, thinStyle);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Heavy);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Heavy);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, thinStyle);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-┎────┰───┒
-┃    ┃   ┃
-┠────╂───┨
-┃    ┃   ┃
-┖────┸───┚
-
-";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Top_Left_From_TopRight_LeftUp ()
-    {
-        var canvas = new LineCanvas ();
-
-        // Upper box
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (new (0, 1), -2, Orientation.Vertical, LineStyle.Single);
-
-        var looksLike =
-            @"
-┌─
-│ ";
-        OutputAssert.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Top_With_1Down ()
-    {
-        var canvas = new LineCanvas ();
-
-        // Top      ─  
-        canvas.AddLine (Point.Empty, 1, Orientation.Horizontal, LineStyle.Single);
-
-        // Bottom   ─
-        canvas.AddLine (new (1, 1), -1, Orientation.Horizontal, LineStyle.Single);
-
-        //// Right down
-        //canvas.AddLine (new Point (9, 0), 3, Orientation.Vertical, LineStyle.Single);
-
-        //// Bottom
-        //canvas.AddLine (new Point (9, 3), -10, Orientation.Horizontal, LineStyle.Single);
-
-        //// Left Up
-        //canvas.AddLine (new Point (0, 3), -3, Orientation.Vertical, LineStyle.Single);
-
-        Assert.Equal (new (0, 0, 2, 2), canvas.Bounds);
-
-        Dictionary<Point, Rune> map = canvas.GetMap ();
-        Assert.Equal (2, map.Count);
-
-        OutputAssert.AssertEqual (
-                                  output,
-                                  @"
-─ 
- ─",
-                                  $"{Environment.NewLine}{canvas}"
-                                 );
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void ToString_Empty ()
-    {
-        var lc = new LineCanvas ();
-        OutputAssert.AssertEqual (output, string.Empty, lc.ToString ());
-    }
-
-    //                  012
-    [InlineData (0, 0, "═══")]
-    [InlineData (1, 0, "═══")]
-    [InlineData (0, 1, "═══")]
-    [InlineData (1, 1, "═══")]
-    [InlineData (2, 2, "═══")]
-    [InlineData (-1, 0, "═══")]
-    [InlineData (0, -1, "═══")]
-    [InlineData (-1, -1, "═══")]
-    [InlineData (-2, -2, "═══")]
-    [Theory]
-    [SetupFakeDriver]
-    public void ToString_Positive_Horizontal_1Line_Offset (int x, int y, string expected)
-    {
-        var lc = new LineCanvas ();
-        lc.AddLine (new (x, y), 3, Orientation.Horizontal, LineStyle.Double);
-        OutputAssert.AssertEqual (output, expected, $"{lc}");
-    }
-
-    [InlineData (0, 0, 0, 0, "═══")]
-    [InlineData (1, 0, 1, 0, "═══")]
-    [InlineData (-1, 0, -1, 0, "═══")]
-    [InlineData (0, 0, 1, 0, "════")]
-    [InlineData (1, 0, 3, 0, "═════")]
-    [InlineData (1, 0, 4, 0, "══════")]
-    [InlineData (1, 0, 5, 0, "═══ ═══")]
-    [InlineData (0, 0, 0, 1, "\u2550\u2550\u2550\r\n\u2550\u2550\u2550")]
-    [InlineData (0, 0, 1, 1, "═══ \r\n ═══")]
-    [InlineData (0, 0, 2, 1, "═══  \r\n  ═══")]
-    [InlineData (1, 0, 0, 1, " ═══\r\n═══ ")]
-    [InlineData (0, 1, 0, 1, "═══")]
-    [InlineData (1, 1, 0, 1, "════")]
-    [InlineData (2, 2, 0, 1, "═══  \r\n  ═══")]
-    [Theory]
-    [SetupFakeDriver]
-    public void ToString_Positive_Horizontal_2Line_Offset (int x1, int y1, int x2, int y2, string expected)
-    {
-        var lc = new LineCanvas ();
-        lc.AddLine (new (x1, y1), 3, Orientation.Horizontal, LineStyle.Double);
-        lc.AddLine (new (x2, y2), 3, Orientation.Horizontal, LineStyle.Double);
-
-        OutputAssert.AssertEqual (output, expected, $"{lc}");
-    }
-
-    //		[Fact, SetupFakeDriver]
-    //		public void LeaveMargin_Top1_Left1 ()
-    //		{
-    //			var canvas = new LineCanvas ();
-
-    //			// Upper box
-    //			canvas.AddLine (Point.Empty, 9, Orientation.Horizontal, LineStyle.Single);
-    //			canvas.AddLine (new Point (8, 0), 3, Orientation.Vertical, LineStyle.Single);
-    //			canvas.AddLine (new Point (8, 3), -9, Orientation.Horizontal, LineStyle.Single);
-    //			canvas.AddLine (new Point (0, 2), -3, Orientation.Vertical, LineStyle.Single);
-
-    //			// Lower Box
-    //			canvas.AddLine (new Point (5, 0), 2, Orientation.Vertical, LineStyle.Single);
-    //			canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, LineStyle.Single);
-
-    //			string looksLike =
-    //@"
-    //┌────┬──┐
-    //│    │  │
-    //├────┼──┤
-    //└────┴──┘
-    //";
-    //			Assert.Equal (looksLike, $"{Environment.NewLine}{canvas}");
-    //		}
-
-    [InlineData (0, 0, 0, Orientation.Horizontal, LineStyle.Double, "═")]
-    [InlineData (0, 0, 0, Orientation.Vertical, LineStyle.Double, "║")]
-    [InlineData (0, 0, 0, Orientation.Horizontal, LineStyle.Single, "─")]
-    [InlineData (0, 0, 0, Orientation.Vertical, LineStyle.Single, "│")]
-    [InlineData (0, 0, 1, Orientation.Horizontal, LineStyle.Double, "═")]
-    [InlineData (0, 0, 1, Orientation.Vertical, LineStyle.Double, "║")]
-    [InlineData (0, 0, 1, Orientation.Horizontal, LineStyle.Single, "─")]
-    [InlineData (0, 0, 1, Orientation.Vertical, LineStyle.Single, "│")]
-    [InlineData (0, 0, 2, Orientation.Horizontal, LineStyle.Double, "══")]
-    [InlineData (0, 0, 2, Orientation.Vertical, LineStyle.Double, "║\n║")]
-    [InlineData (0, 0, 2, Orientation.Horizontal, LineStyle.Single, "──")]
-    [InlineData (0, 0, 2, Orientation.Vertical, LineStyle.Single, "│\n│")]
-    [SetupFakeDriver]
-    [Theory]
-    public void View_Draws_1LineTests (
-        int x1,
-        int y1,
-        int length,
-        Orientation o1,
-        LineStyle s1,
-        string expected
-    )
-    {
-        View v = GetCanvas (out LineCanvas lc);
-        v.Width = 10;
-        v.Height = 10;
-        v.Viewport = new (0, 0, 10, 10);
-
-        lc.AddLine (new (x1, y1), length, o1, s1);
-
-        v.Draw ();
-
-        DriverAssert.AssertDriverContentsAre (expected, output);
-        v.Dispose ();
-    }
-
-    /// <summary>This test demonstrates how to correctly trigger a corner.  By overlapping the lines in the same cell</summary>
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Corner_Correct ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (Point.Empty, 2, Orientation.Vertical, LineStyle.Single);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-┌─
-│";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    /// <summary>
-    ///     This test demonstrates that corners are only drawn when lines overlap. Not when they terminate adjacent to one
-    ///     another.
-    /// </summary>
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Corner_NoOverlap ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (new (0, 1), 2, Orientation.Vertical, LineStyle.Single);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-──
-│
-│";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    [Theory]
-    [SetupFakeDriver]
-    public void View_Draws_Horizontal (LineStyle style)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, style);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-──";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Horizontal_Double ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Double);
-
-        v.Draw ();
-
-        var looksLike =
-            @" 
-══";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    [Theory]
-    [SetupFakeDriver]
-    public void View_Draws_Vertical (LineStyle style)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Vertical, style);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-│
-│";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Vertical_Double ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-        canvas.AddLine (Point.Empty, 2, Orientation.Vertical, LineStyle.Double);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-║
-║";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Window_Double ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Double);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Double);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Double);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Double);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Double);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Double);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-╔════╦═══╗
-║    ║   ║
-╠════╬═══╣
-║    ║   ║
-╚════╩═══╝";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Theory]
-    [SetupFakeDriver]
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    public void View_Draws_Window_DoubleTop_SingleSides (LineStyle thinStyle)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Double);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, thinStyle);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Double);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, thinStyle);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, thinStyle);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Double);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-╒════╤═══╕
-│    │   │
-╞════╪═══╡
-│    │   │
-╘════╧═══╛
-";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    /// <summary>
-    ///     Demonstrates when <see cref="LineStyle.Rounded"/> corners are used. Notice how not all lines declare rounded.
-    ///     If there are 1+ lines intersecting and a corner is to be used then if any of them are rounded a rounded corner is
-    ///     used.
-    /// </summary>
-    [Fact]
-    [SetupFakeDriver]
-    public void View_Draws_Window_Rounded ()
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Rounded);
-
-        // LineStyle.Single is ignored because corner overlaps with the above line which is Rounded
-        // this results in a rounded corner being used.
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Single);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Rounded);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Single);
-
-        // These lines say rounded but they will result in the T sections which are never rounded.
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Rounded);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Rounded);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-╭────┬───╮
-│    │   │
-├────┼───┤
-│    │   │
-╰────┴───╯";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Theory]
-    [InlineData (LineStyle.Single)]
-    [InlineData (LineStyle.Rounded)]
-    [SetupFakeDriver]
-    public void View_Draws_Window_SingleTop_DoubleSides (LineStyle thinStyle)
-    {
-        View v = GetCanvas (out LineCanvas canvas);
-
-        // outer box
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, thinStyle);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Double);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, thinStyle);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Double);
-
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Double);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, thinStyle);
-
-        v.Draw ();
-
-        var looksLike =
-            @"    
-╓────╥───╖
-║    ║   ║
-╟────╫───╢
-║    ║   ║
-╙────╨───╜
-
-";
-        DriverAssert.AssertDriverContentsAre (looksLike, output);
-        v.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Window ()
-    {
-        var canvas = new LineCanvas ();
-
-        // Frame
-        canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (new (9, 0), 5, Orientation.Vertical, LineStyle.Single);
-        canvas.AddLine (new (9, 4), -10, Orientation.Horizontal, LineStyle.Single);
-        canvas.AddLine (new (0, 4), -5, Orientation.Vertical, LineStyle.Single);
-
-        // Cross
-        canvas.AddLine (new (5, 0), 5, Orientation.Vertical, LineStyle.Single);
-        canvas.AddLine (new (0, 2), 10, Orientation.Horizontal, LineStyle.Single);
-
-        var looksLike =
-            @"
-┌────┬───┐
-│    │   │
-├────┼───┤
-│    │   │
-└────┴───┘";
-        OutputAssert.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Zero_Length_Intersections ()
-    {
-        // Draw at 1,2 within client area of View (i.e. leave a top and left margin of 1)
-        // This proves we aren't drawing excess above
-        var x = 1;
-        var y = 2;
-        var width = 5;
-        var height = 2;
-
-        var lc = new LineCanvas ();
-
-        // ╔╡╞═════╗
-        // Add a short horiz line for ╔╡
-        lc.AddLine (new (x, y), 2, Orientation.Horizontal, LineStyle.Double);
-
-        //LHS line down
-        lc.AddLine (new (x, y), height, Orientation.Vertical, LineStyle.Double);
-
-        //Vertical line before Title, results in a ╡
-        lc.AddLine (new (x + 1, y), 0, Orientation.Vertical, LineStyle.Single);
-
-        //Vertical line after Title, results in a ╞
-        lc.AddLine (new (x + 2, y), 0, Orientation.Vertical, LineStyle.Single);
-
-        // remainder of top line
-        lc.AddLine (new (x + 2, y), width - 1, Orientation.Horizontal, LineStyle.Double);
-
-        //RHS line down
-        lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double);
-
-        var looksLike = @"
-╔╡╞══╗
-║    ║";
-        OutputAssert.AssertEqual (output, looksLike, $"{Environment.NewLine}{lc}");
-    }
-
-    [Fact]
-    public void LineCanvas_UsesFillCorrectly ()
-    {
-        // Arrange
-        var foregroundColor = new Color (255, 0); // Red
-        var backgroundColor = new Color (0, 0); // Black
-        var foregroundFill = new SolidFill (foregroundColor);
-        var backgroundFill = new SolidFill (backgroundColor);
-        var fillPair = new FillPair (foregroundFill, backgroundFill);
-
-        var lineCanvas = new LineCanvas
-        {
-            Fill = fillPair
-        };
-
-        // Act
-        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
-        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
-
-        // Assert
-        foreach (Cell? cell in cellMap.Values)
-        {
-            Assert.NotNull (cell);
-            Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);
-            Assert.Equal (backgroundColor, cell.Value.Attribute.Value.Background);
-        }
-    }
-
-    [Fact]
-    public void LineCanvas_LineColorIgnoredBecauseOfFill ()
-    {
-        // Arrange
-        var foregroundColor = new Color (255, 0); // Red
-        var backgroundColor = new Color (0, 0); // Black
-        var lineColor = new Attribute (new Color (0, 255), new Color (255, 255, 255)); // Green on White
-        var foregroundFill = new SolidFill (foregroundColor);
-        var backgroundFill = new SolidFill (backgroundColor);
-        var fillPair = new FillPair (foregroundFill, backgroundFill);
-
-        var lineCanvas = new LineCanvas
-        {
-            Fill = fillPair
-        };
-
-        // Act
-        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single, lineColor);
-        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
-
-        // Assert
-        foreach (Cell? cell in cellMap.Values)
-        {
-            Assert.NotNull (cell);
-            Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);
-            Assert.Equal (backgroundColor, cell.Value.Attribute.Value.Background);
-        }
-    }
-
-    [Fact]
-    public void LineCanvas_IntersectingLinesUseFillCorrectly ()
-    {
-        // Arrange
-        var foregroundColor = new Color (255, 0); // Red
-        var backgroundColor = new Color (0, 0); // Black
-        var foregroundFill = new SolidFill (foregroundColor);
-        var backgroundFill = new SolidFill (backgroundColor);
-        var fillPair = new FillPair (foregroundFill, backgroundFill);
-
-        var lineCanvas = new LineCanvas
-        {
-            Fill = fillPair
-        };
-
-        // Act
-        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
-        lineCanvas.AddLine (new (2, -2), 5, Orientation.Vertical, LineStyle.Single);
-        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
-
-        // Assert
-        foreach (Cell? cell in cellMap.Values)
-        {
-            Assert.NotNull (cell);
-            Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);
-            Assert.Equal (backgroundColor, cell.Value.Attribute.Value.Background);
-        }
-    }
-
-    // TODO: Remove this and make all LineCanvas tests independent of View
-    /// <summary>
-    ///     Creates a new <see cref="View"/> into which a <see cref="LineCanvas"/> is rendered at
-    ///     <see cref="View.DrawComplete"/> time.
-    /// </summary>
-    /// <param name="canvas">The <see cref="LineCanvas"/> you can draw into.</param>
-    /// <param name="offsetX">How far to offset drawing in X</param>
-    /// <param name="offsetY">How far to offset drawing in Y</param>
-    /// <returns></returns>
-    private View GetCanvas (out LineCanvas canvas, int offsetX = 0, int offsetY = 0)
-    {
-        var v = new View { Width = 10, Height = 5, Viewport = new (0, 0, 10, 5) };
-
-        LineCanvas canvasCopy = canvas = new ();
-
-        v.DrawComplete += (s, e) =>
-                          {
-                              v.FillRect (v.Viewport);
-
-                              foreach (KeyValuePair<Point, Rune> p in canvasCopy.GetMap ())
-                              {
-                                  v.AddRune (
-                                             offsetX + p.Key.X,
-                                             offsetY + p.Key.Y,
-                                             p.Value
-                                            );
-                              }
-
-                              canvasCopy.Clear ();
-                          };
-
-        return v;
-    }
-}

+ 0 - 142
Tests/UnitTests/Drawing/RulerTests.cs

@@ -1,142 +0,0 @@
-using UnitTests;
-using Xunit.Abstractions;
-
-namespace UnitTests.DrawingTests;
-
-public class RulerTests
-{
-    private readonly ITestOutputHelper _output;
-    public RulerTests (ITestOutputHelper output) { _output = output; }
-
-    [Fact]
-    [AutoInitShutdown]
-    public void Draw_Default ()
-    {
-        AutoInitShutdownAttribute.FakeResize(new Size(25, 25));
-
-        var r = new Ruler ();
-        r.Draw (Point.Empty);
-        DriverAssert.AssertDriverContentsWithFrameAre (@"", _output);
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Draw_Horizontal ()
-    {
-        var len = 15;
-
-        var r = new Ruler ();
-        Assert.Equal (Orientation.Horizontal, r.Orientation);
-
-        r.Length = len;
-        r.Draw (Point.Empty);
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-|123456789|1234",
-                                                       _output
-                                                      );
-
-        // Postive offset
-        r.Draw (new (1, 1));
-
-        DriverAssert.AssertDriverContentsAre (
-                                              @"
-|123456789|1234
- |123456789|1234
-",
-                                              _output
-                                             );
-
-        // Negative offset
-        r.Draw (new (-1, 3));
-
-        DriverAssert.AssertDriverContentsAre (
-                                              @"
-|123456789|1234
- |123456789|1234
-123456789|1234
-",
-                                              _output
-                                             );
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Draw_Vertical ()
-    {
-        var len = 15;
-
-        var r = new Ruler ();
-        r.Orientation = Orientation.Vertical;
-        r.Length = len;
-        r.Draw (Point.Empty);
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
--
-1
-2
-3
-4
-5
-6
-7
-8
-9
--
-1
-2
-3
-4",
-                                                       _output
-                                                      );
-
-        r.Draw (new (1, 1));
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-- 
-1-
-21
-32
-43
-54
-65
-76
-87
-98
--9
-1-
-21
-32
-43
- 4",
-                                                       _output
-                                                      );
-
-        // Negative offset
-        r.Draw (new (2, -1));
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-- 1
-1-2
-213
-324
-435
-546
-657
-768
-879
-98-
--91
-1-2
-213
-324
-43 
- 4 ",
-                                                       _output
-                                                      );
-    }
-}

+ 0 - 255
Tests/UnitTests/Drawing/ThicknessTests.cs

@@ -1,255 +0,0 @@
-using System.Text;
-using UnitTests;
-using Xunit.Abstractions;
-
-namespace UnitTests.DrawingTests;
-
-public class ThicknessTests (ITestOutputHelper output)
-{
-    [Fact]
-    [AutoInitShutdown]
-    public void DrawTests ()
-    {
-        AutoInitShutdownAttribute.FakeResize(new Size(60, 60));
-        var t = new Thickness (0, 0, 0, 0);
-        var r = new Rectangle (5, 5, 40, 15);
-
-        Application.Driver?.FillRect (
-                                      new (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
-                                      (Rune)' '
-                                     );
-        t.Draw (r, ViewDiagnosticFlags.Thickness, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-       Test (Left=0,Top=0,Right=0,Bottom=0)",
-                                                       output
-                                                      );
-
-        t = new (1, 1, 1, 1);
-        r = new (5, 5, 40, 15);
-
-        Application.Driver?.FillRect (
-                                      new (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
-                                      (Rune)' '
-                                     );
-        t.Draw (r, ViewDiagnosticFlags.Thickness, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     T                                      T
-     TTTest (Left=1,Top=1,Right=1,Bottom=1)TT",
-                                                       output
-                                                      );
-
-        t = new (1, 2, 3, 4);
-        r = new (5, 5, 40, 15);
-
-        Application.Driver?.FillRect (
-                                      new (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
-                                      (Rune)' '
-                                     );
-        t.Draw (r, ViewDiagnosticFlags.Thickness, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     T                                    TTT
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-     TTTest (Left=1,Top=2,Right=3,Bottom=4)TT",
-                                                       output
-                                                      );
-
-        t = new (-1, 1, 1, 1);
-        r = new (5, 5, 40, 15);
-
-        Application.Driver?.FillRect (
-                                      new (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
-                                      (Rune)' '
-                                     );
-        t.Draw (r, ViewDiagnosticFlags.Thickness, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-     TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-                                            T
-     TTest (Left=-1,Top=1,Right=1,Bottom=1)TT",
-                                                       output
-                                                      );
-    }
-
-    [Fact]
-    [AutoInitShutdown]
-    public void DrawTests_Ruler ()
-    {
-        // Add a frame so we can see the ruler
-        var f = new FrameView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single};
-
-        var top = new Toplevel ();
-        top.Add (f);
-        RunState rs = Application.Begin (top);
-
-        AutoInitShutdownAttribute.FakeResize(new Size(45, 20));
-        var t = new Thickness (0, 0, 0, 0);
-        var r = new Rectangle (2, 2, 40, 15);
-
-        AutoInitShutdownAttribute.RunIteration ();
-
-        t.Draw (r, ViewDiagnosticFlags.Ruler, "Test");
-
-        DriverAssert.AssertDriverContentsAre (
-                                              @"
-┌───────────────────────────────────────────┐
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-└───────────────────────────────────────────┘",
-                                              output
-                                             );
-
-        t = new (1, 1, 1, 1);
-        r = new (1, 1, 40, 15);
-        top.SetNeedsDraw ();
-        AutoInitShutdownAttribute.RunIteration ();
-        t.Draw (r, ViewDiagnosticFlags.Ruler, "Test");
-
-        DriverAssert.AssertDriverContentsAre (
-                                              @"
-┌───────────────────────────────────────────┐
-│|123456789|123456789|123456789|123456789   │
-│1                                      1   │
-│2                                      2   │
-│3                                      3   │
-│4                                      4   │
-│5                                      5   │
-│6                                      6   │
-│7                                      7   │
-│8                                      8   │
-│9                                      9   │
-│-                                      -   │
-│1                                      1   │
-│2                                      2   │
-│3                                      3   │
-│|123456789|123456789|123456789|123456789   │
-│                                           │
-│                                           │
-│                                           │
-└───────────────────────────────────────────┘",
-                                              output
-                                             );
-
-        t = new (1, 2, 3, 4);
-        r = new (2, 2, 40, 15);
-        top.SetNeedsDraw ();
-        AutoInitShutdownAttribute.RunIteration ();
-        t.Draw (r, ViewDiagnosticFlags.Ruler, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-┌───────────────────────────────────────────┐
-│                                           │
-│ |123456789|123456789|123456789|123456789  │
-│ 1                                      1  │
-│ 2                                      2  │
-│ 3                                      3  │
-│ 4                                      4  │
-│ 5                                      5  │
-│ 6                                      6  │
-│ 7                                      7  │
-│ 8                                      8  │
-│ 9                                      9  │
-│ -                                      -  │
-│ 1                                      1  │
-│ 2                                      2  │
-│ 3                                      3  │
-│ |123456789|123456789|123456789|123456789  │
-│                                           │
-│                                           │
-└───────────────────────────────────────────┘",
-                                                       output
-                                                      );
-
-        t = new (-1, 1, 1, 1);
-        r = new (5, 5, 40, 15);
-        top.SetNeedsDraw ();
-        AutoInitShutdownAttribute.RunIteration ();
-        t.Draw (r, ViewDiagnosticFlags.Ruler, "Test");
-
-        DriverAssert.AssertDriverContentsWithFrameAre (
-                                                       @"
-┌───────────────────────────────────────────┐
-│                                           │
-│                                           │
-│                                           │
-│                                           │
-│    |123456789|123456789|123456789|123456789
-│                                           1
-│                                           2
-│                                           3
-│                                           4
-│                                           5
-│                                           6
-│                                           7
-│                                           8
-│                                           9
-│                                           -
-│                                           1
-│                                           2
-│                                           3
-└────|123456789|123456789|123456789|123456789",
-                                                       output
-                                                      );
-        top.Dispose ();
-    }
-}

+ 18 - 19
Tests/UnitTests/DriverAssert.cs

@@ -1,4 +1,5 @@
-using System.Text;
+#nullable enable
+using System.Text;
 using System.Text.RegularExpressions;
 using Xunit.Abstractions;
 
@@ -9,8 +10,9 @@ namespace UnitTests;
 /// </summary>
 internal partial class DriverAssert
 {
-    private const char SpaceChar = ' ';
-    private static readonly Rune SpaceRune = (Rune)SpaceChar;
+    private const char SPACE_CHAR = ' ';
+    private static readonly Rune _spaceRune = (Rune)SPACE_CHAR;
+
 #pragma warning disable xUnit1013 // Public method should be marked as test
     /// <summary>
     ///     Verifies <paramref name="expectedAttributes"/> are found at the locations specified by
@@ -28,7 +30,7 @@ internal partial class DriverAssert
     public static void AssertDriverAttributesAre (
         string expectedLook,
         ITestOutputHelper output,
-        IConsoleDriver driver = null,
+        IConsoleDriver? driver = null,
         params Attribute [] expectedAttributes
     )
     {
@@ -42,7 +44,7 @@ internal partial class DriverAssert
         expectedLook = expectedLook.Trim ();
         driver ??= Application.Driver;
 
-        Cell [,] contents = driver!.Contents;
+        Cell [,] contents = driver!.Contents!;
 
         var line = 0;
 
@@ -107,7 +109,6 @@ internal partial class DriverAssert
 
                     //            // get the index of the actual attribute in `expectedAttributes`
 
-
                     //            if (index == -1)
                     //            {
                     //                sb.Append ("x:x ");
@@ -146,7 +147,7 @@ internal partial class DriverAssert
     public static void AssertDriverContentsAre (
         string expectedLook,
         ITestOutputHelper output,
-        IConsoleDriver driver = null,
+        IConsoleDriver? driver = null,
         bool ignoreLeadingWhitespace = false
     )
     {
@@ -192,18 +193,19 @@ internal partial class DriverAssert
     public static Rectangle AssertDriverContentsWithFrameAre (
         string expectedLook,
         ITestOutputHelper output,
-        IConsoleDriver driver = null
+        IConsoleDriver? driver = null
     )
     {
-        List<List<Rune>> lines = new ();
+        List<List<Rune>> lines = [];
         var sb = new StringBuilder ();
         driver ??= Application.Driver;
+
         int x = -1;
         int y = -1;
         int w = -1;
         int h = -1;
 
-        Cell [,] contents = driver.Contents;
+        Cell [,] contents = driver!.Contents!;
 
         for (var rowIndex = 0; rowIndex < driver.Rows; rowIndex++)
         {
@@ -211,9 +213,9 @@ internal partial class DriverAssert
 
             for (var colIndex = 0; colIndex < driver.Cols; colIndex++)
             {
-                Rune runeAtCurrentLocation = contents [rowIndex, colIndex].Rune;
+                Rune runeAtCurrentLocation = contents! [rowIndex, colIndex].Rune;
 
-                if (runeAtCurrentLocation != SpaceRune)
+                if (runeAtCurrentLocation != _spaceRune)
                 {
                     if (x == -1)
                     {
@@ -222,7 +224,7 @@ internal partial class DriverAssert
 
                         for (var i = 0; i < colIndex; i++)
                         {
-                            runes.InsertRange (i, [SpaceRune]);
+                            runes.InsertRange (i, [_spaceRune]);
                         }
                     }
 
@@ -330,7 +332,6 @@ internal partial class DriverAssert
         return new (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0);
     }
 
-
     /// <summary>
     ///     Verifies the console used all the <paramref name="expectedColors"/> when rendering. If one or more of the
     ///     expected colors are not used then the failure will output both the colors that were found to be used and which of
@@ -338,17 +339,17 @@ internal partial class DriverAssert
     /// </summary>
     /// <param name="driver">if null uses <see cref="Application.Driver"/></param>
     /// <param name="expectedColors"></param>
-    internal static void AssertDriverUsedColors (IConsoleDriver driver = null, params Attribute [] expectedColors)
+    internal static void AssertDriverUsedColors (IConsoleDriver? driver = null, params Attribute [] expectedColors)
     {
         driver ??= Application.Driver;
-        Cell [,] contents = driver.Contents;
+        Cell [,] contents = driver?.Contents!;
 
         List<Attribute> toFind = expectedColors.ToList ();
 
         // Contents 3rd column is an Attribute
         HashSet<Attribute> colorsUsed = new ();
 
-        for (var r = 0; r < driver.Rows; r++)
+        for (var r = 0; r < driver!.Rows; r++)
         {
             for (var c = 0; c < driver.Cols; c++)
             {
@@ -381,11 +382,9 @@ internal partial class DriverAssert
         throw new (sb.ToString ());
     }
 
-
     [GeneratedRegex ("^\\s+", RegexOptions.Multiline)]
     private static partial Regex LeadingWhitespaceRegEx ();
 
-
     [GeneratedRegex ("\\s+$", RegexOptions.Multiline)]
     private static partial Regex TrailingWhiteSpaceRegEx ();
 }

+ 0 - 1582
Tests/UnitTests/Input/EscSeqUtilsTests.cs

@@ -1,1582 +0,0 @@
-using System.Text;
-using UnitTests;
-
-// ReSharper disable HeuristicUnreachableCode
-
-namespace UnitTests.DriverTests;
-
-public class EscSeqUtilsTests
-{
-    private bool _actionStarted;
-    private MouseFlags _arg1;
-    private Point _arg2;
-    private string _c1Control, _code, _terminating;
-    private ConsoleKeyInfo [] _cki;
-    private bool _isKeyMouse;
-    private bool _isResponse;
-    private ConsoleKey _key;
-    private ConsoleModifiers _mod;
-    private List<MouseFlags> _mouseFlags;
-    private ConsoleKeyInfo _newConsoleKeyInfo;
-    private Point _pos;
-    private string [] _values;
-
-    [Fact]
-    [AutoInitShutdown]
-    public void DecodeEscSeq_Multiple_Tests ()
-    {
-        // ESC
-        _cki = new ConsoleKeyInfo [] { new ('\u001b', 0, false, false, false) };
-        var expectedCki = new ConsoleKeyInfo ('\u001b', ConsoleKey.Escape, false, false, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.Escape, _key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("ESC", _c1Control);
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Null (_terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-        _cki = new ConsoleKeyInfo [] { new ('\u001b', 0, false, false, false), new ('\u0012', 0, false, false, false) };
-        expectedCki = new ('\u0012', ConsoleKey.R, false, true, true);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.R, _key);
-        Assert.Equal (ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod);
-        Assert.Equal ("ESC", _c1Control);
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Equal ("\u0012", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-        _cki = new ConsoleKeyInfo [] { new ('\u001b', 0, false, false, false), new ('r', 0, false, false, false) };
-        expectedCki = new ('r', ConsoleKey.R, false, true, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.R, _key);
-        Assert.Equal (ConsoleModifiers.Alt, _mod);
-        Assert.Equal ("ESC", _c1Control);
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Equal ("r", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        // SS3
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false), new ('O', 0, false, false, false), new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, false, false, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("SS3", _c1Control);
-        Assert.Null (_code);
-        Assert.Single (_values);
-        Assert.Null (_values [0]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        // CSI
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, true, false, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Shift, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("2", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, false, true, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Alt, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('4', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, true, true, false);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Alt, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("4", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('5', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, false, false, true);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Control, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("5", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('6', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, true, false, true);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Control, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("6", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('7', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, false, true, true);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("7", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('8', 0, false, false, false),
-            new ('R', 0, false, false, false)
-        };
-        expectedCki = new ('\0', ConsoleKey.F3, true, true, true);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.F3, _key);
-        Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("1", _values [0]);
-        Assert.Equal ("8", _values [^1]);
-        Assert.Equal ("R", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("M", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (new () { MouseFlags.Button1Pressed }, _mouseFlags);
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('m', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("m", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (2, _mouseFlags.Count);
-
-        Assert.Equal (
-                      new () { MouseFlags.Button1Released, MouseFlags.Button1Clicked },
-                      _mouseFlags
-                     );
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("M", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (new () { MouseFlags.Button1DoubleClicked }, _mouseFlags);
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("M", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (new () { MouseFlags.Button1TripleClicked }, _mouseFlags);
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-        
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("M", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (new () { MouseFlags.Button1Pressed }, _mouseFlags);
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-
-        Assert.Equal (MouseFlags.None, _arg1);
-        Assert.Equal (new (0, 0), _arg2);
-
-        ClearAll ();
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('m', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Equal ("<", _code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("0", _values [0]);
-        Assert.Equal ("2", _values [1]);
-        Assert.Equal ("3", _values [^1]);
-        Assert.Equal ("m", _terminating);
-        Assert.True (_isKeyMouse);
-        Assert.Equal (new () { MouseFlags.Button1Released }, _mouseFlags);
-        Assert.Equal (new (1, 2), _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-
-        Assert.Empty (EscSeqRequests.Statuses);
-        EscSeqRequests.Clear ();
-        EscSeqRequests.Add ("t");
-
-        _cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('8', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new ('t', 0, false, false, false)
-        };
-        expectedCki = default (ConsoleKeyInfo);
-        Assert.Single (EscSeqRequests.Statuses);
-        Assert.Equal ("t", EscSeqRequests.Statuses.ToArray () [^1].Terminator);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (0, (int)_key);
-        Assert.Equal (0, (int)_mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("8", _values [0]);
-        Assert.Equal ("10", _values [1]);
-        Assert.Equal ("20", _values [^1]);
-        Assert.Equal ("t", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.True (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-    }
-
-    [Theory]
-    [InlineData ('A', ConsoleKey.A, true, true, false, "ESC", '\u001b', 'A')]
-    [InlineData ('a', ConsoleKey.A, false, true, false, "ESC", '\u001b', 'a')]
-    [InlineData ('\0', ConsoleKey.Spacebar, false, true, true, "ESC", '\u001b', '\0')]
-    [InlineData (' ', ConsoleKey.Spacebar, true, true, false, "ESC", '\u001b', ' ')]
-    [InlineData ('\n', ConsoleKey.Enter, false, true, true, "ESC", '\u001b', '\n')]
-    [InlineData ('\r', ConsoleKey.Enter, true, true, false, "ESC", '\u001b', '\r')]
-    public void DecodeEscSeq_More_Multiple_Tests (
-        char keyChar,
-        ConsoleKey consoleKey,
-        bool shift,
-        bool alt,
-        bool control,
-        string c1Control,
-        params char [] kChars
-    )
-    {
-        _cki = new ConsoleKeyInfo [kChars.Length];
-
-        for (var i = 0; i < kChars.Length; i++)
-        {
-            char kChar = kChars [i];
-            _cki [i] = new (kChar, 0, false, false, false);
-        }
-
-        var expectedCki = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (consoleKey, _key);
-
-        ConsoleModifiers mods = new ();
-
-        if (shift)
-        {
-            mods = ConsoleModifiers.Shift;
-        }
-
-        if (alt)
-        {
-            mods |= ConsoleModifiers.Alt;
-        }
-
-        if (control)
-        {
-            mods |= ConsoleModifiers.Control;
-        }
-
-        Assert.Equal (mods, _mod);
-        Assert.Equal (c1Control, _c1Control);
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Equal (keyChar.ToString (), _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-    }
-
-    [Fact]
-    public void DecodeEscSeq_IncompleteCKInfos ()
-    {
-        // This is simulated response from a CSI_ReportTerminalSizeInChars
-        _cki =
-        [
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('8', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('1', 0, false, false, false),
-        ];
-
-        ConsoleKeyInfo expectedCki = default;
-
-        Assert.Null (EscSeqUtils.IncompleteCkInfos);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.None, _key);
-        Assert.Equal (ConsoleModifiers.None, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal ([0], _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-        Assert.NotNull (EscSeqUtils.IncompleteCkInfos);
-        Assert.Equal (_cki, EscSeqUtils.IncompleteCkInfos);
-        Assert.Contains (EscSeqUtils.ToString (EscSeqUtils.IncompleteCkInfos), EscSeqUtils.ToString (_cki));
-
-        _cki = EscSeqUtils.InsertArray (
-                                        EscSeqUtils.IncompleteCkInfos,
-                                        [
-                                            new ('0', 0, false, false, false),
-                                            new (';', 0, false, false, false),
-                                            new ('2', 0, false, false, false),
-                                            new ('0', 0, false, false, false),
-                                            new ('t', 0, false, false, false)
-                                        ]);
-
-        expectedCki = default;
-
-        // Add a request to avoid assert failure in the DecodeEscSeq method
-        EscSeqRequests.Add ("t");
-        Assert.Single (EscSeqRequests.Statuses);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (ConsoleKey.None, _key);
-
-        Assert.Equal (ConsoleModifiers.None, _mod);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (3, _values.Length);
-        Assert.Equal ("t", _terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal ([0], _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (EscSeqRequests.HasResponse ("t"));
-        Assert.True (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-        Assert.Null (EscSeqUtils.IncompleteCkInfos);
-        Assert.NotEqual (_cki, EscSeqUtils.IncompleteCkInfos);
-
-        ClearAll ();
-    }
-
-    [Theory]
-    [InlineData ('\u001B', ConsoleKey.Escape, false, false, false)]
-    [InlineData ('\r', ConsoleKey.Enter, false, false, false)]
-    [InlineData ('1', ConsoleKey.D1, false, false, false)]
-    [InlineData ('!', ConsoleKey.None, false, false, false)]
-    [InlineData ('a', ConsoleKey.A, false, false, false)]
-    [InlineData ('A', ConsoleKey.A, true, false, false)]
-    [InlineData ('\u0001', ConsoleKey.A, false, false, true)]
-    [InlineData ('\0', ConsoleKey.Spacebar, false, false, true)]
-    [InlineData ('\n', ConsoleKey.Enter, false, false, true)]
-    [InlineData ('\t', ConsoleKey.Tab, false, false, false)]
-    public void DecodeEscSeq_Single_Tests (char keyChar, ConsoleKey consoleKey, bool shift, bool alt, bool control)
-    {
-        _cki = [new (keyChar, 0, false, false, false)];
-        var expectedCki = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control);
-
-        EscSeqUtils.DecodeEscSeq (
-                                                     ref _newConsoleKeyInfo,
-                                                     ref _key,
-                                                     _cki,
-                                                     ref _mod,
-                                                     out _c1Control,
-                                                     out _code,
-                                                     out _values,
-                                                     out _terminating,
-                                                     out _isKeyMouse,
-                                                     out _mouseFlags,
-                                                     out _pos,
-                                                     out _isResponse,
-                                                     ProcessContinuousButtonPressed
-                                                    );
-        Assert.Empty (EscSeqRequests.Statuses);
-        Assert.Equal (expectedCki, _newConsoleKeyInfo);
-        Assert.Equal (consoleKey, _key);
-
-        ConsoleModifiers mods = new ();
-
-        if (shift)
-        {
-            mods = ConsoleModifiers.Shift;
-        }
-
-        if (alt)
-        {
-            mods |= ConsoleModifiers.Alt;
-        }
-
-        if (control)
-        {
-            mods |= ConsoleModifiers.Control;
-        }
-
-        Assert.Equal (mods, _mod);
-
-        if (keyChar == '\u001B')
-        {
-            Assert.Equal ("ESC", _c1Control);
-        }
-        else
-        {
-            Assert.Null (_c1Control);
-        }
-
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Null (_terminating);
-        Assert.False (_isKeyMouse);
-        Assert.Equal (new () { 0 }, _mouseFlags);
-        Assert.Equal (Point.Empty, _pos);
-        Assert.False (_isResponse);
-        Assert.Equal (0, (int)_arg1);
-        Assert.Equal (Point.Empty, _arg2);
-
-        ClearAll ();
-    }
-
-    [Fact]
-    public void Defaults_Values ()
-    {
-        Assert.Equal ('\x1b', EscSeqUtils.KeyEsc);
-        Assert.Equal ("\x1b[", EscSeqUtils.CSI);
-        Assert.Equal ("\x1b[?1003h", EscSeqUtils.CSI_EnableAnyEventMouse);
-        Assert.Equal ("\x1b[?1006h", EscSeqUtils.CSI_EnableSgrExtModeMouse);
-        Assert.Equal ("\x1b[?1015h", EscSeqUtils.CSI_EnableUrxvtExtModeMouse);
-        Assert.Equal ("\x1b[?1003l", EscSeqUtils.CSI_DisableAnyEventMouse);
-        Assert.Equal ("\x1b[?1006l", EscSeqUtils.CSI_DisableSgrExtModeMouse);
-        Assert.Equal ("\x1b[?1015l", EscSeqUtils.CSI_DisableUrxvtExtModeMouse);
-        Assert.Equal ("\x1b[?1003h\x1b[?1015h\u001b[?1006h", EscSeqUtils.CSI_EnableMouseEvents);
-        Assert.Equal ("\x1b[?1003l\x1b[?1015l\u001b[?1006l", EscSeqUtils.CSI_DisableMouseEvents);
-    }
-
-    [Fact]
-    public void GetC1ControlChar_Tests ()
-    {
-        Assert.Equal ("IND", EscSeqUtils.GetC1ControlChar ('D'));
-        Assert.Equal ("NEL", EscSeqUtils.GetC1ControlChar ('E'));
-        Assert.Equal ("HTS", EscSeqUtils.GetC1ControlChar ('H'));
-        Assert.Equal ("RI", EscSeqUtils.GetC1ControlChar ('M'));
-        Assert.Equal ("SS2", EscSeqUtils.GetC1ControlChar ('N'));
-        Assert.Equal ("SS3", EscSeqUtils.GetC1ControlChar ('O'));
-        Assert.Equal ("DCS", EscSeqUtils.GetC1ControlChar ('P'));
-        Assert.Equal ("SPA", EscSeqUtils.GetC1ControlChar ('V'));
-        Assert.Equal ("EPA", EscSeqUtils.GetC1ControlChar ('W'));
-        Assert.Equal ("SOS", EscSeqUtils.GetC1ControlChar ('X'));
-        Assert.Equal ("DECID", EscSeqUtils.GetC1ControlChar ('Z'));
-        Assert.Equal ("CSI", EscSeqUtils.GetC1ControlChar ('['));
-        Assert.Equal ("ST", EscSeqUtils.GetC1ControlChar ('\\'));
-        Assert.Equal ("OSC", EscSeqUtils.GetC1ControlChar (']'));
-        Assert.Equal ("PM", EscSeqUtils.GetC1ControlChar ('^'));
-        Assert.Equal ("APC", EscSeqUtils.GetC1ControlChar ('_'));
-        Assert.Equal ("", EscSeqUtils.GetC1ControlChar ('\0'));
-    }
-
-    [Fact]
-    public void GetConsoleInputKey_ConsoleKeyInfo ()
-    {
-        var cki = new ConsoleKeyInfo ('r', 0, false, false, false);
-        var expectedCki = new ConsoleKeyInfo ('r', ConsoleKey.R, false, false, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, true, false, false);
-        expectedCki = new ('r', ConsoleKey.R, true, false, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, false, true, false);
-        expectedCki = new ('r', ConsoleKey.R, false, true, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, false, false, true);
-        expectedCki = new ('r', ConsoleKey.R, false, false, true);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, true, true, false);
-        expectedCki = new ('r', ConsoleKey.R, true, true, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, false, true, true);
-        expectedCki = new ('r', ConsoleKey.R, false, true, true);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('r', 0, true, true, true);
-        expectedCki = new ('r', ConsoleKey.R, true, true, true);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('\u0012', 0, false, false, false);
-        expectedCki = new ('\u0012', ConsoleKey.R, false, false, true);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('\0', (ConsoleKey)64, false, false, true);
-        expectedCki = new ('\0', ConsoleKey.Spacebar, false, false, true);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('\r', 0, false, false, false);
-        expectedCki = new ('\r', ConsoleKey.Enter, false, false, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('\u007f', 0, false, false, false);
-        expectedCki = new ('\u007f', ConsoleKey.Backspace, false, false, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-
-        cki = new ('R', 0, false, false, false);
-        expectedCki = new ('R', ConsoleKey.R, true, false, false);
-        Assert.Equal (expectedCki, EscSeqUtils.MapConsoleKeyInfo (cki));
-    }
-
-    [Fact]
-    public void GetConsoleKey_Tests ()
-    {
-        ConsoleModifiers mod = 0;
-        char keyChar = '\0';
-        Assert.Equal (ConsoleKey.UpArrow, EscSeqUtils.GetConsoleKey ('A', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.DownArrow, EscSeqUtils.GetConsoleKey ('B', "", ref mod, ref keyChar));
-        Assert.Equal (_key = ConsoleKey.RightArrow, EscSeqUtils.GetConsoleKey ('C', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.LeftArrow, EscSeqUtils.GetConsoleKey ('D', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.End, EscSeqUtils.GetConsoleKey ('F', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Home, EscSeqUtils.GetConsoleKey ('H', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F1, EscSeqUtils.GetConsoleKey ('P', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F2, EscSeqUtils.GetConsoleKey ('Q', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F3, EscSeqUtils.GetConsoleKey ('R', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F4, EscSeqUtils.GetConsoleKey ('S', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Tab, EscSeqUtils.GetConsoleKey ('Z', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleModifiers.Shift, mod);
-        Assert.Equal (0, (int)EscSeqUtils.GetConsoleKey ('\0', "", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Insert, EscSeqUtils.GetConsoleKey ('~', "2", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Delete, EscSeqUtils.GetConsoleKey ('~', "3", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.PageUp, EscSeqUtils.GetConsoleKey ('~', "5", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.PageDown, EscSeqUtils.GetConsoleKey ('~', "6", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F5, EscSeqUtils.GetConsoleKey ('~', "15", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F6, EscSeqUtils.GetConsoleKey ('~', "17", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F7, EscSeqUtils.GetConsoleKey ('~', "18", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F8, EscSeqUtils.GetConsoleKey ('~', "19", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F9, EscSeqUtils.GetConsoleKey ('~', "20", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F10, EscSeqUtils.GetConsoleKey ('~', "21", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F11, EscSeqUtils.GetConsoleKey ('~', "23", ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.F12, EscSeqUtils.GetConsoleKey ('~', "24", ref mod, ref keyChar));
-        Assert.Equal (0, (int)EscSeqUtils.GetConsoleKey ('~', "", ref mod, ref keyChar));
-        // These terminators are used by macOS on a numeric keypad without keys modifiers
-        Assert.Equal (ConsoleKey.Add, EscSeqUtils.GetConsoleKey ('l', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Subtract, EscSeqUtils.GetConsoleKey ('m', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Insert, EscSeqUtils.GetConsoleKey ('p', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.End, EscSeqUtils.GetConsoleKey ('q', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.DownArrow, EscSeqUtils.GetConsoleKey ('r', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.PageDown, EscSeqUtils.GetConsoleKey ('s', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.LeftArrow, EscSeqUtils.GetConsoleKey ('t', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Clear, EscSeqUtils.GetConsoleKey ('u', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.RightArrow, EscSeqUtils.GetConsoleKey ('v', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.Home, EscSeqUtils.GetConsoleKey ('w', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.UpArrow, EscSeqUtils.GetConsoleKey ('x', null, ref mod, ref keyChar));
-        Assert.Equal (ConsoleKey.PageUp, EscSeqUtils.GetConsoleKey ('y', null, ref mod, ref keyChar));
-    }
-
-    [Fact]
-    public void GetConsoleModifiers_Tests ()
-    {
-        Assert.Equal (ConsoleModifiers.Shift, EscSeqUtils.GetConsoleModifiers ("2"));
-        Assert.Equal (ConsoleModifiers.Alt, EscSeqUtils.GetConsoleModifiers ("3"));
-        Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Alt, EscSeqUtils.GetConsoleModifiers ("4"));
-        Assert.Equal (ConsoleModifiers.Control, EscSeqUtils.GetConsoleModifiers ("5"));
-        Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Control, EscSeqUtils.GetConsoleModifiers ("6"));
-        Assert.Equal (ConsoleModifiers.Alt | ConsoleModifiers.Control, EscSeqUtils.GetConsoleModifiers ("7"));
-
-        Assert.Equal (
-                      ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control,
-                      EscSeqUtils.GetConsoleModifiers ("8")
-                     );
-        Assert.Equal (0, (int)EscSeqUtils.GetConsoleModifiers (""));
-    }
-
-    [Fact]
-    public void GetEscapeResult_Multiple_Tests ()
-    {
-        char [] kChars = ['\u001b', '[', '5', ';', '1', '0', 'r'];
-        (_c1Control, _code, _values, _terminating) = EscSeqUtils.GetEscapeResult (kChars);
-        Assert.Equal ("CSI", _c1Control);
-        Assert.Null (_code);
-        Assert.Equal (2, _values.Length);
-        Assert.Equal ("5", _values [0]);
-        Assert.Equal ("10", _values [^1]);
-        Assert.Equal ("r", _terminating);
-
-        ClearAll ();
-    }
-
-    [Theory]
-    [InlineData ('\u001B')]
-    [InlineData (['\r'])]
-    [InlineData (['1'])]
-    [InlineData (['!'])]
-    [InlineData (['a'])]
-    [InlineData (['A'])]
-    public void GetEscapeResult_Single_Tests (params char [] kChars)
-    {
-        (_c1Control, _code, _values, _terminating) = EscSeqUtils.GetEscapeResult (kChars);
-
-        if (kChars [0] == '\u001B')
-        {
-            Assert.Equal ("ESC", _c1Control);
-        }
-        else
-        {
-            Assert.Null (_c1Control);
-        }
-
-        Assert.Null (_code);
-        Assert.Null (_values);
-        Assert.Null (_terminating);
-
-        ClearAll ();
-    }
-
-    [Fact]
-    public void GetKeyCharArray_Tests ()
-    {
-        ConsoleKeyInfo [] cki =
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('5', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('1', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new ('r', 0, false, false, false)
-        };
-
-        Assert.Equal (new [] { '\u001b', '[', '5', ';', '1', '0', 'r' }, EscSeqUtils.GetKeyCharArray (cki));
-    }
-
-    [Fact]
-    [AutoInitShutdown]
-    public void GetMouse_Tests ()
-    {
-        ConsoleKeyInfo [] cki =
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        EscSeqUtils.GetMouse (cki, out List<MouseFlags> mouseFlags, out Point pos, ProcessContinuousButtonPressed);
-        Assert.Equal (new () { MouseFlags.Button1Pressed }, mouseFlags);
-        Assert.Equal (new (1, 2), pos);
-
-        cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('m', 0, false, false, false)
-        };
-        EscSeqUtils.GetMouse (cki, out mouseFlags, out pos, ProcessContinuousButtonPressed);
-        Assert.Equal (2, mouseFlags.Count);
-
-        Assert.Equal (
-                      new () { MouseFlags.Button1Released, MouseFlags.Button1Clicked },
-                      mouseFlags
-                     );
-        Assert.Equal (new (1, 2), pos);
-
-        cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        EscSeqUtils.GetMouse (cki, out mouseFlags, out pos, ProcessContinuousButtonPressed);
-        Assert.Equal (new () { MouseFlags.Button1DoubleClicked }, mouseFlags);
-        Assert.Equal (new (1, 2), pos);
-
-        cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('M', 0, false, false, false)
-        };
-        EscSeqUtils.GetMouse (cki, out mouseFlags, out pos, ProcessContinuousButtonPressed);
-        Assert.Equal (new () { MouseFlags.Button1TripleClicked }, mouseFlags);
-        Assert.Equal (new (1, 2), pos);
-
-        cki = new ConsoleKeyInfo []
-        {
-            new ('\u001b', 0, false, false, false),
-            new ('[', 0, false, false, false),
-            new ('<', 0, false, false, false),
-            new ('0', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('2', 0, false, false, false),
-            new (';', 0, false, false, false),
-            new ('3', 0, false, false, false),
-            new ('m', 0, false, false, false)
-        };
-        EscSeqUtils.GetMouse (cki, out mouseFlags, out pos, ProcessContinuousButtonPressed);
-        Assert.Equal (new () { MouseFlags.Button1Released }, mouseFlags);
-        Assert.Equal (new (1, 2), pos);
-    }
-
-    [Fact]
-    public void ResizeArray_ConsoleKeyInfo ()
-    {
-        ConsoleKeyInfo [] expectedCkInfos = null;
-        var cki = new ConsoleKeyInfo ('\u001b', ConsoleKey.Escape, false, false, false);
-        expectedCkInfos = EscSeqUtils.ResizeArray (cki, expectedCkInfos);
-        Assert.Single (expectedCkInfos);
-        Assert.Equal (cki, expectedCkInfos [0]);
-    }
-
-    [Theory]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\b", "\b")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\t", "\t")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\n", "\n")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\r", "\r")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOCe", "e")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOCV", "V")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\u007f", "\u007f")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC ", " ")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\\", "\\")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC|", "|")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC1", "1")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC!", "!")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC\"", "\"")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC@", "@")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC#", "#")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC£", "£")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC$", "$")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC§", "§")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC%", "%")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC€", "€")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC&", "&")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC/", "/")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC{", "{")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC(", "(")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC[", "[")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC)", ")")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC]", "]")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC=", "=")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC}", "}")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC'", "'")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC?", "?")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC«", "«")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC»", "»")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC+", "+")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC*", "*")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC¨", "¨")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC´", "´")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC`", "`")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOCç", "ç")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOCº", "º")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOCª", "ª")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC~", "~")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC^", "^")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC<", "<")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC>", ">")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC,", ",")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC;", ";")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC.", ".")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC:", ":")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC-", "-")]
-    [InlineData ("\r[<35;50;1m[<35;49;1m[<35;47;1m[<35;46;1m[<35;45;2m[<35;44;2m[<35;43;3m[<35;42;3m[<35;41;4m[<35;40;5m[<35;39;6m[<35;49;1m[<35;48;2m[<0;33;6M[<0;33;6mOC_", "_")]
-    public void SplitEscapeRawString_Multiple_Tests (string rawData, string expectedLast)
-    {
-        List<string> splitList = EscSeqUtils.SplitEscapeRawString (rawData);
-        Assert.Equal (18, splitList.Count);
-        Assert.Equal ("\r", splitList [0]);
-        Assert.Equal ("\u001b[<35;50;1m", splitList [1]);
-        Assert.Equal ("\u001b[<35;49;1m", splitList [2]);
-        Assert.Equal ("\u001b[<35;47;1m", splitList [3]);
-        Assert.Equal ("\u001b[<35;46;1m", splitList [4]);
-        Assert.Equal ("\u001b[<35;45;2m", splitList [5]);
-        Assert.Equal ("\u001b[<35;44;2m", splitList [6]);
-        Assert.Equal ("\u001b[<35;43;3m", splitList [7]);
-        Assert.Equal ("\u001b[<35;42;3m", splitList [8]);
-        Assert.Equal ("\u001b[<35;41;4m", splitList [9]);
-        Assert.Equal ("\u001b[<35;40;5m", splitList [10]);
-        Assert.Equal ("\u001b[<35;39;6m", splitList [11]);
-        Assert.Equal ("\u001b[<35;49;1m", splitList [12]);
-        Assert.Equal ("\u001b[<35;48;2m", splitList [13]);
-        Assert.Equal ("\u001b[<0;33;6M", splitList [14]);
-        Assert.Equal ("\u001b[<0;33;6m", splitList [15]);
-        Assert.Equal ("\u001bOC", splitList [16]);
-        Assert.Equal (expectedLast, splitList [^1]);
-    }
-
-    [Theory]
-    [InlineData ("[<35;50;1m")]
-    [InlineData ("\r")]
-    [InlineData ("1")]
-    [InlineData ("!")]
-    [InlineData ("a")]
-    [InlineData ("A")]
-    public void SplitEscapeRawString_Single_Tests (string rawData)
-    {
-        List<string> splitList = EscSeqUtils.SplitEscapeRawString (rawData);
-        Assert.Single (splitList);
-        Assert.Equal (rawData, splitList [0]);
-    }
-
-    [Theory]
-    [InlineData (null, null, null, null)]
-    [InlineData ("\u001b[8;1", null, null, "\u001b[8;1")]
-    [InlineData (null, "\u001b[8;1", 5, "\u001b[8;1")]
-    [InlineData ("\u001b[8;1", null, 5, "\u001b[8;1")]
-    [InlineData ("\u001b[8;1", "0;20t", -1, "\u001b[8;10;20t")]
-    [InlineData ("\u001b[8;1", "0;20t", 0, "\u001b[8;10;20t")]
-    [InlineData ("0;20t", "\u001b[8;1", 5, "\u001b[8;10;20t")]
-    [InlineData ("0;20t", "\u001b[8;1", 3, "\u001b[80;20t;1")]
-    public void InsertArray_Tests (string toInsert, string current, int? index, string expected)
-    {
-        ConsoleKeyInfo [] toIns = EscSeqUtils.ToConsoleKeyInfoArray (toInsert);
-        ConsoleKeyInfo [] cki = EscSeqUtils.ToConsoleKeyInfoArray (current);
-        ConsoleKeyInfo [] result = EscSeqUtils.ToConsoleKeyInfoArray (expected);
-
-        if (index is null)
-        {
-            cki = EscSeqUtils.InsertArray (toIns, cki);
-        }
-        else
-        {
-            cki = EscSeqUtils.InsertArray (toIns, cki, (int)index);
-        }
-
-        Assert.Equal (result, cki);
-    }
-
-    [Theory]
-    [InlineData (0, 0, $"{EscSeqUtils.CSI}0;0H")]
-    [InlineData (int.MaxValue, int.MaxValue, $"{EscSeqUtils.CSI}2147483647;2147483647H")]
-    [InlineData (int.MinValue, int.MinValue, $"{EscSeqUtils.CSI}-2147483648;-2147483648H")]
-    public void CSI_WriteCursorPosition_ReturnsCorrectEscSeq (int row, int col, string expected)
-    {
-        StringBuilder builder = new();
-        using StringWriter writer = new(builder);
-
-        EscSeqUtils.CSI_WriteCursorPosition (writer, row, col);
-
-        string actual = builder.ToString();
-        Assert.Equal (expected, actual);
-    }
-
-    [Theory]
-    [InlineData ('\u001B', KeyCode.Esc)]
-    [InlineData ('\r', KeyCode.Enter)]
-    [InlineData ('1', KeyCode.D1)]
-    [InlineData ('!', (KeyCode)'!')]
-    [InlineData ('a', KeyCode.A)]
-    [InlineData ('A', KeyCode.A | KeyCode.ShiftMask)]
-    public void MapChar_Returns_Modifiers_If_Needed (char ch, KeyCode keyCode)
-    {
-        ConsoleKeyInfo cki = EscSeqUtils.MapChar (ch);
-        Key key = EscSeqUtils.MapKey (cki);
-        Key expectedKey = keyCode;
-
-        Assert.Equal (key, expectedKey);
-    }
-
-    private void ClearAll ()
-    {
-        EscSeqRequests.Clear ();
-        _newConsoleKeyInfo = default (ConsoleKeyInfo);
-        _key = default (ConsoleKey);
-        _cki = default (ConsoleKeyInfo []);
-        _mod = default (ConsoleModifiers);
-        _c1Control = default (string);
-        _code = default (string);
-        _terminating = default (string);
-        _values = default (string []);
-        _isKeyMouse = default (bool);
-        _isResponse = false;
-        _mouseFlags = default (List<MouseFlags>);
-        _pos = default (Point);
-        _arg1 = default (MouseFlags);
-        _arg2 = default (Point);
-    }
-
-    private void ProcessContinuousButtonPressed (MouseFlags arg1, Point arg2)
-    {
-        _arg1 = arg1;
-        _arg2 = arg2;
-        _actionStarted = true;
-    }
-}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików