Forráskód Böngészése

Fixes #4361 - Consolidate `FakeDriver` into library and refactor driver architecture (#4362)

* Initial plan

* Add ScreenChanged event, SetScreenSize method, and fix FakeDriver buffer initialization

Co-authored-by: tig <[email protected]>

* Add comprehensive tests for ScreenChanged event and buffer integrity

Co-authored-by: tig <[email protected]>

* Replace obsolete SizeChanged usage with ScreenChanged in core and tests

Co-authored-by: tig <[email protected]>

* Refactor terminal size event handling

Replaced `ScreenChanged` with `SizeChanged` across the codebase to standardize naming and improve clarity. Updated event handling logic, including subscriptions, unsubscriptions, and raising methods. Removed deprecated `ScreenChanged` event and backward compatibility code.

Refactored driver initialization to handle legacy `IConsoleDriver` types separately. Updated tests and mock implementations to align with the new `SizeChanged` event. Improved documentation and comments to reflect these changes.

These updates enhance maintainability, consistency, and modernize the architecture.

* Refactor & Code Cleanup: Replace IWindowSizeMonitor with IConsoleSizeMonitor

Renamed `IWindowSizeMonitor` to `IConsoleSizeMonitor` across the codebase, updating all references, method signatures, and event handlers. Replaced the `WindowSizeMonitor` class with the new `ConsoleSizeMonitor` implementation, which includes improved terminal size change handling via the `Poll` method.

Enabled nullable reference types in several files to enhance code safety. Updated test cases to reflect the new `IConsoleSizeMonitor` interface. Removed redundant code, simplified null checks, and corrected minor typos in comments. Streamlined the codebase by removing the obsolete `WindowSizeMonitor` class and its interface.

* Code cleanup - Refactor and enhance ShadowView and FakeDriverTests

Updated ShadowView.cs to use null-conditional operators and added null checks for safer access to `ScreenContents`. Refined XML documentation in View.Layout.cs for clarity and consistency.

Refactored FakeDriverTests.cs to leverage modern C# features, including shorthand object instantiation, inline lambdas, and tuple-like syntax for `Size` and `Rectangle`. Removed redundant tests and improved test readability and reliability.

Enhanced error handling with null checks and ensured backward compatibility for deprecated events. Improved test coverage for resizing, clipboard operations, and invalid coordinates. Verified buffer integrity and screen updates after resizing.

General improvements include replacing explicit type declarations with `var`, removing unused imports, and aligning code formatting for better readability.

Refactor and improve code quality and test coverage

Updated `ShadowView` for null safety using null-conditional operators. Simplified object initializations and modernized syntax across the codebase, including shorthand initializations and inline lambdas. Enhanced event handling logic and ensured compatibility with obsolete members.

Refactored `FakeDriverTests` by removing redundant code, standardizing formatting, and improving test setup. Suppressed obsolete warnings where necessary. Improved XML documentation in `View.Layout.cs` for clarity and removed outdated references.

Performed general cleanup, including removing unused namespaces, redundant comments, and ensuring consistent formatting. These changes enhance readability, maintainability, and runtime safety.

* Code cleanup

Refactor TimedEventsTests for readability and consistency

Improved code readability and maintainability:
- Enabled nullable reference types with `#nullable enable`.
- Removed unused `using System.Diagnostics;`.
- Updated namespace to `UnitTests.ApplicationTests`.
- Replaced `Terminal.Gui.App.TimedEvents` with `TimedEvents`.
- Reformatted XML documentation comments for alignment.
- Used `var` and target-typed new expressions for consistency.
- Reformatted `Parallel.For` loops and lambdas for clarity.
- Added `Thread.Sleep(10)` to prevent excessive CPU usage in tests.
- Improved assertions and event handler formatting in tests.

Aligned with modern C# coding practices.

* Code Cleanup - No more driver warnings.

Refactor codebase and introduce FakeClipboard

- Adjusted `.editorconfig` to change severity levels for CS0612, CS0618, and CS0672 diagnostics.
- Replaced `FakeDriver.FakeClipboard` with a new `FakeClipboard` class for testing purposes, supporting exception handling and clipboard data manipulation.
- Removed redundant methods (`MakeColor`, `MapKey`) and unused classes (`MockConsoleDriver`) to streamline the codebase.
- Refactored `ConsoleDriverFacade` and `FakeDriver` to simplify logic and improve maintainability.
- Updated tests to use `CreateFakeDriver` and removed or commented out obsolete tests.
- Reformatted and cleaned up code for readability across multiple files.

* Refactor FakeDriver - Code Cleanup

Standardized console size management by replacing `WindowSizeMonitor` with `ConsoleSizeMonitor` across the codebase. Updated methods `GetWindowSize` and `SetWindowSize` to `GetSize` and `SetSize` for consistency.

Refactored `FakeDriver` to use `SetScreenSize` and removed redundant methods. Simplified driver initialization by removing legacy `InternalInit` logic.

Standardized ANSI escape sequences by replacing `CSI_ReportTerminalSizeInChars` with `CSI_ReportWindowSizeInChars`.

Updated test cases to align with the new `ConsoleSizeMonitor` and `SetScreenSize` methods. Removed obsolete test utilities like `FakeSizeMonitor` and `FakeWindowSizeMonitor`.

Performed general code cleanup, including removing unused classes, redundant code, and improving formatting. Fixed resizing logic issues and improved exception handling in driver methods.

* Update Terminal.Gui/Drivers/OutputBuffer.cs

Co-authored-by: Copilot <[email protected]>

* Update Terminal.Gui/Drivers/MouseButtonStateEx.cs

Co-authored-by: Copilot <[email protected]>

* Update Terminal.Gui/App/MainLoop/IApplicationMainLoop.cs

Co-authored-by: Copilot <[email protected]>

* Update Tests/UnitTests/Views/ToplevelTests.cs

Co-authored-by: Copilot <[email protected]>

* Update Terminal.Gui/ViewBase/View.Layout.cs

Co-authored-by: Copilot <[email protected]>

* Moved all Drawing tests to Paralleizable - proving Fakedriver works

Enhanced `Ruler` and `Thickness` classes by adding an optional `IConsoleDriver? driver` parameter to decouple rendering from the default `Application.Driver`, improving flexibility and testability. Updated `DriverAssert` to support nullable drivers and added defensive checks.

Refactored and expanded test cases for `Ruler`, `Thickness`, `LineCanvas`, and `StraightLineExtensions` to ensure comprehensive coverage, including zero-length intersections, line rendering, and exclusion logic. Migrated rendering-dependent tests to a parallelizable namespace.

Removed redundant tests, improved naming conventions, and updated documentation for better maintainability and clarity.

* Fixed Run<T> startup hang.

Refactor: Simplify driver logic and update SetSize methods

Removed FakeDriver safeguard in unit tests to simplify
CreateDriver logic. Updated SetSize methods in NetOutput,
UnixOutput, and WindowsOutput to do nothing instead of
throwing NotImplementedException. Modified SizeChanged
event in ConsoleDriverFacade to call SetScreenSize directly.
Commented out unnecessary debug validation in DimAuto.
These changes improve maintainability and reduce complexity.

* Fixed intermittent unit test bug.

Refactored `_cachedRunStateToplevel` to `CachedRunStateToplevel` as an internal static property, delegating its management to `ApplicationImpl` for improved encapsulation. Updated all references to use the new property and centralized its handling in `ApplicationImpl`.

Removed the `MouseGrabHandler` property from `ApplicationImpl` and simplified driver-related assignments by replacing `Application.ForceDriver` and `Application.Screen` with direct references.

Reset `CachedRunStateToplevel` during cleanup to ensure proper state management. Updated the `Invoke` method to use `Top` directly, aligning with the refactored design. Improved debug assertions and performed general cleanup to enhance code readability and maintainability.

* Fixed intermittent bug an massive code cleanup of warnings.

Refactor and enhance codebase for maintainability

- Applied null-conditional operator (`!`) to improve null-safety.
- Refactored tests for clarity, added new cases, and removed redundancies.
- Introduced `FakeApplicationFactory` and `FakeSizeMonitor` for testing.
- Removed unused code, including legacy `DecodeEscSeq` logic.
- Reformatted code for readability and consistency.
- Updated assertions for more accurate validation in tests.
- Fixed potential null reference issues across multiple files.
- Improved event handling with proper null checks.
- Enhanced documentation for new classes and methods.
- Modernized code with C# features like `record struct` and `nullable enable`.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: tig <[email protected]>
Co-authored-by: Tig <[email protected]>
Co-authored-by: Copilot <[email protected]>
Copilot 1 hónapja
szülő
commit
e6a0ec64ca
100 módosított fájl, 1196 hozzáadás és 6401 törlés
  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;

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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;
-    }
-}

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott