2
0
Эх сурвалжийг харах

Refactored Application into smaller files.
Made Application #nullable enable

Tig 1 жил өмнө
parent
commit
44ce74a5c0
71 өөрчлөгдсөн 1440 нэмэгдсэн , 1433 устгасан
  1. 29 0
      Terminal.Gui/Application/Application.Driver.cs
  2. 209 0
      Terminal.Gui/Application/Application.Initialization.cs
  3. 1 1
      Terminal.Gui/Application/Application.Keyboard.cs
  4. 2 2
      Terminal.Gui/Application/Application.Mouse.cs
  5. 863 0
      Terminal.Gui/Application/Application.Run.cs
  6. 5 1095
      Terminal.Gui/Application/Application.cs
  7. 11 22
      Terminal.Gui/Clipboard/Clipboard.cs
  8. 3 3
      Terminal.Gui/Drawing/LineCanvas.cs
  9. 4 4
      Terminal.Gui/Drawing/Ruler.cs
  10. 9 5
      Terminal.Gui/Drawing/Thickness.cs
  11. 2 2
      Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs
  12. 3 3
      Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs
  13. 2 2
      Terminal.Gui/View/Layout/Dim.cs
  14. 2 2
      Terminal.Gui/View/Layout/DimView.cs
  15. 6 6
      Terminal.Gui/View/Layout/Pos.cs
  16. 2 2
      Terminal.Gui/View/Layout/PosView.cs
  17. 2 2
      Terminal.Gui/View/Layout/ViewLayout.cs
  18. 4 4
      Terminal.Gui/View/ViewDrawing.cs
  19. 3 3
      Terminal.Gui/Views/GraphView/Annotations.cs
  20. 7 7
      Terminal.Gui/Views/GraphView/Axis.cs
  21. 2 2
      Terminal.Gui/Views/GraphView/Series.cs
  22. 1 1
      Terminal.Gui/Views/Menu/ContextMenu.cs
  23. 6 6
      Terminal.Gui/Views/RadioGroup.cs
  24. 14 14
      UICatalog/Scenarios/CombiningMarks.cs
  25. 2 2
      UICatalog/Scenarios/Images.cs
  26. 1 1
      UICatalog/Scenarios/SendKeys.cs
  27. 1 1
      UICatalog/Scenarios/TextEffectsScenario.cs
  28. 2 2
      UICatalog/Scenarios/TrueColors.cs
  29. 1 1
      UICatalog/Scenarios/VkeyPacketSimulator.cs
  30. 2 2
      UICatalog/UICatalog.cs
  31. 7 7
      UnitTests/Application/ApplicationTests.cs
  32. 5 2
      UnitTests/Application/CursorTests.cs
  33. 2 2
      UnitTests/Clipboard/ClipboardTests.cs
  34. 4 4
      UnitTests/ConsoleDrivers/ClipRegionTests.cs
  35. 1 1
      UnitTests/ConsoleDrivers/ConsoleDriverTests.cs
  36. 1 1
      UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs
  37. 10 10
      UnitTests/Dialogs/MessageBoxTests.cs
  38. 5 5
      UnitTests/Drawing/RulerTests.cs
  39. 10 10
      UnitTests/Drawing/ThicknessTests.cs
  40. 2 2
      UnitTests/FileServices/FileDialogTests.cs
  41. 2 2
      UnitTests/Text/TextFormatterTests.cs
  42. 8 8
      UnitTests/View/Adornment/BorderTests.cs
  43. 1 1
      UnitTests/View/Adornment/MarginTests.cs
  44. 1 1
      UnitTests/View/Adornment/PaddingTests.cs
  45. 23 23
      UnitTests/View/DrawTests.cs
  46. 1 1
      UnitTests/View/Layout/Dim.FillTests.cs
  47. 1 1
      UnitTests/View/Layout/Pos.AnchorEndTests.cs
  48. 2 2
      UnitTests/View/Layout/Pos.CenterTests.cs
  49. 1 1
      UnitTests/View/Layout/ViewportTests.cs
  50. 7 7
      UnitTests/View/NavigationTests.cs
  51. 10 10
      UnitTests/View/TextTests.cs
  52. 15 15
      UnitTests/View/ViewTests.cs
  53. 18 18
      UnitTests/Views/AppendAutocompleteTests.cs
  54. 3 3
      UnitTests/Views/ButtonTests.cs
  55. 4 4
      UnitTests/Views/CheckBoxTests.cs
  56. 9 9
      UnitTests/Views/ContextMenuTests.cs
  57. 1 1
      UnitTests/Views/FrameViewTests.cs
  58. 13 13
      UnitTests/Views/LabelTests.cs
  59. 2 2
      UnitTests/Views/ListViewTests.cs
  60. 14 14
      UnitTests/Views/MenuBarTests.cs
  61. 1 1
      UnitTests/Views/OverlappedTests.cs
  62. 1 1
      UnitTests/Views/RadioGroupTests.cs
  63. 6 6
      UnitTests/Views/ScrollBarViewTests.cs
  64. 1 1
      UnitTests/Views/ScrollViewTests.cs
  65. 1 1
      UnitTests/Views/TableViewTests.cs
  66. 7 7
      UnitTests/Views/TextFieldTests.cs
  67. 9 9
      UnitTests/Views/TextViewTests.cs
  68. 24 24
      UnitTests/Views/ToplevelTests.cs
  69. 2 2
      UnitTests/Views/TreeTableSourceTests.cs
  70. 1 1
      UnitTests/Views/TreeViewTests.cs
  71. 3 3
      UnitTests/Views/WindowTests.cs

+ 29 - 0
Terminal.Gui/Application/Application.Driver.cs

@@ -0,0 +1,29 @@
+#nullable enable
+namespace Terminal.Gui;
+
+public static partial class Application // Driver abstractions
+{
+    internal static bool _forceFakeConsole;
+
+    /// <summary>Gets the <see cref="ConsoleDriver"/> that has been selected. See also <see cref="ForceDriver"/>.</summary>
+    public static ConsoleDriver? Driver { get; internal set; }
+
+    /// <summary>
+    ///     Gets or sets whether <see cref="Application.Driver"/> will be forced to output only the 16 colors defined in
+    ///     <see cref="ColorName"/>. The default is <see langword="false"/>, meaning 24-bit (TrueColor) colors will be output
+    ///     as long as the selected <see cref="ConsoleDriver"/> supports TrueColor.
+    /// </summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static bool Force16Colors { get; set; }
+
+    /// <summary>
+    ///     Forces the use of the specified driver (one of "fake", "ansi", "curses", "net", or "windows"). If not
+    ///     specified, the driver is selected based on the platform.
+    /// </summary>
+    /// <remarks>
+    ///     Note, <see cref="Application.Init(ConsoleDriver, string)"/> will override this configuration setting if called
+    ///     with either `driver` or `driverName` specified.
+    /// </remarks>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static string ForceDriver { get; set; } = string.Empty;
+}

+ 209 - 0
Terminal.Gui/Application/Application.Initialization.cs

@@ -0,0 +1,209 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+
+namespace Terminal.Gui;
+
+public static partial class Application // Initialization (Init/Shutdown)
+{
+    /// <summary>Initializes a new instance of <see cref="Terminal.Gui"/> Application.</summary>
+    /// <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
+    /// <para>
+    ///     This function loads the right <see cref="ConsoleDriver"/> for the platform, Creates a <see cref="Toplevel"/>. and
+    ///     assigns it to <see cref="Top"/>
+    /// </para>
+    /// <para>
+    ///     <see cref="Shutdown"/> must be called when the application is closing (typically after
+    ///     <see cref="Run{T}"/> has returned) to ensure resources are cleaned up and
+    ///     terminal settings
+    ///     restored.
+    /// </para>
+    /// <para>
+    ///     The <see cref="Run{T}"/> function combines
+    ///     <see cref="Init(Terminal.Gui.ConsoleDriver,string)"/> and <see cref="Run(Toplevel, Func{Exception, bool})"/>
+    ///     into a single
+    ///     call. An application cam use <see cref="Run{T}"/> without explicitly calling
+    ///     <see cref="Init(Terminal.Gui.ConsoleDriver,string)"/>.
+    /// </para>
+    /// <param name="driver">
+    ///     The <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or
+    ///     <paramref name="driverName"/> are specified the default driver for the platform will be used.
+    /// </param>
+    /// <param name="driverName">
+    ///     The short name (e.g. "net", "windows", "ansi", "fake", or "curses") of the
+    ///     <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
+    ///     specified the default driver for the platform will be used.
+    /// </param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+    public static void Init (ConsoleDriver driver = null, string driverName = null) { InternalInit (driver, driverName); }
+
+    internal static bool _initialized;
+    internal static int _mainThreadId = -1;
+
+
+    // 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 (
+        ConsoleDriver 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 ();
+        }
+
+        // For UnitTests
+        if (driver is { })
+        {
+            Driver = driver;
+        }
+
+        // Start the process of configuration management.
+        // Note that we end up calling LoadConfigurationFromAllSources
+        // multiple times. We need to do this because some settings are only
+        // valid after a Driver is loaded. In this case we need just
+        // `Settings` so we can determine which driver to use.
+        // Don't reset, so we can inherit the theme from the previous run.
+        Load ();
+        Apply ();
+
+        // Ignore Configuration for ForceDriver if driverName is specified
+        if (!string.IsNullOrEmpty (driverName))
+        {
+            ForceDriver = driverName;
+        }
+
+        if (Driver is null)
+        {
+            PlatformID p = Environment.OSVersion.Platform;
+
+            if (string.IsNullOrEmpty (ForceDriver))
+            {
+                if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows)
+                {
+                    Driver = new WindowsDriver ();
+                }
+                else
+                {
+                    Driver = new CursesDriver ();
+                }
+            }
+            else
+            {
+                List<Type> drivers = GetDriverTypes ();
+                Type driverType = drivers.FirstOrDefault (t => t.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase));
+
+                if (driverType is { })
+                {
+                    Driver = (ConsoleDriver)Activator.CreateInstance (driverType);
+                }
+                else
+                {
+                    throw new ArgumentException (
+                                                 $"Invalid driver name: {ForceDriver}. Valid names are {string.Join (", ", drivers.Select (t => t.Name))}"
+                                                );
+                }
+            }
+        }
+
+        try
+        {
+            MainLoop = Driver.Init ();
+        }
+        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
+                                                );
+        }
+
+        Driver.SizeChanged += (s, args) => OnSizeChanging (args);
+        Driver.KeyDown += (s, args) => OnKeyDown (args);
+        Driver.KeyUp += (s, args) => OnKeyUp (args);
+        Driver.MouseEvent += (s, args) => OnMouseEvent (args);
+
+        SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());
+
+        SupportedCultures = GetSupportedCultures ();
+        _mainThreadId = Thread.CurrentThread.ManagedThreadId;
+        _initialized = true;
+        InitializedChanged?.Invoke (null, new (in _initialized));
+    }
+
+    private static void Driver_SizeChanged (object sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
+    private static void Driver_KeyDown (object sender, Key e) { OnKeyDown (e); }
+    private static void Driver_KeyUp (object sender, Key e) { OnKeyUp (e); }
+    private static void Driver_MouseEvent (object sender, MouseEvent e) { OnMouseEvent (e); }
+
+    /// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
+    /// <returns></returns>
+    [RequiresUnreferencedCode ("AOT")]
+    public static List<Type> GetDriverTypes ()
+    {
+        // use reflection to get the list of drivers
+        List<Type> driverTypes = new ();
+
+        foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ())
+        {
+            foreach (Type type in asm.GetTypes ())
+            {
+                if (type.IsSubclassOf (typeof (ConsoleDriver)) && !type.IsAbstract)
+                {
+                    driverTypes.Add (type);
+                }
+            }
+        }
+
+        return driverTypes;
+    }
+
+    /// <summary>Shutdown an application initialized with <see cref="Init"/>.</summary>
+    /// <remarks>
+    ///     Shutdown must be called for every call to <see cref="Init"/> or
+    ///     <see cref="Application.Run(Toplevel, Func{Exception, bool})"/> to ensure all resources are cleaned
+    ///     up (Disposed)
+    ///     and terminal settings are restored.
+    /// </remarks>
+    public static void Shutdown ()
+    {
+        // TODO: Throw an exception if Init hasn't been called.
+        ResetState ();
+        PrintJsonErrors ();
+        InitializedChanged?.Invoke (null, new (in _initialized));
+    }
+
+    /// <summary>
+    ///     This event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
+    /// </summary>
+    /// <remarks>
+    ///     Intended to support unit tests that need to know when the application has been initialized.
+    /// </remarks>
+    public static event EventHandler<EventArgs<bool>> InitializedChanged;
+}

+ 1 - 1
Terminal.Gui/Application/ApplicationKeyboard.cs → Terminal.Gui/Application/Application.Keyboard.cs

@@ -2,7 +2,7 @@
 
 namespace Terminal.Gui;
 
-partial class Application
+public static partial class Application // Keyboard handling
 {
     private static Key _alternateForwardKey = Key.Empty; // Defined in config.json
 

+ 2 - 2
Terminal.Gui/Application/ApplicationMouse.cs → Terminal.Gui/Application/Application.Mouse.cs

@@ -1,6 +1,6 @@
 namespace Terminal.Gui;
 
-partial class Application
+public static partial class Application // Mouse handling
 {
     #region Mouse handling
 
@@ -272,7 +272,7 @@ partial class Application
 
             if (view is Adornment adornmentView)
             {
-                view = adornmentView.Parent.SuperView;
+                view = adornmentView.Parent!.SuperView;
             }
             else
             {

+ 863 - 0
Terminal.Gui/Application/Application.Run.cs

@@ -0,0 +1,863 @@
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Terminal.Gui;
+
+public static partial class Application // Run (Begin, Run, End, Stop)
+{
+    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.
+    /// </summary>
+    /// <remarks>
+    ///     If <see cref="EndAfterFirstIteration"/> is <see langword="true"/> callers to <see cref="Begin(Toplevel)"/>
+    ///     must also subscribe to <see cref="NotifyStopRunState"/> and manually dispose of the <see cref="RunState"/> token
+    ///     when the application is done.
+    /// </remarks>
+    public static event EventHandler<RunStateEventArgs> NotifyNewRunState;
+
+    /// <summary>Notify that an existent <see cref="RunState"/> is stopping (<see cref="End(RunState)"/> was called).</summary>
+    /// <remarks>
+    ///     If <see cref="EndAfterFirstIteration"/> is <see langword="true"/> callers to <see cref="Begin(Toplevel)"/>
+    ///     must also subscribe to <see cref="NotifyStopRunState"/> and manually dispose of the <see cref="RunState"/> token
+    ///     when the application is done.
+    /// </remarks>
+    public static event EventHandler<ToplevelEventArgs> NotifyStopRunState;
+
+    /// <summary>Building block API: Prepares the provided <see cref="Toplevel"/> for execution.</summary>
+    /// <returns>
+    ///     The <see cref="RunState"/> handle that needs to be passed to the <see cref="End(RunState)"/> method upon
+    ///     completion.
+    /// </returns>
+    /// <param name="toplevel">The <see cref="Toplevel"/> to prepare execution for.</param>
+    /// <remarks>
+    ///     This method prepares the provided <see cref="Toplevel"/> for running with the focus, it adds this to the list
+    ///     of <see cref="Toplevel"/>s, lays out the Subviews, focuses the first element, and draws the <see cref="Toplevel"/>
+    ///     in the screen. This is usually followed by executing the <see cref="RunLoop"/> method, and then the
+    ///     <see cref="End(RunState)"/> method upon termination which will undo these changes.
+    /// </remarks>
+    public static RunState Begin (Toplevel toplevel)
+    {
+        ArgumentNullException.ThrowIfNull (toplevel);
+
+#if DEBUG_IDISPOSABLE
+        Debug.Assert (!toplevel.WasDisposed);
+
+        if (_cachedRunStateToplevel is { } && _cachedRunStateToplevel != toplevel)
+        {
+            Debug.Assert (_cachedRunStateToplevel.WasDisposed);
+        }
+#endif
+
+        if (toplevel.IsOverlappedContainer && OverlappedTop != toplevel && OverlappedTop is { })
+        {
+            throw new InvalidOperationException ("Only one Overlapped Container is allowed.");
+        }
+
+        // Ensure the mouse is ungrabbed.
+        MouseGrabView = null;
+
+        var rs = new RunState (toplevel);
+
+        // View implements ISupportInitializeNotification which is derived from ISupportInitialize
+        if (!toplevel.IsInitialized)
+        {
+            toplevel.BeginInit ();
+            toplevel.EndInit ();
+        }
+
+#if DEBUG_IDISPOSABLE
+        if (Top is { } && toplevel != Top && !_topLevels.Contains (Top))
+        {
+            // This assertion confirm if the Top was already disposed
+            Debug.Assert (Top.WasDisposed);
+            Debug.Assert (Top == _cachedRunStateToplevel);
+        }
+#endif
+
+        lock (_topLevels)
+        {
+            if (Top is { } && toplevel != Top && !_topLevels.Contains (Top))
+            {
+                // 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)
+                {
+                    Top = null;
+                }
+                else
+                {
+                    // Probably this will never hit
+                    throw new ObjectDisposedException (Top.GetType ().FullName);
+                }
+            }
+            else if (OverlappedTop is { } && toplevel != Top && _topLevels.Contains (Top))
+            {
+                Top.OnLeave (toplevel);
+            }
+
+            // BUGBUG: We should not depend on `Id` internally.
+            // BUGBUG: It is super unclear what this code does anyway.
+            if (string.IsNullOrEmpty (toplevel.Id))
+            {
+                var count = 1;
+                var id = (_topLevels.Count + count).ToString ();
+
+                while (_topLevels.Count > 0 && _topLevels.FirstOrDefault (x => x.Id == id) is { })
+                {
+                    count++;
+                    id = (_topLevels.Count + count).ToString ();
+                }
+
+                toplevel.Id = (_topLevels.Count + count).ToString ();
+
+                _topLevels.Push (toplevel);
+            }
+            else
+            {
+                Toplevel dup = _topLevels.FirstOrDefault (x => x.Id == toplevel.Id);
+
+                if (dup is null)
+                {
+                    _topLevels.Push (toplevel);
+                }
+            }
+
+            if (_topLevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0)
+            {
+                throw new ArgumentException ("There are duplicates Toplevel IDs");
+            }
+        }
+
+        if (Top is null || toplevel.IsOverlappedContainer)
+        {
+            Top = toplevel;
+        }
+
+        var refreshDriver = true;
+
+        if (OverlappedTop is null
+            || toplevel.IsOverlappedContainer
+            || (Current?.Modal == false && toplevel.Modal)
+            || (Current?.Modal == false && !toplevel.Modal)
+            || (Current?.Modal == true && toplevel.Modal))
+        {
+            if (toplevel.Visible)
+            {
+                Current?.OnDeactivate (toplevel);
+                Toplevel previousCurrent = Current;
+                Current = toplevel;
+                Current.OnActivate (previousCurrent);
+
+                SetCurrentOverlappedAsTop ();
+            }
+            else
+            {
+                refreshDriver = false;
+            }
+        }
+        else if ((OverlappedTop != null
+                  && toplevel != OverlappedTop
+                  && Current?.Modal == true
+                  && !_topLevels.Peek ().Modal)
+                 || (OverlappedTop is { } && toplevel != OverlappedTop && Current?.Running == false))
+        {
+            refreshDriver = false;
+            MoveCurrent (toplevel);
+        }
+        else
+        {
+            refreshDriver = false;
+            MoveCurrent (Current);
+        }
+
+        toplevel.SetRelativeLayout (Driver.Screen.Size);
+
+        toplevel.LayoutSubviews ();
+        toplevel.PositionToplevels ();
+        toplevel.FocusFirst ();
+        BringOverlappedTopToFront ();
+
+        if (refreshDriver)
+        {
+            OverlappedTop?.OnChildLoaded (toplevel);
+            toplevel.OnLoaded ();
+            toplevel.SetNeedsDisplay ();
+            toplevel.Draw ();
+            Driver.UpdateScreen ();
+
+            if (PositionCursor (toplevel))
+            {
+                Driver.UpdateCursor ();
+            }
+        }
+
+        NotifyNewRunState?.Invoke (toplevel, new (rs));
+
+        return rs;
+    }
+
+    /// <summary>
+    ///     Calls <see cref="View.PositionCursor"/> on the most focused view in the view starting with <paramref name="view"/>.
+    /// </summary>
+    /// <remarks>
+    ///     Does nothing if <paramref name="view"/> is <see langword="null"/> or if the most focused view is not visible or
+    ///     enabled.
+    ///     <para>
+    ///         If the most focused view is not visible within it's superview, the cursor will be hidden.
+    ///     </para>
+    /// </remarks>
+    /// <returns><see langword="true"/> if a view positioned the cursor and the position is visible.</returns>
+    internal static bool PositionCursor (View view)
+    {
+        // Find the most focused view and position the cursor there.
+        View mostFocused = view?.MostFocused;
+
+        if (mostFocused is null)
+        {
+            if (view is { HasFocus: true })
+            {
+                mostFocused = view;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        // If the view is not visible or enabled, don't position the cursor
+        if (!mostFocused.Visible || !mostFocused.Enabled)
+        {
+            Driver.GetCursorVisibility (out CursorVisibility current);
+
+            if (current != CursorVisibility.Invisible)
+            {
+                Driver.SetCursorVisibility (CursorVisibility.Invisible);
+            }
+
+            return false;
+        }
+
+        // If the view is not visible within it's superview, don't position the cursor
+        Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty });
+        Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver.Screen;
+
+        if (!superViewViewport.IntersectsWith (mostFocusedViewport))
+        {
+            return false;
+        }
+
+        Point? cursor = mostFocused.PositionCursor ();
+
+        Driver.GetCursorVisibility (out CursorVisibility currentCursorVisibility);
+
+        if (cursor is { })
+        {
+            // Convert cursor to screen coords
+            cursor = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = cursor.Value }).Location;
+
+            // If the cursor is not in a visible location in the SuperView, hide it
+            if (!superViewViewport.Contains (cursor.Value))
+            {
+                if (currentCursorVisibility != CursorVisibility.Invisible)
+                {
+                    Driver.SetCursorVisibility (CursorVisibility.Invisible);
+                }
+
+                return false;
+            }
+
+            // Show it
+            if (currentCursorVisibility == CursorVisibility.Invisible)
+            {
+                Driver.SetCursorVisibility (mostFocused.CursorVisibility);
+            }
+
+            return true;
+        }
+
+        if (currentCursorVisibility != CursorVisibility.Invisible)
+        {
+            Driver.SetCursorVisibility (CursorVisibility.Invisible);
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    ///     Runs the application by creating a <see cref="Toplevel"/> object and calling
+    ///     <see cref="Run(Toplevel, Func{Exception, bool})"/>.
+    /// </summary>
+    /// <remarks>
+    ///     <para>Calling <see cref="Init"/> first is not needed as this function will initialize the application.</para>
+    ///     <para>
+    ///         <see cref="Shutdown"/> must be called when the application is closing (typically after Run> has returned) to
+    ///         ensure resources are cleaned up and terminal settings restored.
+    ///     </para>
+    ///     <para>
+    ///         The caller is responsible for disposing the object returned by this method.
+    ///     </para>
+    /// </remarks>
+    /// <returns>The created <see cref="Toplevel"/> object. The caller is responsible for disposing this object.</returns>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+    public static Toplevel Run (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null) { return Run<Toplevel> (errorHandler, driver); }
+
+    /// <summary>
+    ///     Runs the application by creating a <see cref="Toplevel"/>-derived object of type <c>T</c> and calling
+    ///     <see cref="Run(Toplevel, Func{Exception, bool})"/>.
+    /// </summary>
+    /// <remarks>
+    ///     <para>Calling <see cref="Init"/> first is not needed as this function will initialize the application.</para>
+    ///     <para>
+    ///         <see cref="Shutdown"/> must be called when the application is closing (typically after Run> has returned) to
+    ///         ensure resources are cleaned up and terminal settings restored.
+    ///     </para>
+    ///     <para>
+    ///         The caller is responsible for disposing the object returned by this method.
+    ///     </para>
+    /// </remarks>
+    /// <param name="errorHandler"></param>
+    /// <param name="driver">
+    ///     The <see cref="ConsoleDriver"/> to use. If not specified the default driver for the platform will
+    ///     be used ( <see cref="WindowsDriver"/>, <see cref="CursesDriver"/>, or <see cref="NetDriver"/>). Must be
+    ///     <see langword="null"/> if <see cref="Init"/> has already been called.
+    /// </param>
+    /// <returns>The created T object. The caller is responsible for disposing this object.</returns>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+    public static T Run<T> (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
+        where T : Toplevel, new ()
+    {
+        if (!_initialized)
+        {
+            // Init() has NOT been called.
+            InternalInit (driver, null, true);
+        }
+
+        var top = new T ();
+
+        Run (top, errorHandler);
+
+        return top;
+    }
+
+    /// <summary>Runs the Application using the provided <see cref="Toplevel"/> view.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method is used to start processing events for the main application, but it is also used to run other
+    ///         modal <see cref="View"/>s such as <see cref="Dialog"/> boxes.
+    ///     </para>
+    ///     <para>
+    ///         To make a <see cref="Run(Terminal.Gui.Toplevel,System.Func{System.Exception,bool})"/> stop execution, call
+    ///         <see cref="Application.RequestStop"/>.
+    ///     </para>
+    ///     <para>
+    ///         Calling <see cref="Run(Terminal.Gui.Toplevel,System.Func{System.Exception,bool})"/> is equivalent to calling
+    ///         <see cref="Begin(Toplevel)"/>, followed by <see cref="RunLoop(RunState)"/>, and then calling
+    ///         <see cref="End(RunState)"/>.
+    ///     </para>
+    ///     <para>
+    ///         Alternatively, to have a program control the main loop and process events manually, call
+    ///         <see cref="Begin(Toplevel)"/> to set things up manually and then repeatedly call
+    ///         <see cref="RunLoop(RunState)"/> with the wait parameter set to false. By doing this the
+    ///         <see cref="RunLoop(RunState)"/> method will only process any pending events, timers, idle handlers and then
+    ///         return control immediately.
+    ///     </para>
+    ///     <para>When using <see cref="Run{T}"/> or
+    ///         <see cref="Run(System.Func{System.Exception,bool},Terminal.Gui.ConsoleDriver)"/>
+    ///         <see cref="Init"/> will be called automatically.
+    ///     </para>
+    ///     <para>
+    ///         RELEASE builds only: When <paramref name="errorHandler"/> is <see langword="null"/> any exceptions will be
+    ///         rethrown. Otherwise, if <paramref name="errorHandler"/> will be called. If <paramref name="errorHandler"/>
+    ///         returns <see langword="true"/> the <see cref="RunLoop(RunState)"/> will resume; otherwise this method will
+    ///         exit.
+    ///     </para>
+    /// </remarks>
+    /// <param name="view">The <see cref="Toplevel"/> to run as a modal.</param>
+    /// <param name="errorHandler">
+    ///     RELEASE builds only: Handler for any unhandled exceptions (resumes when returns true,
+    ///     rethrows when null).
+    /// </param>
+    public static void Run (Toplevel view, Func<Exception, bool> errorHandler = null)
+    {
+        ArgumentNullException.ThrowIfNull (view);
+
+        if (_initialized)
+        {
+            if (Driver is null)
+            {
+                // Disposing before throwing
+                view.Dispose ();
+
+                // This code path should be impossible because Init(null, null) will select the platform default driver
+                throw new InvalidOperationException (
+                                                     "Init() completed without a driver being set (this should be impossible); Run<T>() cannot be called."
+                                                    );
+            }
+        }
+        else
+        {
+            // Init() has NOT been called.
+            throw new InvalidOperationException (
+                                                 "Init() has not been called. Only Run() or Run<T>() can be used without calling Init()."
+                                                );
+        }
+
+        var resume = true;
+
+        while (resume)
+        {
+#if !DEBUG
+            try
+            {
+#endif
+            resume = false;
+            RunState runState = Begin (view);
+
+            // If EndAfterFirstIteration is true then the user must dispose of the runToken
+            // by using NotifyStopRunState event.
+            RunLoop (runState);
+
+            if (runState.Toplevel is null)
+            {
+#if DEBUG_IDISPOSABLE
+                Debug.Assert (_topLevels.Count == 0);
+#endif
+                runState.Dispose ();
+
+                return;
+            }
+
+            if (!EndAfterFirstIteration)
+            {
+                End (runState);
+            }
+#if !DEBUG
+            }
+            catch (Exception error)
+            {
+                if (errorHandler is null)
+                {
+                    throw;
+                }
+
+                resume = errorHandler (error);
+            }
+#endif
+        }
+    }
+
+    /// <summary>Adds a timeout to the application.</summary>
+    /// <remarks>
+    ///     When time specified passes, the callback will be invoked. If the callback returns true, the timeout will be
+    ///     reset, repeating the invocation. If it returns false, the timeout will stop and be removed. The returned value is a
+    ///     token that can be used to stop the timeout by calling <see cref="RemoveTimeout(object)"/>.
+    /// </remarks>
+    public static object AddTimeout (TimeSpan time, Func<bool> callback) { return MainLoop?.AddTimeout (time, callback); }
+
+    /// <summary>Removes a previously scheduled timeout</summary>
+    /// <remarks>The token parameter is the value returned by <see cref="AddTimeout"/>.</remarks>
+    /// Returns
+    /// <c>true</c>
+    /// if the timeout is successfully removed; otherwise,
+    /// <c>false</c>
+    /// .
+    /// This method also returns
+    /// <c>false</c>
+    /// if the timeout is not found.
+    public static bool RemoveTimeout (object token) { return MainLoop?.RemoveTimeout (token) ?? false; }
+
+    /// <summary>Runs <paramref name="action"/> on the thread that is processing events</summary>
+    /// <param name="action">the action to be invoked on the main processing thread.</param>
+    public static void Invoke (Action action)
+    {
+        MainLoop?.AddIdle (
+                           () =>
+                           {
+                               action ();
+
+                               return false;
+                           }
+                          );
+    }
+
+    /// <summary>Wakes up the running application that might be waiting on input.</summary>
+    public static void Wakeup () { MainLoop?.Wakeup (); }
+
+    /// <summary>Triggers a refresh of the entire display.</summary>
+    public static void Refresh ()
+    {
+        // TODO: Figure out how to remove this call to ClearContents. Refresh should just repaint damaged areas, not clear
+        Driver.ClearContents ();
+        View last = null;
+
+        foreach (Toplevel v in _topLevels.Reverse ())
+        {
+            if (v.Visible)
+            {
+                v.SetNeedsDisplay ();
+                v.SetSubViewNeedsDisplay ();
+                v.Draw ();
+            }
+
+            last = v;
+        }
+
+        Driver.Refresh ();
+    }
+
+    /// <summary>This event is raised on each iteration of the main loop.</summary>
+    /// <remarks>See also <see cref="Timeout"/></remarks>
+    public static event EventHandler<IterationEventArgs> Iteration;
+
+    /// <summary>The <see cref="MainLoop"/> driver for the application</summary>
+    /// <value>The main loop.</value>
+    internal static MainLoop MainLoop { get; private set; }
+
+    /// <summary>
+    ///     Set to true to cause <see cref="End"/> to be called after the first iteration. Set to false (the default) to
+    ///     cause the application to continue running until Application.RequestStop () is called.
+    /// </summary>
+    public static bool EndAfterFirstIteration { get; set; }
+
+    /// <summary>Building block API: Runs the main loop for the created <see cref="Toplevel"/>.</summary>
+    /// <param name="state">The state returned by the <see cref="Begin(Toplevel)"/> method.</param>
+    public static void RunLoop (RunState state)
+    {
+        ArgumentNullException.ThrowIfNull (state);
+        ObjectDisposedException.ThrowIf (state.Toplevel is null, "state");
+
+        var firstIteration = true;
+
+        for (state.Toplevel.Running = true; state.Toplevel?.Running == true;)
+        {
+            MainLoop.Running = true;
+
+            if (EndAfterFirstIteration && !firstIteration)
+            {
+                return;
+            }
+
+            RunIteration (ref state, ref firstIteration);
+        }
+
+        MainLoop.Running = false;
+
+        // Run one last iteration to consume any outstanding input events from Driver
+        // This is important for remaining OnKeyUp events.
+        RunIteration (ref state, ref firstIteration);
+    }
+
+    /// <summary>Run one application iteration.</summary>
+    /// <param name="state">The state returned by <see cref="Begin(Toplevel)"/>.</param>
+    /// <param name="firstIteration">
+    ///     Set to <see langword="true"/> if this is the first run loop iteration. Upon return, it
+    ///     will be set to <see langword="false"/> if at least one iteration happened.
+    /// </param>
+    public static void RunIteration (ref RunState state, ref bool firstIteration)
+    {
+        if (MainLoop.Running && MainLoop.EventsPending ())
+        {
+            // Notify Toplevel it's ready
+            if (firstIteration)
+            {
+                state.Toplevel.OnReady ();
+            }
+
+            MainLoop.RunIteration ();
+            Iteration?.Invoke (null, new ());
+            EnsureModalOrVisibleAlwaysOnTop (state.Toplevel);
+
+            if (state.Toplevel != Current)
+            {
+                OverlappedTop?.OnDeactivate (state.Toplevel);
+                state.Toplevel = Current;
+                OverlappedTop?.OnActivate (state.Toplevel);
+                Top.SetSubViewNeedsDisplay ();
+                Refresh ();
+            }
+        }
+
+        firstIteration = false;
+
+        if (Current == null)
+        {
+            return;
+        }
+
+        if (state.Toplevel != Top && (Top.NeedsDisplay || Top.SubViewNeedsDisplay || Top.LayoutNeeded))
+        {
+            state.Toplevel.SetNeedsDisplay (state.Toplevel.Frame);
+            Top.Draw ();
+
+            foreach (Toplevel top in _topLevels.Reverse ())
+            {
+                if (top != Top && top != state.Toplevel)
+                {
+                    top.SetNeedsDisplay ();
+                    top.SetSubViewNeedsDisplay ();
+                    top.Draw ();
+                }
+            }
+        }
+
+        if (_topLevels.Count == 1
+            && state.Toplevel == Top
+            && (Driver.Cols != state.Toplevel.Frame.Width
+                || Driver.Rows != state.Toplevel.Frame.Height)
+            && (state.Toplevel.NeedsDisplay
+                || state.Toplevel.SubViewNeedsDisplay
+                || state.Toplevel.LayoutNeeded))
+        {
+            Driver.ClearContents ();
+        }
+
+        if (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded || OverlappedChildNeedsDisplay ())
+        {
+            state.Toplevel.SetNeedsDisplay ();
+            state.Toplevel.Draw ();
+            Driver.UpdateScreen ();
+
+            //Driver.UpdateCursor ();
+        }
+
+        if (PositionCursor (state.Toplevel))
+        {
+            Driver.UpdateCursor ();
+        }
+
+        //        else
+        {
+            //if (PositionCursor (state.Toplevel))
+            //{
+            //    Driver.Refresh ();
+            //}
+            //Driver.UpdateCursor ();
+        }
+
+        if (state.Toplevel != Top && !state.Toplevel.Modal && (Top.NeedsDisplay || Top.SubViewNeedsDisplay || Top.LayoutNeeded))
+        {
+            Top.Draw ();
+        }
+    }
+
+    /// <summary>Stops the provided <see cref="Toplevel"/>, causing or the <paramref name="top"/> if provided.</summary>
+    /// <param name="top">The <see cref="Toplevel"/> to stop.</param>
+    /// <remarks>
+    ///     <para>This will cause <see cref="Application.Run(Toplevel, Func{Exception, bool})"/> to return.</para>
+    ///     <para>
+    ///         Calling <see cref="RequestStop(Terminal.Gui.Toplevel)"/> is equivalent to setting the <see cref="Toplevel.Running"/>
+    ///         property on the currently running <see cref="Toplevel"/> to false.
+    ///     </para>
+    /// </remarks>
+    public static void RequestStop (Toplevel top = null)
+    {
+        if (OverlappedTop is null || top is null || (OverlappedTop is null && top is { }))
+        {
+            top = Current;
+        }
+
+        if (OverlappedTop != null
+            && top.IsOverlappedContainer
+            && top?.Running == true
+            && (Current?.Modal == false || (Current?.Modal == true && Current?.Running == false)))
+        {
+            OverlappedTop.RequestStop ();
+        }
+        else if (OverlappedTop != null
+                 && top != Current
+                 && Current?.Running == true
+                 && Current?.Modal == true
+                 && top.Modal
+                 && top.Running)
+        {
+            var ev = new ToplevelClosingEventArgs (Current);
+            Current.OnClosing (ev);
+
+            if (ev.Cancel)
+            {
+                return;
+            }
+
+            ev = new (top);
+            top.OnClosing (ev);
+
+            if (ev.Cancel)
+            {
+                return;
+            }
+
+            Current.Running = false;
+            OnNotifyStopRunState (Current);
+            top.Running = false;
+            OnNotifyStopRunState (top);
+        }
+        else if ((OverlappedTop != null
+                  && top != OverlappedTop
+                  && top != Current
+                  && Current?.Modal == false
+                  && Current?.Running == true
+                  && !top.Running)
+                 || (OverlappedTop != null
+                     && top != OverlappedTop
+                     && top != Current
+                     && Current?.Modal == false
+                     && Current?.Running == false
+                     && !top.Running
+                     && _topLevels.ToArray () [1].Running))
+        {
+            MoveCurrent (top);
+        }
+        else if (OverlappedTop != null
+                 && Current != top
+                 && Current?.Running == true
+                 && !top.Running
+                 && Current?.Modal == true
+                 && top.Modal)
+        {
+            // The Current and the top are both modal so needed to set the Current.Running to false too.
+            Current.Running = false;
+            OnNotifyStopRunState (Current);
+        }
+        else if (OverlappedTop != null
+                 && Current == top
+                 && OverlappedTop?.Running == true
+                 && Current?.Running == true
+                 && top.Running
+                 && Current?.Modal == true
+                 && top.Modal)
+        {
+            // The OverlappedTop was requested to stop inside a modal Toplevel which is the Current and top,
+            // both are the same, so needed to set the Current.Running to false too.
+            Current.Running = false;
+            OnNotifyStopRunState (Current);
+        }
+        else
+        {
+            Toplevel currentTop;
+
+            if (top == Current || (Current?.Modal == true && !top.Modal))
+            {
+                currentTop = Current;
+            }
+            else
+            {
+                currentTop = top;
+            }
+
+            if (!currentTop.Running)
+            {
+                return;
+            }
+
+            var ev = new ToplevelClosingEventArgs (currentTop);
+            currentTop.OnClosing (ev);
+
+            if (ev.Cancel)
+            {
+                return;
+            }
+
+            currentTop.Running = false;
+            OnNotifyStopRunState (currentTop);
+        }
+    }
+
+    private static void OnNotifyStopRunState (Toplevel top)
+    {
+        if (EndAfterFirstIteration)
+        {
+            NotifyStopRunState?.Invoke (top, new (top));
+        }
+    }
+
+    /// <summary>
+    ///     Building block API: completes the execution of a <see cref="Toplevel"/> that was started with
+    ///     <see cref="Begin(Toplevel)"/> .
+    /// </summary>
+    /// <param name="runState">The <see cref="RunState"/> returned by the <see cref="Begin(Toplevel)"/> method.</param>
+    public static void End (RunState runState)
+    {
+        ArgumentNullException.ThrowIfNull (runState);
+
+        if (OverlappedTop is { })
+        {
+            OverlappedTop.OnChildUnloaded (runState.Toplevel);
+        }
+        else
+        {
+            runState.Toplevel.OnUnloaded ();
+        }
+
+        // End the RunState.Toplevel
+        // First, take it off the Toplevel Stack
+        if (_topLevels.Count > 0)
+        {
+            if (_topLevels.Peek () != runState.Toplevel)
+            {
+                // If the top of the stack is not the RunState.Toplevel then
+                // this call to End is not balanced with the call to Begin that started the RunState
+                throw new ArgumentException ("End must be balanced with calls to Begin");
+            }
+
+            _topLevels.Pop ();
+        }
+
+        // Notify that it is closing
+        runState.Toplevel?.OnClosed (runState.Toplevel);
+
+        // If there is a OverlappedTop that is not the RunState.Toplevel then RunState.Toplevel
+        // is a child of MidTop, and we should notify the OverlappedTop that it is closing
+        if (OverlappedTop is { } && !runState.Toplevel.Modal && runState.Toplevel != OverlappedTop)
+        {
+            OverlappedTop.OnChildClosed (runState.Toplevel);
+        }
+
+        // Set Current and Top to the next TopLevel on the stack
+        if (_topLevels.Count == 0)
+        {
+            Current = null;
+        }
+        else
+        {
+            if (_topLevels.Count > 1 && _topLevels.Peek () == OverlappedTop && OverlappedChildren.Any (t => t.Visible) is { })
+            {
+                OverlappedMoveNext ();
+            }
+
+            Current = _topLevels.Peek ();
+
+            if (_topLevels.Count == 1 && Current == OverlappedTop)
+            {
+                OverlappedTop.OnAllChildClosed ();
+            }
+            else
+            {
+                SetCurrentOverlappedAsTop ();
+                runState.Toplevel.OnLeave (Current);
+                Current.OnEnter (runState.Toplevel);
+            }
+
+            Refresh ();
+        }
+
+        // Don't dispose runState.Toplevel. It's up to caller dispose it
+        // If it's not the same as the current in the RunIteration,
+        // it will be fixed later in the next RunIteration.
+        if (OverlappedTop is { } && !_topLevels.Contains (OverlappedTop))
+        {
+            _cachedRunStateToplevel = OverlappedTop;
+        }
+        else
+        {
+            _cachedRunStateToplevel = runState.Toplevel;
+        }
+
+        runState.Toplevel = null;
+        runState.Dispose ();
+    }
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 5 - 1095
Terminal.Gui/Application/Application.cs


+ 11 - 22
Terminal.Gui/Clipboard/Clipboard.cs

@@ -31,11 +31,11 @@ public static class Clipboard
             {
                 if (IsSupported)
                 {
-                    string clipData = Application.Driver.Clipboard.GetClipboardData ();
+                    string clipData = Application.Driver?.Clipboard.GetClipboardData ();
 
                     if (clipData is null)
                     {
-                        // throw new InvalidOperationException ($"{Application.Driver.GetType ().Name}.GetClipboardData returned null instead of string.Empty");
+                        // throw new InvalidOperationException ($"{Application.Driver?.GetType ().Name}.GetClipboardData returned null instead of string.Empty");
                         clipData = string.Empty;
                     }
 
@@ -60,7 +60,7 @@ public static class Clipboard
                         value = string.Empty;
                     }
 
-                    Application.Driver.Clipboard.SetClipboardData (value);
+                    Application.Driver?.Clipboard.SetClipboardData (value);
                 }
 
                 _contents = value;
@@ -74,19 +74,16 @@ public static class Clipboard
 
     /// <summary>Returns true if the environmental dependencies are in place to interact with the OS clipboard.</summary>
     /// <remarks></remarks>
-    public static bool IsSupported => Application.Driver.Clipboard.IsSupported;
+    public static bool IsSupported => Application.Driver?.Clipboard.IsSupported ?? false;
 
     /// <summary>Copies the _contents of the OS clipboard to <paramref name="result"/> if possible.</summary>
     /// <param name="result">The _contents of the OS clipboard if successful, <see cref="string.Empty"/> if not.</param>
     /// <returns><see langword="true"/> the OS clipboard was retrieved, <see langword="false"/> otherwise.</returns>
     public static bool TryGetClipboardData (out string result)
     {
-        if (IsSupported && Application.Driver.Clipboard.TryGetClipboardData (out result))
+        if (IsSupported && Application.Driver!.Clipboard.TryGetClipboardData (out result))
         {
-            if (_contents != result)
-            {
-                _contents = result;
-            }
+            _contents = result;
 
             return true;
         }
@@ -101,7 +98,7 @@ public static class Clipboard
     /// <returns><see langword="true"/> the OS clipboard was set, <see langword="false"/> otherwise.</returns>
     public static bool TrySetClipboardData (string text)
     {
-        if (IsSupported && Application.Driver.Clipboard.TrySetClipboardData (text))
+        if (IsSupported && Application.Driver!.Clipboard.TrySetClipboardData (text))
         {
             _contents = text;
 
@@ -155,7 +152,7 @@ internal static class ClipboardProcessRunner
 
         using (var process = new Process
                {
-                   StartInfo = new ProcessStartInfo
+                   StartInfo = new()
                    {
                        FileName = cmd,
                        Arguments = arguments,
@@ -191,17 +188,9 @@ internal static class ClipboardProcessRunner
 
             if (process.ExitCode > 0)
             {
-                output = $@"Process failed to run. Command line: {
-                    cmd
-                } {
-                    arguments
-                }.
-										Output: {
-                                            output
-                                        }
-										Error: {
-                                            process.StandardError.ReadToEnd ()
-                                        }";
+                output = $@"Process failed to run. Command line: {cmd} {arguments}.
+										Output: {output}
+										Error: {process.StandardError.ReadToEnd ()}";
             }
 
             return (process.ExitCode, output);

+ 3 - 3
Terminal.Gui/Drawing/LineCanvas.cs

@@ -336,7 +336,7 @@ public class LineCanvas : IDisposable
         return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) : intersects [0]!.Line.Attribute;
     }
 
-    private Cell? GetCellForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
+    private Cell? GetCellForIntersects (ConsoleDriver? driver, IntersectionDefinition? [] intersects)
     {
         if (!intersects.Any ())
         {
@@ -356,7 +356,7 @@ public class LineCanvas : IDisposable
         return cell;
     }
 
-    private Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
+    private Rune? GetRuneForIntersects (ConsoleDriver? driver, IntersectionDefinition? [] intersects)
     {
         if (!intersects.Any ())
         {
@@ -679,7 +679,7 @@ public class LineCanvas : IDisposable
         internal Rune _thickV;
         public IntersectionRuneResolver () { SetGlyphs (); }
 
-        public Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
+        public Rune? GetRuneForIntersects (ConsoleDriver? driver, IntersectionDefinition? [] intersects)
         {
             bool useRounded = intersects.Any (
                                               i => i?.Line.Length != 0

+ 4 - 4
Terminal.Gui/Drawing/Ruler.cs

@@ -39,8 +39,8 @@ public class Ruler
                 _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);
+            Application.Driver?.Move (location.X, location.Y);
+            Application.Driver?.AddStr (hrule);
         }
         else
         {
@@ -50,8 +50,8 @@ public 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]);
+                Application.Driver?.Move (location.X, r);
+                Application.Driver?.AddRune ((Rune)vrule [r - location.Y]);
             }
         }
     }

+ 9 - 5
Terminal.Gui/Drawing/Thickness.cs

@@ -119,20 +119,20 @@ public record struct Thickness
         // Draw the Top side
         if (Top > 0)
         {
-            Application.Driver.FillRect (rect with { Height = Math.Min (rect.Height, Top) }, topChar);
+            Application.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);
+            Application.Driver?.FillRect (rect with { Width = Math.Min (rect.Width, Left) }, leftChar);
         }
 
         // Draw the Right side
         if (Right > 0)
         {
-            Application.Driver.FillRect (
+            Application.Driver?.FillRect (
                                          rect with
                                          {
                                              X = Math.Max (0, rect.X + rect.Width - Right),
@@ -145,7 +145,7 @@ public record struct Thickness
         // Draw the Bottom side
         if (Bottom > 0)
         {
-            Application.Driver.FillRect (
+            Application.Driver?.FillRect (
                                          rect with
                                          {
                                              Y = rect.Y + Math.Max (0, rect.Height - Bottom),
@@ -197,7 +197,11 @@ public record struct Thickness
                 VerticalAlignment = Alignment.End,
                 AutoSize = true
             };
-            tf.Draw (rect, Application.Driver.CurrentAttribute, Application.Driver.CurrentAttribute, rect);
+
+            if (Application.Driver?.CurrentAttribute is { })
+            {
+                tf.Draw (rect, Application.Driver!.CurrentAttribute, Application.Driver!.CurrentAttribute, rect);
+            }
         }
 
         return GetInside (rect);

+ 2 - 2
Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs

@@ -106,7 +106,7 @@ public class AppendAutocomplete : AutocompleteBase
         }
 
         // draw it like it's selected, even though it's not
-        Application.Driver.SetAttribute (
+        Application.Driver?.SetAttribute (
                                          new Attribute (
                                                         ColorScheme.Normal.Foreground,
                                                         textField.ColorScheme.Focus.Background
@@ -128,7 +128,7 @@ public class AppendAutocomplete : AutocompleteBase
                                   );
         }
 
-        Application.Driver.AddStr (fragment);
+        Application.Driver?.AddStr (fragment);
     }
 
     /// <summary>

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

@@ -376,18 +376,18 @@ public abstract partial class PopupAutocomplete : AutocompleteBase
         {
             if (i == SelectedIdx - ScrollOffset)
             {
-                Application.Driver.SetAttribute (ColorScheme.Focus);
+                Application.Driver?.SetAttribute (ColorScheme.Focus);
             }
             else
             {
-                Application.Driver.SetAttribute (ColorScheme.Normal);
+                Application.Driver?.SetAttribute (ColorScheme.Normal);
             }
 
             popup.Move (0, i);
 
             string text = TextFormatter.ClipOrPad (toRender [i].Title, width);
 
-            Application.Driver.AddStr (text);
+            Application.Driver?.AddStr (text);
         }
     }
 

+ 2 - 2
Terminal.Gui/View/Layout/Dim.cs

@@ -139,7 +139,7 @@ public abstract class Dim
     /// <summary>Creates a <see cref="Dim"/> object that tracks the Height of the specified <see cref="View"/>.</summary>
     /// <returns>The height <see cref="Dim"/> of the other <see cref="View"/>.</returns>
     /// <param name="view">The view that will be tracked.</param>
-    public static Dim Height (View view) { return new DimView (view, Dimension.Height); }
+    public static Dim Height (View? view) { return new DimView (view, Dimension.Height); }
 
     /// <summary>Creates a percentage <see cref="Dim"/> object that is a percentage of the width or height of the SuperView.</summary>
     /// <returns>The percent <see cref="Dim"/> object.</returns>
@@ -171,7 +171,7 @@ public abstract class Dim
     /// <summary>Creates a <see cref="Dim"/> object that tracks the Width of the specified <see cref="View"/>.</summary>
     /// <returns>The width <see cref="Dim"/> of the other <see cref="View"/>.</returns>
     /// <param name="view">The view that will be tracked.</param>
-    public static Dim Width (View view) { return new DimView (view, Dimension.Width); }
+    public static Dim Width (View? view) { return new DimView (view, Dimension.Width); }
 
     #endregion static Dim creation methods
 

+ 2 - 2
Terminal.Gui/View/Layout/DimView.cs

@@ -15,7 +15,7 @@ public class DimView : Dim
     /// </summary>
     /// <param name="view">The view the dimension is anchored to.</param>
     /// <param name="dimension">Indicates which dimension is tracked.</param>
-    public DimView (View view, Dimension dimension)
+    public DimView (View? view, Dimension dimension)
     {
         Target = view;
         Dimension = dimension;
@@ -35,7 +35,7 @@ public class DimView : Dim
     /// <summary>
     ///     Gets the View the dimension is anchored to.
     /// </summary>
-    public View Target { get; init; }
+    public View? Target { get; init; }
 
     /// <inheritdoc/>
     public override string ToString ()

+ 6 - 6
Terminal.Gui/View/Layout/Pos.cs

@@ -257,22 +257,22 @@ public abstract class Pos
     /// <summary>Creates a <see cref="Pos"/> object that tracks the Top (Y) position of the specified <see cref="View"/>.</summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos Top (View view) { return new PosView (view, Side.Top); }
+    public static Pos Top (View? view) { return new PosView (view, Side.Top); }
 
     /// <summary>Creates a <see cref="Pos"/> object that tracks the Top (Y) position of the specified <see cref="View"/>.</summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos Y (View view) { return new PosView (view, Side.Top); }
+    public static Pos Y (View? view) { return new PosView (view, Side.Top); }
 
     /// <summary>Creates a <see cref="Pos"/> object that tracks the Left (X) position of the specified <see cref="View"/>.</summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos Left (View view) { return new PosView (view, Side.Left); }
+    public static Pos Left (View? view) { return new PosView (view, Side.Left); }
 
     /// <summary>Creates a <see cref="Pos"/> object that tracks the Left (X) position of the specified <see cref="View"/>.</summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos X (View view) { return new PosView (view, Side.Left); }
+    public static Pos X (View? view) { return new PosView (view, Side.Left); }
 
     /// <summary>
     ///     Creates a <see cref="Pos"/> object that tracks the Bottom (Y+Height) coordinate of the specified
@@ -280,7 +280,7 @@ public abstract class Pos
     /// </summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos Bottom (View view) { return new PosView (view, Side.Bottom); }
+    public static Pos Bottom (View? view) { return new PosView (view, Side.Bottom); }
 
     /// <summary>
     ///     Creates a <see cref="Pos"/> object that tracks the Right (X+Width) coordinate of the specified
@@ -288,7 +288,7 @@ public abstract class Pos
     /// </summary>
     /// <returns>The <see cref="Pos"/> that depends on the other view.</returns>
     /// <param name="view">The <see cref="View"/>  that will be tracked.</param>
-    public static Pos Right (View view) { return new PosView (view, Side.Right); }
+    public static Pos Right (View? view) { return new PosView (view, Side.Right); }
 
     #endregion static Pos creation methods
 

+ 2 - 2
Terminal.Gui/View/Layout/PosView.cs

@@ -12,12 +12,12 @@ namespace Terminal.Gui;
 /// </remarks>
 /// <param name="view">The View the position is anchored to.</param>
 /// <param name="side">The side of the View the position is anchored to.</param>
-public class PosView (View view, Side side) : Pos
+public class PosView (View? view, Side side) : Pos
 {
     /// <summary>
     ///     Gets the View the position is anchored to.
     /// </summary>
-    public View Target { get; } = view;
+    public View? Target { get; } = view;
 
     /// <summary>
     ///     Gets the side of the View the position is anchored to.

+ 2 - 2
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -398,7 +398,7 @@ public partial class View
     ///     Either <see cref="Application.Top"/> (if <paramref name="viewToMove"/> does not have a Super View) or
     ///     <paramref name="viewToMove"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
     /// </returns>
-    internal static View GetLocationEnsuringFullVisibility (
+    internal static View? GetLocationEnsuringFullVisibility (
         View viewToMove,
         int targetX,
         int targetY,
@@ -408,7 +408,7 @@ public partial class View
     )
     {
         int maxDimension;
-        View superView;
+        View? superView;
         statusBar = null!;
 
         if (viewToMove?.SuperView is null || viewToMove == Application.Top || viewToMove?.SuperView == Application.Top)

+ 4 - 4
Terminal.Gui/View/ViewDrawing.cs

@@ -288,19 +288,19 @@ public partial class View
     public void DrawHotString (string text, Attribute hotColor, Attribute normalColor)
     {
         Rune hotkeySpec = HotKeySpecifier == (Rune)0xffff ? (Rune)'_' : HotKeySpecifier;
-        Application.Driver.SetAttribute (normalColor);
+        Application.Driver?.SetAttribute (normalColor);
 
         foreach (Rune rune in text.EnumerateRunes ())
         {
             if (rune == new Rune (hotkeySpec.Value))
             {
-                Application.Driver.SetAttribute (hotColor);
+                Application.Driver?.SetAttribute (hotColor);
 
                 continue;
             }
 
-            Application.Driver.AddRune (rune);
-            Application.Driver.SetAttribute (normalColor);
+            Application.Driver?.AddRune (rune);
+            Application.Driver?.SetAttribute (normalColor);
         }
     }
 

+ 3 - 3
Terminal.Gui/Views/GraphView/Annotations.cs

@@ -133,7 +133,7 @@ public class LegendAnnotation : View, IAnnotation
     {
         if (!IsInitialized)
         {
-            ColorScheme = new ColorScheme { Normal = Application.Driver.GetAttribute () };
+            ColorScheme = new ColorScheme { Normal = Application.Driver?.GetAttribute () ?? Attribute.Default};
             graph.Add (this);
         }
 
@@ -149,7 +149,7 @@ public class LegendAnnotation : View, IAnnotation
         {
             if (entry.Item1.Color.HasValue)
             {
-                Application.Driver.SetAttribute (entry.Item1.Color.Value);
+                Application.Driver?.SetAttribute (entry.Item1.Color.Value);
             }
             else
             {
@@ -166,7 +166,7 @@ public class LegendAnnotation : View, IAnnotation
             Move (1, linesDrawn);
 
             string str = TextFormatter.ClipOrPad (entry.Item2, Viewport.Width - 1);
-            Application.Driver.AddStr (str);
+            Application.Driver?.AddStr (str);
 
             linesDrawn++;
 

+ 7 - 7
Terminal.Gui/Views/GraphView/Axis.cs

@@ -103,7 +103,7 @@ public class HorizontalAxis : Axis
         graph.Move (screenPosition, y);
 
         // draw the tick on the axis
-        Application.Driver.AddRune (Glyphs.TopTee);
+        Application.Driver?.AddRune (Glyphs.TopTee);
 
         // and the label text
         if (!string.IsNullOrWhiteSpace (text))
@@ -161,7 +161,7 @@ public class HorizontalAxis : Axis
             }
 
             graph.Move (graph.Viewport.Width / 2 - toRender.Length / 2, graph.Viewport.Height - 1);
-            Application.Driver.AddStr (toRender);
+            Application.Driver?.AddStr (toRender);
         }
     }
 
@@ -222,7 +222,7 @@ public class HorizontalAxis : Axis
     protected override void DrawAxisLine (GraphView graph, int x, int y)
     {
         graph.Move (x, y);
-        Application.Driver.AddRune (Glyphs.HLine);
+        Application.Driver?.AddRune (Glyphs.HLine);
     }
 
     private IEnumerable<AxisIncrementToRender> GetLabels (GraphView graph, Rectangle viewport)
@@ -298,13 +298,13 @@ public class VerticalAxis : Axis
         graph.Move (x, screenPosition);
 
         // draw the tick on the axis
-        Application.Driver.AddRune (Glyphs.RightTee);
+        Application.Driver?.AddRune (Glyphs.RightTee);
 
         // and the label text
         if (!string.IsNullOrWhiteSpace (text))
         {
             graph.Move (Math.Max (0, x - labelThickness), screenPosition);
-            Application.Driver.AddStr (text);
+            Application.Driver?.AddStr (text);
         }
     }
 
@@ -342,7 +342,7 @@ public class VerticalAxis : Axis
             for (var i = 0; i < toRender.Length; i++)
             {
                 graph.Move (0, startDrawingAtY + i);
-                Application.Driver.AddRune ((Rune)toRender [i]);
+                Application.Driver?.AddRune ((Rune)toRender [i]);
             }
         }
     }
@@ -395,7 +395,7 @@ public class VerticalAxis : Axis
     protected override void DrawAxisLine (GraphView graph, int x, int y)
     {
         graph.Move (x, y);
-        Application.Driver.AddRune (Glyphs.VLine);
+        Application.Driver?.AddRune (Glyphs.VLine);
     }
 
     private int GetAxisYEnd (GraphView graph)

+ 2 - 2
Terminal.Gui/Views/GraphView/Series.cs

@@ -33,7 +33,7 @@ public class ScatterSeries : ISeries
     {
         if (Fill.Color.HasValue)
         {
-            Application.Driver.SetAttribute (Fill.Color.Value);
+            Application.Driver?.SetAttribute (Fill.Color.Value);
         }
 
         foreach (PointF p in Points.Where (p => graphBounds.Contains (p)))
@@ -261,7 +261,7 @@ public class BarSeries : ISeries
 
         if (adjusted.Color.HasValue)
         {
-            Application.Driver.SetAttribute (adjusted.Color.Value);
+            Application.Driver?.SetAttribute (adjusted.Color.Value);
         }
 
         graph.DrawLine (start, end, adjusted.Rune);

+ 1 - 1
Terminal.Gui/Views/Menu/ContextMenu.cs

@@ -144,7 +144,7 @@ public sealed class ContextMenu : IDisposable
         _container = Application.Current;
         _container.Closing += Container_Closing;
         _container.Deactivate += Container_Deactivate;
-        Rectangle frame = Application.Driver.Screen;
+        Rectangle frame = Application.Driver?.Screen ?? Rectangle.Empty;
         Point position = Position;
 
         if (Host is { })

+ 6 - 6
Terminal.Gui/Views/RadioGroup.cs

@@ -278,7 +278,7 @@ public class RadioGroup : View, IDesignable
 
                     if (j == hotPos && i == _cursor)
                     {
-                        Application.Driver.SetAttribute (
+                        Application.Driver?.SetAttribute (
                                                          HasFocus
                                                              ? ColorScheme.HotFocus
                                                              : GetHotNormalColor ()
@@ -286,11 +286,11 @@ public class RadioGroup : View, IDesignable
                     }
                     else if (j == hotPos && i != _cursor)
                     {
-                        Application.Driver.SetAttribute (GetHotNormalColor ());
+                        Application.Driver?.SetAttribute (GetHotNormalColor ());
                     }
                     else if (HasFocus && i == _cursor)
                     {
-                        Application.Driver.SetAttribute (ColorScheme.Focus);
+                        Application.Driver?.SetAttribute (ColorScheme.Focus);
                     }
 
                     if (rune == HotKeySpecifier && j + 1 < rlRunes.Length)
@@ -300,7 +300,7 @@ public class RadioGroup : View, IDesignable
 
                         if (i == _cursor)
                         {
-                            Application.Driver.SetAttribute (
+                            Application.Driver?.SetAttribute (
                                                              HasFocus
                                                                  ? ColorScheme.HotFocus
                                                                  : GetHotNormalColor ()
@@ -308,11 +308,11 @@ public class RadioGroup : View, IDesignable
                         }
                         else if (i != _cursor)
                         {
-                            Application.Driver.SetAttribute (GetHotNormalColor ());
+                            Application.Driver?.SetAttribute (GetHotNormalColor ());
                         }
                     }
 
-                    Application.Driver.AddRune (rune);
+                    Application.Driver?.AddRune (rune);
                     Driver.SetAttribute (GetNormalColor ());
                 }
             }

+ 14 - 14
UICatalog/Scenarios/CombiningMarks.cs

@@ -15,20 +15,20 @@ public class CombiningMarks : Scenario
 
         top.DrawContentComplete += (s, e) =>
                                    {
-                                       Application.Driver.Move (0, 0);
-                                       Application.Driver.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
-                                       Application.Driver.Move (0, 2);
-                                       Application.Driver.AddStr ("\u0301\u0301\u0328<- \"\\u301\\u301\\u328]\" using AddStr.");
-                                       Application.Driver.Move (0, 3);
-                                       Application.Driver.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u301\\u301\\u328]\" using AddStr.");
-                                       Application.Driver.Move (0, 4);
-                                       Application.Driver.AddRune ('[');
-                                       Application.Driver.AddRune ('a');
-                                       Application.Driver.AddRune ('\u0301');
-                                       Application.Driver.AddRune ('\u0301');
-                                       Application.Driver.AddRune ('\u0328');
-                                       Application.Driver.AddRune (']');
-                                       Application.Driver.AddStr ("<- \"[a\\u301\\u301\\u328]\" using AddRune for each.");
+                                       Application.Driver?.Move (0, 0);
+                                       Application.Driver?.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
+                                       Application.Driver?.Move (0, 2);
+                                       Application.Driver?.AddStr ("\u0301\u0301\u0328<- \"\\u301\\u301\\u328]\" using AddStr.");
+                                       Application.Driver?.Move (0, 3);
+                                       Application.Driver?.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u301\\u301\\u328]\" using AddStr.");
+                                       Application.Driver?.Move (0, 4);
+                                       Application.Driver?.AddRune ('[');
+                                       Application.Driver?.AddRune ('a');
+                                       Application.Driver?.AddRune ('\u0301');
+                                       Application.Driver?.AddRune ('\u0301');
+                                       Application.Driver?.AddRune ('\u0328');
+                                       Application.Driver?.AddRune (']');
+                                       Application.Driver?.AddStr ("<- \"[a\\u301\\u301\\u328]\" using AddRune for each.");
                                    };
 
         Application.Run (top);

+ 2 - 2
UICatalog/Scenarios/Images.cs

@@ -20,9 +20,9 @@ public class Images : Scenario
         Application.Init ();
         var win = new Window { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName()}" };
 
-        bool canTrueColor = Application.Driver.SupportsTrueColor;
+        bool canTrueColor = Application.Driver?.SupportsTrueColor ?? false;
 
-        var lblDriverName = new Label { X = 0, Y = 0, Text = $"Driver is {Application.Driver.GetType ().Name}" };
+        var lblDriverName = new Label { X = 0, Y = 0, Text = $"Driver is {Application.Driver?.GetType ().Name}" };
         win.Add (lblDriverName);
 
         var cbSupportsTrueColor = new CheckBox

+ 1 - 1
UICatalog/Scenarios/SendKeys.cs

@@ -86,7 +86,7 @@ public class SendKeys : Scenario
                                     ? (ConsoleKey)char.ToUpper (r)
                                     : (ConsoleKey)r;
 
-                Application.Driver.SendKeys (
+                Application.Driver?.SendKeys (
                                              r,
                                              ck,
                                              ckbShift.State == CheckState.Checked,

+ 1 - 1
UICatalog/Scenarios/TextEffectsScenario.cs

@@ -260,5 +260,5 @@ internal class GradientsView : View
         }
     }
 
-    private static void SetColor (Color color) { Application.Driver.SetAttribute (new (color, color)); }
+    private static void SetColor (Color color) { Application.Driver?.SetAttribute (new (color, color)); }
 }

+ 2 - 2
UICatalog/Scenarios/TrueColors.cs

@@ -19,11 +19,11 @@ public class TrueColors : Scenario
         var x = 2;
         var y = 1;
 
-        bool canTrueColor = Application.Driver.SupportsTrueColor;
+        bool canTrueColor = Application.Driver?.SupportsTrueColor ?? false;
 
         var lblDriverName = new Label
         {
-            X = x, Y = y++, Text = $"Current driver is {Application.Driver.GetType ().Name}"
+            X = x, Y = y++, Text = $"Current driver is {Application.Driver?.GetType ().Name}"
         };
         app.Add (lblDriverName);
         y++;

+ 1 - 1
UICatalog/Scenarios/VkeyPacketSimulator.cs

@@ -198,7 +198,7 @@ public class VkeyPacketSimulator : Scenario
                                                            char keyChar =
                                                                ConsoleKeyMapping.EncodeKeyCharForVKPacket (consoleKeyInfo);
 
-                                                           Application.Driver.SendKeys (
+                                                           Application.Driver?.SendKeys (
                                                                                         keyChar,
                                                                                         ConsoleKey.Packet,
                                                                                         consoleKeyInfo.Modifiers.HasFlag (ConsoleModifiers.Shift),

+ 2 - 2
UICatalog/UICatalog.cs

@@ -369,7 +369,7 @@ internal class UICatalogApp
     /// </summary>
     public class UICatalogTopLevel : Toplevel
     {
-        public ListView CategoryList;
+        public ListView? CategoryList;
         public MenuItem? MiForce16Colors;
         public MenuItem? MiIsMenuBorderDisabled;
         public MenuItem? MiIsMouseDisabled;
@@ -999,7 +999,7 @@ internal class UICatalogApp
                 Title = "Force _16 Colors",
                 Shortcut = (KeyCode)Key.F6,
                 Checked = Application.Force16Colors,
-                CanExecute = () => Application.Driver.SupportsTrueColor
+                CanExecute = () => Application.Driver?.SupportsTrueColor ?? false
             };
             MiForce16Colors.CheckType |= MenuItemCheckStyle.Checked;
 

+ 7 - 7
UnitTests/Application/ApplicationTests.cs

@@ -44,7 +44,7 @@ public class ApplicationTests
         Toplevel top = new ();
         Application.Begin (top);
         Assert.Equal (new (0, 0, 80, 25), Application.Top.Frame);
-        ((FakeDriver)Application.Driver).SetBufferSize (5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, 5);
         Assert.Equal (new (0, 0, 5, 5), Application.Top.Frame);
         top.Dispose ();
     }
@@ -134,7 +134,7 @@ public class ApplicationTests
         Application.Init (driverName: driverType.Name);
         Assert.NotNull (Application.Driver);
         Assert.NotEqual (driver, Application.Driver);
-        Assert.Equal (driverType, Application.Driver.GetType ());
+        Assert.Equal (driverType, Application.Driver?.GetType ());
         Shutdown ();
     }
 
@@ -565,8 +565,8 @@ public class ApplicationTests
         Assert.NotNull (Application.MainLoop);
 
         // FakeDriver is always 80x25
-        Assert.Equal (80, Application.Driver.Cols);
-        Assert.Equal (25, Application.Driver.Rows);
+        Assert.Equal (80, Application.Driver!.Cols);
+        Assert.Equal (25, Application.Driver!.Rows);
     }
 
     private void Pre_Init_State ()
@@ -695,7 +695,7 @@ public class ApplicationTests
         Application.ForceDriver = "FakeDriver";
 
         Application.Init ();
-        Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ());
+        Assert.Equal (typeof (FakeDriver), Application.Driver?.GetType ());
 
         Application.Iteration += (s, a) => { Application.RequestStop (); };
 
@@ -737,7 +737,7 @@ public class ApplicationTests
         Application.Iteration += (s, a) => { Application.RequestStop (); };
 
         Application.Run<TestToplevel> ();
-        Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ());
+        Assert.Equal (typeof (FakeDriver), Application.Driver?.GetType ());
 
         Application.Top.Dispose ();
         Shutdown ();
@@ -888,7 +888,7 @@ public class ApplicationTests
             Width = 5, Height = 5,
             Arrangement = ViewArrangement.Movable
         };
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
         RunState rs = Application.Begin (w);
 
         // Don't use visuals to test as style of border can change over time.

+ 5 - 2
UnitTests/Application/CursorTests.cs

@@ -141,7 +141,10 @@ public class CursorTests
 
         Assert.True (view.HasFocus);
         Assert.False (Application.PositionCursor (view));
-        Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
-        Assert.Equal (CursorVisibility.Invisible, cursor);
+
+        if (Application.Driver?.GetCursorVisibility (out CursorVisibility cursor) ?? false)
+        {
+            Assert.Equal (CursorVisibility.Invisible, cursor);
+        }
     }
 }

+ 2 - 2
UnitTests/Clipboard/ClipboardTests.cs

@@ -9,14 +9,14 @@ public class ClipboardTests
     [Fact, AutoInitShutdown (useFakeClipboard: true, fakeClipboardAlwaysThrowsNotSupportedException: true)]
     public void IClipboard_GetClipBoardData_Throws_NotSupportedException ()
     {
-        var iclip = Application.Driver.Clipboard;
+        var iclip = Application.Driver?.Clipboard;
         Assert.Throws<NotSupportedException> (() => iclip.GetClipboardData ());
     }
 
     [Fact, AutoInitShutdown (useFakeClipboard: true, fakeClipboardAlwaysThrowsNotSupportedException: true)]
     public void IClipboard_SetClipBoardData_Throws_NotSupportedException ()
     {
-        var iclip = Application.Driver.Clipboard;
+        var iclip = Application.Driver?.Clipboard;
         Assert.Throws<NotSupportedException> (() => iclip.SetClipboardData ("foo"));
     }
 

+ 4 - 4
UnitTests/ConsoleDrivers/ClipRegionTests.cs

@@ -26,8 +26,8 @@ public class ClipRegionTests
     {
         var driver = (ConsoleDriver)Activator.CreateInstance (driverType);
         Application.Init (driver);
-        Application.Driver.Rows = 25;
-        Application.Driver.Cols = 80;
+        Application.Driver!.Rows = 25;
+        Application.Driver!.Cols = 80;
 
         driver.Move (0, 0);
         driver.AddRune ('x');
@@ -94,8 +94,8 @@ public class ClipRegionTests
     {
         var driver = (ConsoleDriver)Activator.CreateInstance (driverType);
         Application.Init (driver);
-        Application.Driver.Rows = 10;
-        Application.Driver.Cols = 10;
+        Application.Driver!.Rows = 10;
+        Application.Driver!.Cols = 10;
 
         // positive
         Assert.True (driver.IsValidLocation (0, 0));

+ 1 - 1
UnitTests/ConsoleDrivers/ConsoleDriverTests.cs

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

+ 1 - 1
UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs

@@ -123,7 +123,7 @@ public class ConsoleKeyMappingTests
                                          if (iterations == 0)
                                          {
                                              var keyChar = ConsoleKeyMapping.EncodeKeyCharForVKPacket (consoleKeyInfo);
-                                             Application.Driver.SendKeys (keyChar, ConsoleKey.Packet, shift, alt, control);
+                                             Application.Driver?.SendKeys (keyChar, ConsoleKey.Packet, shift, alt, control);
                                          }
                                      };
             Application.Run ();

+ 10 - 10
UnitTests/Dialogs/MessageBoxTests.cs

@@ -125,7 +125,7 @@ public class MessageBoxTests
     public void Location_Default ()
     {
         int iterations = -1;
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -243,7 +243,7 @@ public class MessageBoxTests
         int iterations = -1;
         var top = new Toplevel ();
         top.BorderStyle = LineStyle.None;
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var btn =
             $"{
@@ -319,7 +319,7 @@ public class MessageBoxTests
         int iterations = -1;
         var top = new Toplevel ();
         top.BorderStyle = LineStyle.None;
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var btn =
             $"{
@@ -396,7 +396,7 @@ ffffffffffffffffffff
         int iterations = -1;
         var top = new Toplevel();
         top.BorderStyle = LineStyle.None;
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var btn =
             $"{
@@ -477,7 +477,7 @@ ffffffffffffffffffff
         int iterations = -1;
         var top = new Toplevel();
         top.BorderStyle = LineStyle.None;
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var btn =
             $"{
@@ -547,7 +547,7 @@ ffffffffffffffffffff
     public void Size_Default ()
     {
         int iterations = -1;
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -650,7 +650,7 @@ ffffffffffffffffffff
                 CM.Glyphs.RightBracket
             }";
 
-        ((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40 + 4, 8);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -737,7 +737,7 @@ ffffffffffffffffffff
     public void Size_Not_Default_Message (int height, int width, string message)
     {
         int iterations = -1;
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -774,7 +774,7 @@ ffffffffffffffffffff
     public void Size_Not_Default_Message_Button (int height, int width, string message)
     {
         int iterations = -1;
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -807,7 +807,7 @@ ffffffffffffffffffff
     public void Size_Not_Default_No_Message (int height, int width)
     {
         int iterations = -1;
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         Application.Iteration += (s, a) =>
                                  {

+ 5 - 5
UnitTests/Drawing/RulerTests.cs

@@ -29,7 +29,7 @@ public class RulerTests
     [AutoInitShutdown]
     public void Draw_Default ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (25, 25);
+        ((FakeDriver)Application.Driver!).SetBufferSize (25, 25);
 
         var r = new Ruler ();
         r.Draw (Point.Empty);
@@ -47,7 +47,7 @@ public class RulerTests
         var top = new Toplevel ();
         top.Add (f);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (len + 5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (len + 5, 5);
         Assert.Equal (new (0, 0, len + 5, 5), f.Frame);
 
         var r = new Ruler ();
@@ -121,7 +121,7 @@ public class RulerTests
         var top = new Toplevel ();
         top.Add (f);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (len + 5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (len + 5, 5);
         Assert.Equal (new (0, 0, len + 5, 5), f.Frame);
 
         var r = new Ruler ();
@@ -168,7 +168,7 @@ public class RulerTests
         var top = new Toplevel ();
         top.Add (f);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (5, len + 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, len + 5);
         Assert.Equal (new (0, 0, 5, len + 5), f.Frame);
 
         var r = new Ruler ();
@@ -302,7 +302,7 @@ public class RulerTests
         var top = new Toplevel ();
         top.Add (f);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (5, len + 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, len + 5);
         Assert.Equal (new (0, 0, 5, len + 5), f.Frame);
 
         var r = new Ruler ();

+ 10 - 10
UnitTests/Drawing/ThicknessTests.cs

@@ -51,13 +51,13 @@ public class ThicknessTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void DrawTests ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (60, 60);
+        ((FakeDriver)Application.Driver!).SetBufferSize (60, 60);
         var t = new Thickness (0, 0, 0, 0);
         var r = new Rectangle (5, 5, 40, 15);
         View.Diagnostics |= ViewDiagnosticFlags.Padding;
 
-        Application.Driver.FillRect (
-                                     new Rectangle (0, 0, Application.Driver.Cols, Application.Driver.Rows),
+        Application.Driver?.FillRect (
+                                     new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
                                      (Rune)' '
                                     );
         t.Draw (r, "Test");
@@ -73,8 +73,8 @@ public class ThicknessTests (ITestOutputHelper output)
         r = new Rectangle (5, 5, 40, 15);
         View.Diagnostics |= ViewDiagnosticFlags.Padding;
 
-        Application.Driver.FillRect (
-                                     new Rectangle (0, 0, Application.Driver.Cols, Application.Driver.Rows),
+        Application.Driver?.FillRect (
+                                     new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
                                      (Rune)' '
                                     );
         t.Draw (r, "Test");
@@ -104,8 +104,8 @@ public class ThicknessTests (ITestOutputHelper output)
         r = new Rectangle (5, 5, 40, 15);
         View.Diagnostics |= ViewDiagnosticFlags.Padding;
 
-        Application.Driver.FillRect (
-                                     new Rectangle (0, 0, Application.Driver.Cols, Application.Driver.Rows),
+        Application.Driver?.FillRect (
+                                     new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
                                      (Rune)' '
                                     );
         t.Draw (r, "Test");
@@ -135,8 +135,8 @@ public class ThicknessTests (ITestOutputHelper output)
         r = new Rectangle (5, 5, 40, 15);
         View.Diagnostics |= ViewDiagnosticFlags.Padding;
 
-        Application.Driver.FillRect (
-                                     new Rectangle (0, 0, Application.Driver.Cols, Application.Driver.Rows),
+        Application.Driver?.FillRect (
+                                     new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows),
                                      (Rune)' '
                                     );
         t.Draw (r, "Test");
@@ -174,7 +174,7 @@ public class ThicknessTests (ITestOutputHelper output)
         top.Add (f);
         Application.Begin (top);
 
-        ((FakeDriver)Application.Driver).SetBufferSize (45, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (45, 20);
         var t = new Thickness (0, 0, 0, 0);
         var r = new Rectangle (2, 2, 40, 15);
         Application.Refresh ();

+ 2 - 2
UnitTests/FileServices/FileDialogTests.cs

@@ -701,14 +701,14 @@ public class FileDialogTests (ITestOutputHelper output)
 
     private void Send (char ch, ConsoleKey ck, bool shift = false, bool alt = false, bool control = false)
     {
-        Application.Driver.SendKeys (ch, ck, shift, alt, control);
+        Application.Driver?.SendKeys (ch, ck, shift, alt, control);
     }
 
     private void Send (string chars)
     {
         foreach (char ch in chars)
         {
-            Application.Driver.SendKeys (ch, ConsoleKey.NoName, false, false, false);
+            Application.Driver?.SendKeys (ch, ConsoleKey.NoName, false, false, false);
         }
     }
 

+ 2 - 2
UnitTests/Text/TextFormatterTests.cs

@@ -451,7 +451,7 @@ ssb
     [SetupFakeDriver]
     public void FillRemaining_True_False ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (22, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (22, 5);
 
         Attribute [] attrs =
         {
@@ -6041,7 +6041,7 @@ B")]
             Text = text
         };
 
-        Application.Driver.FillRect (new Rectangle (0, 0, 7, 7), (Rune)'*');
+        Application.Driver?.FillRect (new Rectangle (0, 0, 7, 7), (Rune)'*');
         tf.Draw (new Rectangle (0, 0, 7, 7), Attribute.Default, Attribute.Default);
         TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
     }

+ 8 - 8
UnitTests/View/Adornment/BorderTests.cs

@@ -95,7 +95,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (width, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, 5);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -229,7 +229,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (width, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, 4);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -363,7 +363,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (width, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, 4);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -486,7 +486,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, height);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, height);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -548,7 +548,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (width, 3);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, 3);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -728,7 +728,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (top);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, 5);
         Application.RunIteration (ref rs, ref firstIteration);
 
         var expected = @"
@@ -756,7 +756,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (top);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
         Application.RunIteration (ref rs, ref firstIteration);
 
         var expected = @"
@@ -779,7 +779,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (3, 3);
+        ((FakeDriver)Application.Driver!).SetBufferSize (3, 3);
         Application.RunIteration (ref rs, ref firstIteration);
 
         var expected = @"

+ 1 - 1
UnitTests/View/Adornment/MarginTests.cs

@@ -8,7 +8,7 @@ public class MarginTests (ITestOutputHelper output)
     [SetupFakeDriver]
     public void Margin_Uses_SuperView_ColorScheme ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, 5);
         var view = new View { Height = 3, Width = 3 };
         view.Margin.Thickness = new (1);
 

+ 1 - 1
UnitTests/View/Adornment/PaddingTests.cs

@@ -8,7 +8,7 @@ public class PaddingTests (ITestOutputHelper output)
     [SetupFakeDriver]
     public void Padding_Uses_Parent_ColorScheme ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (5, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, 5);
         var view = new View { Height = 3, Width = 3 };
         view.Padding.Thickness = new (1);
 

+ 23 - 23
UnitTests/View/DrawTests.cs

@@ -22,13 +22,13 @@ public class DrawTests (ITestOutputHelper _output)
         // Only valid location w/in Viewport is 0, 0 (view) - 2, 2 (screen)
 
         view.Move (0, 0);
-        Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
+        Assert.Equal (new Point (2, 2), new Point (Application.Driver!.Col, Application.Driver!.Row));
 
         view.Move (-1, -1);
-        Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
+        Assert.Equal (new Point (2, 2), new Point (Application.Driver!.Col, Application.Driver!.Row));
 
         view.Move (1, 1);
-        Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
+        Assert.Equal (new Point (2, 2), new Point (Application.Driver!.Col, Application.Driver!.Row));
     }
 
     [Fact]
@@ -48,16 +48,16 @@ public class DrawTests (ITestOutputHelper _output)
         view.Draw ();
 
         // Only valid location w/in Viewport is 0, 0 (view) - 2, 2 (screen)
-        Assert.Equal ((Rune)' ', Application.Driver.Contents [2, 2].Rune);
+        Assert.Equal ((Rune)' ', Application.Driver?.Contents [2, 2].Rune);
 
         view.AddRune (0, 0, Rune.ReplacementChar);
-        Assert.Equal (Rune.ReplacementChar, Application.Driver.Contents [2, 2].Rune);
+        Assert.Equal (Rune.ReplacementChar, Application.Driver?.Contents [2, 2].Rune);
 
         view.AddRune (-1, -1, Rune.ReplacementChar);
-        Assert.Equal ((Rune)'M', Application.Driver.Contents [1, 1].Rune);
+        Assert.Equal ((Rune)'M', Application.Driver?.Contents [1, 1].Rune);
 
         view.AddRune (1, 1, Rune.ReplacementChar);
-        Assert.Equal ((Rune)'M', Application.Driver.Contents [3, 3].Rune);
+        Assert.Equal ((Rune)'M', Application.Driver?.Contents [3, 3].Rune);
 
         View.Diagnostics = ViewDiagnosticFlags.Off;
     }
@@ -250,7 +250,7 @@ public class DrawTests (ITestOutputHelper _output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
 
         const string expectedOutput = """
 
@@ -301,7 +301,7 @@ public class DrawTests (ITestOutputHelper _output)
         dg.Add (view);
         RunState rsTop = Application.Begin (top);
         RunState rsDiag = Application.Begin (dg);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 10);
 
         const string expectedOutput = """
 
@@ -354,7 +354,7 @@ public class DrawTests (ITestOutputHelper _output)
         top.Add (viewRight, viewBottom);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (7, 7);
+        ((FakeDriver)Application.Driver!).SetBufferSize (7, 7);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       """
@@ -394,7 +394,7 @@ public class DrawTests (ITestOutputHelper _output)
         var view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single };
         view.BeginInit ();
         view.EndInit ();
-        view.SetRelativeLayout (Application.Driver.Screen.Size);
+        view.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 2, 2), view.Frame);
         Assert.Equal (Rectangle.Empty, view.Viewport);
@@ -419,7 +419,7 @@ public class DrawTests (ITestOutputHelper _output)
         view.Border.Thickness = new Thickness (1, 1, 1, 0);
         view.BeginInit ();
         view.EndInit ();
-        view.SetRelativeLayout (Application.Driver.Screen.Size);
+        view.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 2, 1), view.Frame);
         Assert.Equal (Rectangle.Empty, view.Viewport);
@@ -437,7 +437,7 @@ public class DrawTests (ITestOutputHelper _output)
         view.Border.Thickness = new Thickness (0, 1, 1, 1);
         view.BeginInit ();
         view.EndInit ();
-        view.SetRelativeLayout (Application.Driver.Screen.Size);
+        view.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 1, 2), view.Frame);
         Assert.Equal (Rectangle.Empty, view.Viewport);
@@ -462,7 +462,7 @@ public class DrawTests (ITestOutputHelper _output)
         view.Border.Thickness = new Thickness (1, 1, 0, 1);
         view.BeginInit ();
         view.EndInit ();
-        view.SetRelativeLayout (Application.Driver.Screen.Size);
+        view.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 1, 2), view.Frame);
         Assert.Equal (Rectangle.Empty, view.Viewport);
@@ -488,7 +488,7 @@ public class DrawTests (ITestOutputHelper _output)
 
         view.BeginInit ();
         view.EndInit ();
-        view.SetRelativeLayout (Application.Driver.Screen.Size);
+        view.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 2, 1), view.Frame);
         Assert.Equal (Rectangle.Empty, view.Viewport);
@@ -561,7 +561,7 @@ public class DrawTests (ITestOutputHelper _output)
         container.Add (content);
         Toplevel top = new ();
         top.Add (container);
-        Application.Driver.Clip = container.Frame;
+        Application.Driver!.Clip = container.Frame;
         Application.Begin (top);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
@@ -727,7 +727,7 @@ public class DrawTests (ITestOutputHelper _output)
 
         return;
 
-        void Top_LayoutComplete (object? sender, LayoutEventArgs e) { Application.Driver.Clip = container.Frame; }
+        void Top_LayoutComplete (object? sender, LayoutEventArgs e) { Application.Driver!.Clip = container.Frame; }
     }
 
     [Fact]
@@ -767,7 +767,7 @@ public class DrawTests (ITestOutputHelper _output)
         container.Add (content);
         Toplevel top = new ();
         top.Add (container);
-        Application.Driver.Clip = container.Frame;
+        Application.Driver!.Clip = container.Frame;
         Application.Begin (top);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
@@ -889,7 +889,7 @@ public class DrawTests (ITestOutputHelper _output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
 
         var expected = """
 
@@ -928,13 +928,13 @@ public class DrawTests (ITestOutputHelper _output)
         view.Border.Thickness = new Thickness (1);
         view.BeginInit ();
         view.EndInit ();
-        Assert.Equal (view.Frame, Application.Driver.Clip);
+        Assert.Equal (view.Frame, Application.Driver?.Clip);
 
         // Act
         view.SetClip ();
 
         // Assert
-        Assert.Equal (expectedClip, Application.Driver.Clip);
+        Assert.Equal (expectedClip, Application.Driver?.Clip);
         view.Dispose ();
     }
 
@@ -960,14 +960,14 @@ public class DrawTests (ITestOutputHelper _output)
         view.Border.Thickness = new Thickness (1);
         view.BeginInit ();
         view.EndInit ();
-        Assert.Equal (view.Frame, Application.Driver.Clip);
+        Assert.Equal (view.Frame, Application.Driver?.Clip);
         view.Viewport = view.Viewport with { X = 1, Y = 1 };
 
         // Act
         view.SetClip ();
 
         // Assert
-        Assert.Equal (expectedClip, Application.Driver.Clip);
+        Assert.Equal (expectedClip, Application.Driver?.Clip);
         view.Dispose ();
     }
 

+ 1 - 1
UnitTests/View/Layout/Dim.FillTests.cs

@@ -14,7 +14,7 @@ public class DimFillTests (ITestOutputHelper output)
         var top = new Toplevel ();
         top.Add (view);
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (32, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (32, 5);
 
         //view.SetNeedsLayout ();
         top.LayoutSubviews ();

+ 1 - 1
UnitTests/View/Layout/Pos.AnchorEndTests.cs

@@ -184,7 +184,7 @@ public class PosAnchorEndTests (ITestOutputHelper output)
     [SetupFakeDriver]
     public void  PosAnchorEnd_View_And_Button ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 5);
 
         var b = $"{CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket}";
 

+ 2 - 2
UnitTests/View/Layout/Pos.CenterTests.cs

@@ -85,7 +85,7 @@ public class PosCenterTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, height);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, height);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 
@@ -232,7 +232,7 @@ public class PosCenterTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         var firstIteration = false;
 
-        ((FakeDriver)Application.Driver).SetBufferSize (width, 7);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, 7);
         Application.RunIteration (ref rs, ref firstIteration);
         var expected = string.Empty;
 

+ 1 - 1
UnitTests/View/Layout/ViewportTests.cs

@@ -472,7 +472,7 @@ public class ViewportTests (ITestOutputHelper output)
     //[InlineData (5, 5, false)]
     //public void IsVisibleInSuperView_With_Driver (int x, int y, bool expected)
     //{
-    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+    //    ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
 
     //    var view = new View { X = 1, Y = 1, Width = 5, Height = 5 };
     //    var top = new Toplevel ();

+ 7 - 7
UnitTests/View/NavigationTests.cs

@@ -669,7 +669,7 @@ public class NavigationTests (ITestOutputHelper output)
 //        Assert.False (tfQuiting);
 //        Assert.False (topQuiting);
 
-//        Application.Driver.SendKeys ('Q', ConsoleKey.Q, false, false, true);
+//        Application.Driver?.SendKeys ('Q', ConsoleKey.Q, false, false, true);
 //        Assert.False (sbQuiting);
 //        Assert.True (tfQuiting);
 //        Assert.False (topQuiting);
@@ -677,7 +677,7 @@ public class NavigationTests (ITestOutputHelper output)
 //#if BROKE_WITH_2927
 //        tf.KeyPressed -= Tf_KeyPress;
 //        tfQuiting = false;
-//        Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true);
+//        Application.Driver?.SendKeys ('q', ConsoleKey.Q, false, false, true);
 //        Application.MainLoop.RunIteration ();
 //        Assert.True (sbQuiting);
 //        Assert.False (tfQuiting);
@@ -685,7 +685,7 @@ public class NavigationTests (ITestOutputHelper output)
 
 //        sb.RemoveItem (0);
 //        sbQuiting = false;
-//        Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true);
+//        Application.Driver?.SendKeys ('q', ConsoleKey.Q, false, false, true);
 //        Application.MainLoop.RunIteration ();
 //        Assert.False (sbQuiting);
 //        Assert.False (tfQuiting);
@@ -733,13 +733,13 @@ public class NavigationTests (ITestOutputHelper output)
 //        Assert.False (sbQuiting);
 //        Assert.False (tfQuiting);
 
-//        Application.Driver.SendKeys ('Q', ConsoleKey.Q, false, false, true);
+//        Application.Driver?.SendKeys ('Q', ConsoleKey.Q, false, false, true);
 //        Assert.False (sbQuiting);
 //        Assert.True (tfQuiting);
 
 //        tf.KeyDown -= Tf_KeyPressed;
 //        tfQuiting = false;
-//        Application.Driver.SendKeys ('Q', ConsoleKey.Q, false, false, true);
+//        Application.Driver?.SendKeys ('Q', ConsoleKey.Q, false, false, true);
 //        Application.MainLoop.RunIteration ();
 //#if BROKE_WITH_2927
 //        Assert.True (sbQuiting);
@@ -834,7 +834,7 @@ public class NavigationTests (ITestOutputHelper output)
         Assert.Equal (new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows), top.Frame);
         Assert.Equal (new Rectangle (0, 0, 80, 25), top.Frame);
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
         Assert.Equal (new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows), top.Frame);
         Assert.Equal (new Rectangle (0, 0, 20, 10), top.Frame);
 
@@ -984,7 +984,7 @@ public class NavigationTests (ITestOutputHelper output)
         Assert.NotEqual (new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows), top.Frame);
         Assert.Equal (new Rectangle (3, 2, 20, 10), top.Frame);
 
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 20);
         Assert.Equal (new Rectangle (0, 0, 30, 20), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows));
         Assert.NotEqual (new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows), top.Frame);
         Assert.Equal (new Rectangle (3, 2, 20, 10), top.Frame);

+ 10 - 10
UnitTests/View/TextTests.cs

@@ -148,7 +148,7 @@ Y
         top.Add (win);
 
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (15, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (15, 15);
 
         Assert.Equal (new (0, 0, 15, 15), win.Frame);
         Assert.Equal (new (0, 0, 15, 15), win.Margin.Frame);
@@ -416,7 +416,7 @@ Y
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (4, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (4, 10);
 
         Assert.Equal (5, text.Length);
 
@@ -489,7 +489,7 @@ Y
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (4, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (4, 10);
 
         Assert.Equal (5, text.Length);
         Assert.Equal (new (0, 0, 2, 5), view.Frame);
@@ -584,7 +584,7 @@ Y
         var top = new Toplevel ();
         top.Add (win);
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 20);
 
         Assert.Equal (new (0, 0, 11, 2), horizontalView.Frame);
         Assert.Equal (new (0, 3, 2, 11), verticalView.Frame);
@@ -672,7 +672,7 @@ Y
         var top = new Toplevel ();
         top.Add (win);
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (22, 22);
+        ((FakeDriver)Application.Driver!).SetBufferSize (22, 22);
 
         Assert.Equal (new (text.GetColumns (), 1), horizontalView.TextFormatter.Size);
         Assert.Equal (new (2, 8), verticalView.TextFormatter.Size);
@@ -769,7 +769,7 @@ Y
 
             for (var i = 0; i < 4; i++)
             {
-                text += Application.Driver.Contents [0, i].Rune;
+                text += Application.Driver?.Contents [0, i].Rune;
             }
 
             return text;
@@ -804,7 +804,7 @@ Y
         var top = new Toplevel ();
         top.Add (horizontalView, verticalView);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (50, 50);
+        ((FakeDriver)Application.Driver!).SetBufferSize (50, 50);
 
         Assert.Equal (new (0, 0, 12, 1), horizontalView.Frame);
         Assert.Equal (new (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ());
@@ -900,7 +900,7 @@ Y
         var top = new Toplevel ();
         top.Add (frame);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width + 2, 6);
 
         if (autoSize)
         {
@@ -1028,7 +1028,7 @@ Y
         var top = new Toplevel ();
         top.Add (frame);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (9, height + 2);
+        ((FakeDriver)Application.Driver!).SetBufferSize (9, height + 2);
 
         if (autoSize)
         {
@@ -1272,7 +1272,7 @@ Y
     [SetupFakeDriver]
     public void Narrow_Wide_Runes ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (32, 32);
+        ((FakeDriver)Application.Driver!).SetBufferSize (32, 32);
         var top = new View { Width = 32, Height = 32 };
 
         var text = $"First line{Environment.NewLine}Second line";

+ 15 - 15
UnitTests/View/ViewTests.cs

@@ -14,26 +14,26 @@ public class ViewTests (ITestOutputHelper output)
 
         view.DrawContent += (s, e) =>
                             {
-                                Rectangle savedClip = Application.Driver.Clip;
-                                Application.Driver.Clip = new (1, 1, view.Viewport.Width, view.Viewport.Height);
+                                Rectangle savedClip = Application.Driver!.Clip;
+                                Application.Driver!.Clip = new (1, 1, view.Viewport.Width, view.Viewport.Height);
 
                                 for (var row = 0; row < view.Viewport.Height; row++)
                                 {
-                                    Application.Driver.Move (1, row + 1);
+                                    Application.Driver?.Move (1, row + 1);
 
                                     for (var col = 0; col < view.Viewport.Width; col++)
                                     {
-                                        Application.Driver.AddStr ($"{col}");
+                                        Application.Driver?.AddStr ($"{col}");
                                     }
                                 }
 
-                                Application.Driver.Clip = savedClip;
+                                Application.Driver!.Clip = savedClip;
                                 e.Cancel = true;
                             };
         var top = new Toplevel ();
         top.Add (view);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var expected = @"
 ┌──────────────────┐
@@ -78,26 +78,26 @@ public class ViewTests (ITestOutputHelper output)
 
         view.DrawContent += (s, e) =>
                             {
-                                Rectangle savedClip = Application.Driver.Clip;
-                                Application.Driver.Clip = new (1, 1, view.Viewport.Width, view.Viewport.Height);
+                                Rectangle savedClip = Application.Driver!.Clip;
+                                Application.Driver!.Clip = new (1, 1, view.Viewport.Width, view.Viewport.Height);
 
                                 for (var row = 0; row < view.Viewport.Height; row++)
                                 {
-                                    Application.Driver.Move (1, row + 1);
+                                    Application.Driver?.Move (1, row + 1);
 
                                     for (var col = 0; col < view.Viewport.Width; col++)
                                     {
-                                        Application.Driver.AddStr ($"{col}");
+                                        Application.Driver?.AddStr ($"{col}");
                                     }
                                 }
 
-                                Application.Driver.Clip = savedClip;
+                                Application.Driver!.Clip = savedClip;
                                 e.Cancel = true;
                             };
         var top = new Toplevel ();
         top.Add (view);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         var expected = @"
 ┌──────────────────┐
@@ -1016,7 +1016,7 @@ At 0,0
         view.Height = Dim.Auto ();
         Assert.Equal ("Testing visibility.".Length, view.Frame.Width);
         Assert.True (view.Visible);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"
@@ -1107,9 +1107,9 @@ At 0,0
             Cell [,] contents = ((FakeDriver)Application.Driver).Contents;
             var runesCount = 0;
 
-            for (var i = 0; i < Application.Driver.Rows; i++)
+            for (var i = 0; i < Application.Driver!.Rows; i++)
             {
-                for (var j = 0; j < Application.Driver.Cols; j++)
+                for (var j = 0; j < Application.Driver!.Cols; j++)
                 {
                     if (contents [i, j].Rune != (Rune)' ')
                     {

+ 18 - 18
UnitTests/Views/AppendAutocompleteTests.cs

@@ -11,14 +11,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting ("fish");
 
         // f is typed and suggestion is "fish"
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
         // When cancelling autocomplete
-        Application.Driver.SendKeys ('e', ConsoleKey.Escape, false, false, false);
+        Application.Driver?.SendKeys ('e', ConsoleKey.Escape, false, false, false);
 
         // Suggestion should disappear
         tf.Draw ();
@@ -29,7 +29,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         Assert.Same (tf, Application.Top.Focused);
 
         // But can tab away
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
         Assert.NotSame (tf, Application.Top.Focused);
         Application.Top.Dispose ();
     }
@@ -41,14 +41,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting ("fish");
 
         // f is typed and suggestion is "fish"
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
         // When cancelling autocomplete
-        Application.Driver.SendKeys ('\0', ConsoleKey.Escape, false, false, false);
+        Application.Driver?.SendKeys ('\0', ConsoleKey.Escape, false, false, false);
 
         // Suggestion should disappear
         tf.Draw ();
@@ -56,7 +56,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         Assert.Equal ("f", tf.Text);
 
         // Should reappear when you press next letter
-        Application.Driver.SendKeys ('i', ConsoleKey.I, false, false, false);
+        Application.Driver?.SendKeys ('i', ConsoleKey.I, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
@@ -73,14 +73,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting ("fish", "friend");
 
         // f is typed and suggestion is "fish"
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
         // When cycling autocomplete
-        Application.Driver.SendKeys (' ', cycleKey, false, false, false);
+        Application.Driver?.SendKeys (' ', cycleKey, false, false, false);
 
         tf.Draw ();
         tf.PositionCursor ();
@@ -88,7 +88,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         Assert.Equal ("f", tf.Text);
 
         // Should be able to cycle in circles endlessly
-        Application.Driver.SendKeys (' ', cycleKey, false, false, false);
+        Application.Driver?.SendKeys (' ', cycleKey, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
@@ -103,15 +103,15 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting ("fish");
 
         // f is typed and suggestion is "fish"
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
         // add a space then go back 1
-        Application.Driver.SendKeys (' ', ConsoleKey.Spacebar, false, false, false);
-        Application.Driver.SendKeys ('<', ConsoleKey.LeftArrow, false, false, false);
+        Application.Driver?.SendKeys (' ', ConsoleKey.Spacebar, false, false, false);
+        Application.Driver?.SendKeys ('<', ConsoleKey.LeftArrow, false, false, false);
 
         tf.Draw ();
         TestHelpers.AssertDriverContentsAre ("f", output);
@@ -126,14 +126,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting ("fish");
 
         // f is typed and suggestion is "fish"
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
         // x is typed and suggestion should disappear
-        Application.Driver.SendKeys ('x', ConsoleKey.X, false, false, false);
+        Application.Driver?.SendKeys ('x', ConsoleKey.X, false, false, false);
         tf.Draw ();
         TestHelpers.AssertDriverContentsAre ("fx", output);
         Assert.Equal ("fx", tf.Text);
@@ -166,7 +166,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         Assert.Equal ("my f", tf.Text);
 
         // When tab completing the case of the whole suggestion should be applied
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
         tf.Draw ();
         TestHelpers.AssertDriverContentsAre ("my FISH", output);
         Assert.Equal ("my FISH", tf.Text);
@@ -194,7 +194,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TestHelpers.AssertDriverContentsAre ("fish", output);
         Assert.Equal ("f", tf.Text);
 
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
 
         tf.Draw ();
         TestHelpers.AssertDriverContentsAre ("fish", output);
@@ -204,7 +204,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         Assert.Same (tf, Application.Top.Focused);
 
         // Second tab should move focus (nothing to autocomplete)
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
         Assert.NotSame (tf, Application.Top.Focused);
         Application.Top.Dispose ();
     }
@@ -219,7 +219,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInViewSuggesting (overspillUsing);
 
         // f is typed we should only see 'f' up to size of View (10)
-        Application.Driver.SendKeys ('f', ConsoleKey.F, false, false, false);
+        Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false);
         tf.Draw ();
         tf.PositionCursor ();
         TestHelpers.AssertDriverContentsAre (expectRender, output);

+ 3 - 3
UnitTests/Views/ButtonTests.cs

@@ -224,7 +224,7 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.Equal ('_', btn.HotKeySpecifier.Value);
         Assert.True (btn.CanFocus);
 
-        Application.Driver.ClearContents ();
+        Application.Driver?.ClearContents ();
         btn.Draw ();
 
         expected = @$"
@@ -563,7 +563,7 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.False (btn.IsInitialized);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.True (btn.IsInitialized);
         Assert.Equal ("Say Hello 你", btn.Text);
@@ -597,7 +597,7 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.False (btn.IsInitialized);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.True (btn.IsInitialized);
         Assert.Equal ("Say Hello 你", btn.Text);

+ 4 - 4
UnitTests/Views/CheckBoxTests.cs

@@ -254,7 +254,7 @@ public class CheckBoxTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.Equal (Alignment.Center, checkBox.TextAlignment);
         Assert.Equal (new (1, 1, 25, 1), checkBox.Frame);
@@ -314,7 +314,7 @@ public class CheckBoxTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 6);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 6);
 
         Assert.Equal (Alignment.Fill, checkBox1.TextAlignment);
         Assert.Equal (new (1, 1, 25, 1), checkBox1.Frame);
@@ -372,7 +372,7 @@ public class CheckBoxTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.Equal (Alignment.Start, checkBox.TextAlignment);
         Assert.Equal (new (1, 1, 25, 1), checkBox.Frame);
@@ -423,7 +423,7 @@ public class CheckBoxTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.Equal (Alignment.End, checkBox.TextAlignment);
         Assert.Equal (new (1, 1, 25, 1), checkBox.Frame);

+ 9 - 9
UnitTests/Views/ContextMenuTests.cs

@@ -117,9 +117,9 @@ public class ContextMenuTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Draw_A_ContextMenu_Over_A_Borderless_Top ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
 
-        Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver.Clip);
+        Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver?.Clip);
         TestHelpers.AssertDriverContentsWithFrameAre ("", output);
 
         var top = new Toplevel { X = 2, Y = 2, Width = 15, Height = 4 };
@@ -167,7 +167,7 @@ public class ContextMenuTests (ITestOutputHelper output)
         var win = new Window ();
         top.Add (win);
         RunState rsTop = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
 
         Assert.Equal (new Rectangle (0, 0, 20, 15), win.Frame);
 
@@ -252,9 +252,9 @@ public class ContextMenuTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Draw_A_ContextMenu_Over_A_Top_Dialog ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
 
-        Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver.Clip);
+        Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver?.Clip);
         TestHelpers.AssertDriverContentsWithFrameAre ("", output);
 
         // Don't use Dialog here as it has more layout logic. Use Window instead.
@@ -542,7 +542,7 @@ public class ContextMenuTests (ITestOutputHelper output)
                                                       output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 20);
         cm.Position = new Point (41, -2);
         cm.Show ();
         Application.Refresh ();
@@ -677,7 +677,7 @@ public class ContextMenuTests (ITestOutputHelper output)
                                                       output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (18, 8);
+        ((FakeDriver)Application.Driver!).SetBufferSize (18, 8);
         cm.Position = new Point (19, 10);
         cm.Show ();
         Application.Refresh ();
@@ -891,7 +891,7 @@ public class ContextMenuTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Show_Display_At_Zero_If_The_Toplevel_Height_Is_Less_Than_The_Menu_Height ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (80, 3);
+        ((FakeDriver)Application.Driver!).SetBufferSize (80, 3);
 
         var cm = new ContextMenu
         {
@@ -929,7 +929,7 @@ public class ContextMenuTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Show_Display_At_Zero_If_The_Toplevel_Width_Is_Less_Than_The_Menu_Width ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (5, 25);
+        ((FakeDriver)Application.Driver!).SetBufferSize (5, 25);
 
         var cm = new ContextMenu
         {

+ 1 - 1
UnitTests/Views/FrameViewTests.cs

@@ -37,7 +37,7 @@ public class FrameViewTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Draw_Defaults ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
         var fv = new FrameView ();
         Assert.Equal (string.Empty, fv.Title);
         Assert.Equal (string.Empty, fv.Text);

+ 13 - 13
UnitTests/Views/LabelTests.cs

@@ -97,7 +97,7 @@ public class LabelTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         var expected = @"
 ┌────────────────────────────┐
@@ -137,7 +137,7 @@ public class LabelTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         var expected = @"
 ┌────────────────────────────┐
@@ -179,7 +179,7 @@ public class LabelTests (ITestOutputHelper output)
         label.Text = "Say Hello 你";
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         var expected = @"
 ┌────────────────────────────┐
@@ -414,7 +414,7 @@ e
         Assert.False (label.IsInitialized);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.True (label.IsInitialized);
         Assert.Equal ("Say Hello 你", label.Text);
@@ -446,7 +446,7 @@ e
         Assert.False (label.IsInitialized);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.True (label.IsInitialized);
         Assert.Equal ("Say Hello 你", label.Text);
@@ -473,7 +473,7 @@ e
         var label = new Label { BorderStyle = LineStyle.Single, Text = "Test" };
         label.BeginInit ();
         label.EndInit ();
-        label.SetRelativeLayout (Application.Driver.Screen.Size);
+        label.SetRelativeLayout (Application.Driver!.Screen.Size);
 
         Assert.Equal (new (0, 0, 4, 1), label.Viewport);
         Assert.Equal (new (0, 0, 6, 3), label.Frame);
@@ -881,7 +881,7 @@ e
         Toplevel top = new ();
         top.Add (win);
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 10);
 
         Assert.Equal (29, label.Text.Length);
         Assert.Equal (new (0, 0, 40, 10), top.Frame);
@@ -931,7 +931,7 @@ e
         Toplevel top = new ();
         top.Add (win);
         RunState rs = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 10);
 
         Assert.Equal (new (0, 0, 40, 10), top.Frame);
         Assert.Equal (new (0, 0, 40, 10), win.Frame);
@@ -1071,7 +1071,7 @@ e
                          {
                              if (k.KeyCode == KeyCode.Enter)
                              {
-                                 ((FakeDriver)Application.Driver).SetBufferSize (22, count + 4);
+                                 ((FakeDriver)Application.Driver!).SetBufferSize (22, count + 4);
                                  Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expecteds [count], output);
                                  Assert.Equal (new (0, 0, 22, count + 4), pos);
 
@@ -1135,7 +1135,7 @@ e
     [SetupFakeDriver]
     public void Label_Height_Zero_Stays_Zero ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
         var text = "Label";
 
         var label = new Label
@@ -1223,7 +1223,7 @@ e
                          {
                              if (k.KeyCode == KeyCode.Enter)
                              {
-                                 ((FakeDriver)Application.Driver).SetBufferSize (22, count + 4);
+                                 ((FakeDriver)Application.Driver!).SetBufferSize (22, count + 4);
                                  Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expecteds [count], output);
                                  Assert.Equal (new (0, 0, 22, count + 4), pos);
 
@@ -1299,7 +1299,7 @@ e
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
 
         Assert.Equal (5, text.Length);
         Assert.Equal (new (0, 0, 5, 1), label.Frame);
@@ -1358,7 +1358,7 @@ e
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
 
         Assert.Equal (5, text.Length);
         Assert.Equal (new (0, 0, 5, 1), label.Frame);

+ 2 - 2
UnitTests/Views/ListViewTests.cs

@@ -55,7 +55,7 @@ public class ListViewTests (ITestOutputHelper output)
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (12, 12);
+        ((FakeDriver)Application.Driver!).SetBufferSize (12, 12);
         Application.Refresh ();
 
         Assert.Equal (-1, lv.SelectedItem);
@@ -357,7 +357,7 @@ Item 6",
 
             for (var i = 0; i < 7; i++)
             {
-                item += Application.Driver.Contents [line, i].Rune;
+                item += Application.Driver?.Contents [line, i].Rune;
             }
 
             return item;

+ 14 - 14
UnitTests/Views/MenuBarTests.cs

@@ -366,7 +366,7 @@ public class MenuBarTests (ITestOutputHelper output)
         var win = new Window ();
         top.Add (win);
         RunState rsTop = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 15);
 
         Assert.Equal (new (0, 0, 40, 15), win.Frame);
 
@@ -556,7 +556,7 @@ public class MenuBarTests (ITestOutputHelper output)
             Assert.Equal (items [i], menu.Menus [0].Title);
         }
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
         menu.OpenMenu ();
         firstIteration = false;
         Application.RunIteration (ref rsDialog, ref firstIteration);
@@ -590,9 +590,9 @@ public class MenuBarTests (ITestOutputHelper output)
     [AutoInitShutdown]
     public void Draw_A_Menu_Over_A_Top_Dialog ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 15);
 
-        Assert.Equal (new (0, 0, 40, 15), Application.Driver.Clip);
+        Assert.Equal (new (0, 0, 40, 15), Application.Driver?.Clip);
         TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
 
         List<string> items = new ()
@@ -734,7 +734,7 @@ public class MenuBarTests (ITestOutputHelper output)
             Assert.Equal (items [i], menu.Menus [0].Title);
         }
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
         menu.OpenMenu ();
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -805,7 +805,7 @@ public class MenuBarTests (ITestOutputHelper output)
 
         menu.CloseAllMenus ();
         menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height);
-        ((FakeDriver)Application.Driver).SetBufferSize (7, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (7, 5);
         menu.OpenMenu ();
         Application.Refresh ();
 
@@ -821,7 +821,7 @@ public class MenuBarTests (ITestOutputHelper output)
 
         menu.CloseAllMenus ();
         menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height);
-        ((FakeDriver)Application.Driver).SetBufferSize (7, 3);
+        ((FakeDriver)Application.Driver!).SetBufferSize (7, 3);
         menu.OpenMenu ();
         Application.Refresh ();
 
@@ -878,7 +878,7 @@ wo
 
         menu.CloseAllMenus ();
         menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height);
-        ((FakeDriver)Application.Driver).SetBufferSize (3, 2);
+        ((FakeDriver)Application.Driver!).SetBufferSize (3, 2);
         menu.OpenMenu ();
         Application.Refresh ();
 
@@ -891,7 +891,7 @@ wo
 
         menu.CloseAllMenus ();
         menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height);
-        ((FakeDriver)Application.Driver).SetBufferSize (3, 1);
+        ((FakeDriver)Application.Driver!).SetBufferSize (3, 1);
         menu.OpenMenu ();
         Application.Refresh ();
 
@@ -1519,7 +1519,7 @@ wo
         Toplevel top = new ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 8);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 8);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"
@@ -1630,7 +1630,7 @@ wo
 
         Application.Iteration += (s, a) =>
                                  {
-                                     ((FakeDriver)Application.Driver).SetBufferSize (40, 8);
+                                     ((FakeDriver)Application.Driver!).SetBufferSize (40, 8);
 
                                      TestHelpers.AssertDriverContentsWithFrameAre (
                                                                                    @"
@@ -1741,7 +1741,7 @@ wo
             ]
         };
         win.Add (menu);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 8);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 8);
         Application.Begin (win);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
@@ -1827,7 +1827,7 @@ wo
     [AutoInitShutdown]
     public void MenuBar_In_Window_Without_Other_Views_Without_Top_Init_With_Run_T ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 8);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 8);
 
         Application.Iteration += (s, a) =>
                                  {
@@ -2758,7 +2758,7 @@ Edit
                                                       output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 15);
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
 

+ 1 - 1
UnitTests/Views/OverlappedTests.cs

@@ -881,7 +881,7 @@ public class OverlappedTests
         var overlapped = new Overlapped ();
         var win1 = new Window { Width = 5, Height = 5, Visible = false };
         var win2 = new Window { X = 1, Y = 1, Width = 5, Height = 5 };
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
         RunState rsOverlapped = Application.Begin (overlapped);
 
         // Need to fool MainLoop into thinking it's running

+ 1 - 1
UnitTests/Views/RadioGroupTests.cs

@@ -219,7 +219,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 5);
 
         Assert.Equal (Orientation.Vertical, rg.Orientation);
         Assert.Equal (2, rg.RadioLabels.Length);

+ 6 - 6
UnitTests/Views/ScrollBarViewTests.cs

@@ -173,7 +173,7 @@ public class ScrollBarViewTests
         super.Add (vert);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (width, height);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
 
         var expected = @"
 ┌─┐
@@ -703,7 +703,7 @@ This is a test
         var sbv = new ScrollBarView { Id = "sbv", Size = width * 2, ShowScrollIndicator = true };
         super.Add (sbv);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (width, height);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
 
         var expected = @"
 ┌──────────────────────────────────────┐
@@ -829,7 +829,7 @@ This is a test
         top.Add (win);
 
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (45, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (45, 20);
 
         Assert.True (scrollBar.AutoHideScrollBars);
         Assert.False (scrollBar.ShowScrollIndicator);
@@ -867,7 +867,7 @@ This is a test
         Assert.Equal (new Rectangle (0, 0, 45, 20), pos);
 
         textView.WordWrap = true;
-        ((FakeDriver)Application.Driver).SetBufferSize (26, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (26, 20);
         Application.Refresh ();
 
         Assert.True (textView.WordWrap);
@@ -904,7 +904,7 @@ This is a test
         pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
         Assert.Equal (new Rectangle (0, 0, 26, 20), pos);
 
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
         Application.Refresh ();
 
         Assert.True (textView.WordWrap);
@@ -1229,7 +1229,7 @@ This is a test             ",
 
         super.Add (sbv);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (width, height);
+        ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
 
         var expected = @"
 ┌─┐

+ 1 - 1
UnitTests/Views/ScrollViewTests.cs

@@ -362,7 +362,7 @@ public class ScrollViewTests (ITestOutputHelper output)
     [SetupFakeDriver]
     public void ContentBottomRightCorner_Draw ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 30);
+        ((FakeDriver)Application.Driver!).SetBufferSize (30, 30);
 
         var top = new View { Width = 30, Height = 30, ColorScheme = new() { Normal = Attribute.Default } };
 

+ 1 - 1
UnitTests/Views/TableViewTests.cs

@@ -2196,7 +2196,7 @@ public class TableViewTests (ITestOutputHelper output)
     [SetupFakeDriver]
     public void TestEnumerableDataSource_BasicTypes ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize(100,100);
+        ((FakeDriver)Application.Driver!).SetBufferSize(100,100);
         var tv = new TableView ();
         tv.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         tv.Viewport = new (0, 0, 50, 6);

+ 7 - 7
UnitTests/Views/TextFieldTests.cs

@@ -67,7 +67,7 @@ public class TextFieldTests (ITestOutputHelper output)
 
             for (var i = 0; i < 16; i++)
             {
-                item += Application.Driver.Contents [0, i].Rune;
+                item += Application.Driver?.Contents [0, i].Rune;
             }
 
             return item;
@@ -164,7 +164,7 @@ public class TextFieldTests (ITestOutputHelper output)
 
         // Caption has no effect when focused
         tf.Caption = caption;
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
         Assert.False (tf.HasFocus);
 
         tf.Draw ();
@@ -184,7 +184,7 @@ public class TextFieldTests (ITestOutputHelper output)
         TextField tf = GetTextFieldsInView ();
 
         tf.Caption = caption;
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
         Assert.False (tf.HasFocus);
 
         tf.Draw ();
@@ -205,7 +205,7 @@ public class TextFieldTests (ITestOutputHelper output)
         TestHelpers.AssertDriverContentsAre ("", output);
 
         tf.Caption = "Enter txt";
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
 
         // Caption should appear when not focused and no text
         Assert.False (tf.HasFocus);
@@ -234,7 +234,7 @@ public class TextFieldTests (ITestOutputHelper output)
         tf.Draw ();
         TestHelpers.AssertDriverContentsAre ("", output);
 
-        Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
+        Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
 
         Assert.False (tf.HasFocus);
         tf.Draw ();
@@ -347,7 +347,7 @@ public class TextFieldTests (ITestOutputHelper output)
 
         Assert.Equal (
                       "TextField with some more test text. Unicode shouldn't 𝔹Aℝ𝔽!",
-                      Application.Driver.Clipboard.GetClipboardData ()
+                      Application.Driver?.Clipboard.GetClipboardData ()
                      );
         Assert.Equal (string.Empty, _textField.Text);
         _textField.Paste ();
@@ -374,7 +374,7 @@ public class TextFieldTests (ITestOutputHelper output)
         Assert.Equal (32, _textField.CursorPosition);
         _textField.SelectAll ();
         _textField.Cut ();
-        Assert.Equal ("TAB to jump between text fields.", Application.Driver.Clipboard.GetClipboardData ());
+        Assert.Equal ("TAB to jump between text fields.", Application.Driver?.Clipboard.GetClipboardData ());
         Assert.Equal (string.Empty, _textField.Text);
         Assert.Equal (0, _textField.CursorPosition);
         _textField.Paste ();

+ 9 - 9
UnitTests/Views/TextViewTests.cs

@@ -609,7 +609,7 @@ public class TextViewTests
 
         Assert.Equal (
                       "TextView with some more test text. Unicode shouldn't 𝔹Aℝ𝔽!",
-                      Application.Driver.Clipboard.GetClipboardData ()
+                      Application.Driver?.Clipboard.GetClipboardData ()
                      );
         Assert.Equal (string.Empty, _textView.Text);
         _textView.Paste ();
@@ -1018,7 +1018,7 @@ This is the second line.
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight });
             Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn);
             Application.PositionCursor (top);
-            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility);
             Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
         }
 
@@ -1028,7 +1028,7 @@ This is the second line.
             Assert.Equal (i - 1, tv.LeftColumn);
 
             Application.PositionCursor (top);
-            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility);
 
             if (i - 1 == 0)
             {
@@ -1070,7 +1070,7 @@ This is the second line.
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown });
             Application.PositionCursor (top);
             Assert.Equal (i + 1, tv.TopRow);
-            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility);
             Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
         }
 
@@ -1081,7 +1081,7 @@ This is the second line.
             Assert.Equal (i - 1, tv.TopRow);
 
             Application.PositionCursor (top);
-            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility);
 
             if (i - 1 == 0)
             {
@@ -6697,7 +6697,7 @@ TAB to jump between text field",
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (15, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (15, 15);
         Application.Refresh ();
 
         //this passes
@@ -6774,7 +6774,7 @@ TAB to jump between text field",
         var top = new Toplevel ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (15, 15);
+        ((FakeDriver)Application.Driver!).SetBufferSize (15, 15);
         Application.Refresh ();
 
         //this passes
@@ -6899,8 +6899,8 @@ This is the second line.
                                                       _output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (6, 25);
-        tv.SetRelativeLayout (Application.Driver.Screen.Size);
+        ((FakeDriver)Application.Driver!).SetBufferSize (6, 25);
+        tv.SetRelativeLayout (Application.Driver!.Screen.Size);
         tv.Draw ();
         Assert.Equal (new Point (4, 2), tv.CursorPosition);
         Assert.Equal (new Point (12, 0), cp);

+ 24 - 24
UnitTests/Views/ToplevelTests.cs

@@ -44,8 +44,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                              Assert.Equal ("Top1", Application.Top.Text);
                                              Assert.Equal (0, Application.Top.Frame.X);
                                              Assert.Equal (0, Application.Top.Frame.Y);
-                                             Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
-                                             Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
+                                             Assert.Equal (Application.Driver!.Cols, Application.Top.Frame.Width);
+                                             Assert.Equal (Application.Driver!.Rows, Application.Top.Frame.Height);
 
                                              Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
 
@@ -54,8 +54,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                              Assert.Equal ("Top2", Application.Top.Text);
                                              Assert.Equal (0, Application.Top.Frame.X);
                                              Assert.Equal (0, Application.Top.Frame.Y);
-                                             Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
-                                             Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
+                                             Assert.Equal (Application.Driver!.Cols, Application.Top.Frame.Width);
+                                             Assert.Equal (Application.Driver!.Rows, Application.Top.Frame.Height);
 
                                              Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
 
@@ -64,8 +64,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                              Assert.Equal ("Top1", Application.Top.Text);
                                              Assert.Equal (0, Application.Top.Frame.X);
                                              Assert.Equal (0, Application.Top.Frame.Y);
-                                             Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
-                                             Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
+                                             Assert.Equal (Application.Driver!.Cols, Application.Top.Frame.Width);
+                                             Assert.Equal (Application.Driver!.Rows, Application.Top.Frame.Height);
 
                                              Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
 
@@ -74,8 +74,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                              Assert.Equal ("Top2", Application.Top.Text);
                                              Assert.Equal (0, Application.Top.Frame.X);
                                              Assert.Equal (0, Application.Top.Frame.Y);
-                                             Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
-                                             Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
+                                             Assert.Equal (Application.Driver!.Cols, Application.Top.Frame.Width);
+                                             Assert.Equal (Application.Driver!.Rows, Application.Top.Frame.Height);
 
                                              Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
 
@@ -84,8 +84,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                              Assert.Equal ("Top1", Application.Top.Text);
                                              Assert.Equal (0, Application.Top.Frame.X);
                                              Assert.Equal (0, Application.Top.Frame.Y);
-                                             Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
-                                             Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
+                                             Assert.Equal (Application.Driver!.Cols, Application.Top.Frame.Width);
+                                             Assert.Equal (Application.Driver!.Rows, Application.Top.Frame.Height);
 
                                              Application.OnKeyPressed (new (Key.CtrlMask | Key.Q));
 
@@ -675,7 +675,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
 
                                      if (iterations == 0)
                                      {
-                                         ((FakeDriver)Application.Driver).SetBufferSize (15, 7);
+                                         ((FakeDriver)Application.Driver!).SetBufferSize (15, 7);
 
                                          // Don't use MessageBox here; it's too complicated for this unit test; just use Window
                                          testWindow = new ()
@@ -794,7 +794,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
 
                                      if (iterations == 0)
                                      {
-                                         ((FakeDriver)Application.Driver).SetBufferSize (30, 10);
+                                         ((FakeDriver)Application.Driver!).SetBufferSize (30, 10);
                                      }
                                      else if (iterations == 1)
                                      {
@@ -896,10 +896,10 @@ public partial class ToplevelTests (ITestOutputHelper output)
         top.BeginInit ();
         top.EndInit ();
 
-        Exception exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (0, 10));
+        Exception exception = Record.Exception (() => ((FakeDriver)Application.Driver!).SetBufferSize (0, 10));
         Assert.Null (exception);
 
-        exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (10, 0));
+        exception = Record.Exception (() => ((FakeDriver)Application.Driver!).SetBufferSize (10, 0));
         Assert.Null (exception);
     }
 
@@ -1085,13 +1085,13 @@ public partial class ToplevelTests (ITestOutputHelper output)
 
         Assert.True (tf.HasFocus);
         Application.PositionCursor (top);
-        Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
+        Application.Driver!.GetCursorVisibility (out CursorVisibility cursor);
         Assert.Equal (CursorVisibility.Default, cursor);
 
         view.Enabled = false;
         Assert.False (tf.HasFocus);
         Application.PositionCursor (top);
-        Application.Driver.GetCursorVisibility (out cursor);
+        Application.Driver!.GetCursorVisibility (out cursor);
         Assert.Equal (CursorVisibility.Invisible, cursor);
         top.Dispose ();
     }
@@ -1209,7 +1209,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
         Toplevel top = new ();
         var window = new Window { Width = 20, Height = 3, Arrangement = ViewArrangement.Movable };
         RunState rsTop = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 10);
         RunState rsWindow = Application.Begin (window);
         Application.Refresh ();
         Assert.Equal (new (0, 0, 40, 10), top.Frame);
@@ -1232,7 +1232,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
         Assert.Equal (new (0, 0, 20, 3), window.Frame);
 
         // Changes Top size to same size as Dialog more menu and scroll bar
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 3);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 3);
 
         Application.OnMouseEvent (
                                   new ()
@@ -1245,7 +1245,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
         Assert.Equal (new (0, 0, 20, 3), window.Frame);
 
         // Changes Top size smaller than Dialog size
-        ((FakeDriver)Application.Driver).SetBufferSize (19, 2);
+        ((FakeDriver)Application.Driver!).SetBufferSize (19, 2);
 
         Application.OnMouseEvent (
                                   new ()
@@ -1338,7 +1338,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
     {
         Toplevel top = new ();
         RunState rsTop = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 20);
 
         var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
         Assert.Equal (new (2, 1, 15, 10), testWindow.Frame);
@@ -1360,7 +1360,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
         var win = new Window ();
         top.Add (win);
         RunState rsTop = Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 20);
 
         Assert.Equal (new (0, 0, 20, 20), win.Frame);
 
@@ -1389,8 +1389,8 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                {
                                    Assert.Equal (new (1, 3, 18, 16), viewAddedToTop.Frame);
 
-                                   Rectangle savedClip = Application.Driver.Clip;
-                                   Application.Driver.Clip = top.Frame;
+                                   Rectangle savedClip = Application.Driver!.Clip;
+                                   Application.Driver!.Clip = top.Frame;
                                    viewAddedToTop.Draw ();
                                    top.Move (2, 15);
                                    View.Driver.AddStr ("One");
@@ -1398,7 +1398,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
                                    View.Driver.AddStr ("Two");
                                    top.Move (2, 17);
                                    View.Driver.AddStr ("Three");
-                                   Application.Driver.Clip = savedClip;
+                                   Application.Driver!.Clip = savedClip;
 
                                    Application.Current.DrawContentComplete -= OnDrawContentComplete;
                                }

+ 2 - 2
UnitTests/Views/TreeTableSourceTests.cs

@@ -29,7 +29,7 @@ public class TreeTableSourceTests : IDisposable
     [SetupFakeDriver]
     public void TestTreeTableSource_BasicExpanding_WithKeyboard ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
         TableView tv = GetTreeTable (out _);
 
         tv.Style.GetOrCreateColumnStyle (1).MinAcceptableWidth = 1;
@@ -88,7 +88,7 @@ public class TreeTableSourceTests : IDisposable
     [SetupFakeDriver]
     public void TestTreeTableSource_BasicExpanding_WithMouse ()
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+        ((FakeDriver)Application.Driver!).SetBufferSize (100, 100);
 
         TableView tv = GetTreeTable (out _);
 

+ 1 - 1
UnitTests/Views/TreeViewTests.cs

@@ -114,7 +114,7 @@ public class TreeViewTests
         tv.SelectAll ();
         tv.CursorVisibility = CursorVisibility.Default;
         Application.PositionCursor (top);
-        Application.Driver.GetCursorVisibility (out CursorVisibility visibility);
+        Application.Driver!.GetCursorVisibility (out CursorVisibility visibility);
         Assert.Equal (CursorVisibility.Default, tv.CursorVisibility);
         Assert.Equal (CursorVisibility.Default, visibility);
         top.Dispose ();

+ 3 - 3
UnitTests/Views/WindowTests.cs

@@ -53,7 +53,7 @@ public class WindowTests
         Toplevel top = new ();
         top.Add (win);
         Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"
@@ -70,7 +70,7 @@ public class WindowTests
                                                       _output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (40, 20);
+        ((FakeDriver)Application.Driver!).SetBufferSize (40, 20);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"
@@ -97,7 +97,7 @@ public class WindowTests
                                                       _output
                                                      );
 
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+        ((FakeDriver)Application.Driver!).SetBufferSize (20, 10);
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно