Skip to content

Commit ad1de25

Browse files
authored
Fixes #4139. Application.Run<T> isn't initializing properly by setting the Application.ForceDriver property (#4142)
* Fixes #4139. Application.Run<T> isn't initializing properly by setting the Application.ForceDriver property * Trying fix unit tests * Only to force again CI tests because I haven't errors locally * This should pass, unless RunningUnitTests is set to false somewhere * Fix Unix unit tests and failures via ReSharper * Changes suggested by @tig * Prevent empty string * Centralize all the entry logic in the InternalInit method * Change GetDriverTypes to return a tuple
1 parent 76b7e52 commit ad1de25

File tree

17 files changed

+257
-47
lines changed

17 files changed

+257
-47
lines changed

Examples/UICatalog/Properties/launchSettings.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
"commandName": "Project",
1313
"commandLineArgs": "--driver WindowsDriver"
1414
},
15+
"UICatalog --driver v2": {
16+
"commandName": "Project",
17+
"commandLineArgs": "--driver v2 -dl Trace"
18+
},
1519
"UICatalog --driver v2win": {
1620
"commandName": "Project",
1721
"commandLineArgs": "--driver v2win -dl Trace"
@@ -32,6 +36,18 @@
3236
"commandLineArgs": "dotnet UICatalog.dll --driver NetDriver",
3337
"distributionName": ""
3438
},
39+
"WSL: UICatalog --driver v2": {
40+
"commandName": "Executable",
41+
"executablePath": "wsl",
42+
"commandLineArgs": "dotnet UICatalog.dll --driver v2",
43+
"distributionName": ""
44+
},
45+
"WSL: UICatalog --driver v2net": {
46+
"commandName": "Executable",
47+
"executablePath": "wsl",
48+
"commandLineArgs": "dotnet UICatalog.dll --driver v2net",
49+
"distributionName": ""
50+
},
3551
"Benchmark All": {
3652
"commandName": "Project",
3753
"commandLineArgs": "--benchmark"

Examples/UICatalog/UICatalog.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ namespace UICatalog;
5454
/// </remarks>
5555
public class UICatalog
5656
{
57-
private static string _forceDriver = string.Empty;
57+
private static string? _forceDriver = null;
5858

5959
public static string LogFilePath { get; set; } = string.Empty;
6060
public static LoggingLevelSwitch LogLevelSwitch { get; } = new ();
@@ -77,11 +77,7 @@ private static int Main (string [] args)
7777

7878
// If no driver is provided, the default driver is used.
7979
Option<string> driverOption = new Option<string> ("--driver", "The IConsoleDriver to use.").FromAmong (
80-
Application.GetDriverTypes ()
81-
.Where (d => !typeof (IConsoleDriverFacade).IsAssignableFrom (d))
82-
.Select (d => d!.Name)
83-
.Union (["v2", "v2win", "v2net"])
84-
.ToArray ()
80+
Application.GetDriverTypes ().Item2.ToArray ()!
8581
);
8682
driverOption.AddAlias ("-d");
8783
driverOption.AddAlias ("--d");

Terminal.Gui/App/Application.Initialization.cs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public static partial class Application // Initialization (Init/Shutdown)
4040
[RequiresDynamicCode ("AOT")]
4141
public static void Init (IConsoleDriver? driver = null, string? driverName = null)
4242
{
43-
if (driverName?.StartsWith ("v2") ?? false)
44-
{
45-
ApplicationImpl.ChangeInstance (new ApplicationV2 ());
46-
}
47-
4843
ApplicationImpl.Instance.Init (driver, driverName);
4944
}
5045

@@ -83,12 +78,6 @@ internal static void InternalInit (
8378
ResetState (ignoreDisposed: true);
8479
}
8580

86-
Debug.Assert (Navigation is null);
87-
Navigation = new ();
88-
89-
Debug.Assert(Popover is null);
90-
Popover = new ();
91-
9281
// For UnitTests
9382
if (driver is { })
9483
{
@@ -105,8 +94,6 @@ internal static void InternalInit (
10594
}
10695
}
10796

108-
AddKeyBindings ();
109-
11097
// Ignore Configuration for ForceDriver if driverName is specified
11198
if (!string.IsNullOrEmpty (driverName))
11299
{
@@ -130,13 +117,21 @@ internal static void InternalInit (
130117
}
131118
else
132119
{
133-
List<Type?> drivers = GetDriverTypes ();
120+
(List<Type?> drivers, List<string?> driverTypeNames) = GetDriverTypes ();
134121
Type? driverType = drivers.FirstOrDefault (t => t!.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase));
135122

136123
if (driverType is { })
137124
{
138125
Driver = (IConsoleDriver)Activator.CreateInstance (driverType)!;
139126
}
127+
else if (ForceDriver?.StartsWith ("v2") ?? false)
128+
{
129+
ApplicationImpl.ChangeInstance (new ApplicationV2 ());
130+
ApplicationImpl.Instance.Init (driver, ForceDriver);
131+
Debug.Assert (Driver is { });
132+
133+
return;
134+
}
140135
else
141136
{
142137
throw new ArgumentException (
@@ -146,6 +141,14 @@ internal static void InternalInit (
146141
}
147142
}
148143

144+
Debug.Assert (Navigation is null);
145+
Navigation = new ();
146+
147+
Debug.Assert (Popover is null);
148+
Popover = new ();
149+
150+
AddKeyBindings ();
151+
149152
try
150153
{
151154
MainLoop = Driver!.Init ();
@@ -201,10 +204,10 @@ internal static void UnsubscribeDriverEvents ()
201204
private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); }
202205
private static void Driver_MouseEvent (object? sender, MouseEventArgs e) { RaiseMouseEvent (e); }
203206

204-
/// <summary>Gets of list of <see cref="IConsoleDriver"/> types that are available.</summary>
207+
/// <summary>Gets of list of <see cref="IConsoleDriver"/> types and type names that are available.</summary>
205208
/// <returns></returns>
206209
[RequiresUnreferencedCode ("AOT")]
207-
public static List<Type?> GetDriverTypes ()
210+
public static (List<Type?>, List<string?>) GetDriverTypes ()
208211
{
209212
// use reflection to get the list of drivers
210213
List<Type?> driverTypes = new ();
@@ -220,7 +223,13 @@ internal static void UnsubscribeDriverEvents ()
220223
}
221224
}
222225

223-
return driverTypes;
226+
List<string?> driverTypeNames = driverTypes
227+
.Where (d => !typeof (IConsoleDriverFacade).IsAssignableFrom (d))
228+
.Select (d => d!.Name)
229+
.Union (["v2", "v2win", "v2net"])
230+
.ToList ()!;
231+
232+
return (driverTypes, driverTypeNames);
224233
}
225234

226235
/// <summary>Shutdown an application initialized with <see cref="Init"/>.</summary>

Terminal.Gui/App/ApplicationImpl.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static void ChangeInstance (IApplication newApplication)
3434
[RequiresDynamicCode ("AOT")]
3535
public virtual void Init (IConsoleDriver? driver = null, string? driverName = null)
3636
{
37-
Application.InternalInit (driver, driverName);
37+
Application.InternalInit (driver, string.IsNullOrWhiteSpace (driverName) ? Application.ForceDriver : driverName);
3838
}
3939

4040
/// <summary>
@@ -85,7 +85,12 @@ public virtual T Run<T> (Func<Exception, bool>? errorHandler = null, IConsoleDri
8585
if (!Application.Initialized)
8686
{
8787
// Init() has NOT been called.
88-
Application.InternalInit (driver, null, true);
88+
Application.InternalInit (driver, Application.ForceDriver, true);
89+
}
90+
91+
if (Instance is ApplicationV2)
92+
{
93+
return Instance.Run<T> (errorHandler, driver);
8994
}
9095

9196
var top = new T ();
@@ -227,6 +232,8 @@ public virtual void Shutdown ()
227232

228233
Application.OnInitializedChanged (this, new (in init));
229234
}
235+
236+
_lazyInstance = new (() => new ApplicationImpl ());
230237
}
231238

232239
/// <inheritdoc />

Terminal.Gui/Drivers/NetDriver/NetEvents.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public NetEvents (IConsoleDriver consoleDriver)
1919
{
2020
_consoleDriver = consoleDriver ?? throw new ArgumentNullException (nameof (consoleDriver));
2121

22+
if (ConsoleDriver.RunningUnitTests)
23+
{
24+
return;
25+
}
26+
2227
Task.Run (() =>
2328
{
2429
try
@@ -29,7 +34,8 @@ public NetEvents (IConsoleDriver consoleDriver)
2934
{ }
3035
}, _netEventsDisposed.Token);
3136

32-
Task.Run (() => {
37+
Task.Run (() =>
38+
{
3339
try
3440
{
3541
CheckWindowSizeChange ();

Terminal.Gui/Drivers/V2/ConsoleDriverFacade.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,19 @@ private void CreateClipboard ()
6464
}
6565

6666
/// <summary>Gets the location and size of the terminal screen.</summary>
67-
public Rectangle Screen => new (new (0, 0), _output.GetWindowSize ());
67+
public Rectangle Screen
68+
{
69+
get
70+
{
71+
if (ConsoleDriver.RunningUnitTests)
72+
{
73+
// In unit tests, we don't have a real output, so we return an empty rectangle.
74+
return Rectangle.Empty;
75+
}
76+
77+
return new (new (0, 0), _output.GetWindowSize ());
78+
}
79+
}
6880

6981
/// <summary>
7082
/// Gets or sets the clip rectangle that <see cref="AddRune(Rune)"/> and <see cref="AddStr(string)"/> are subject

Terminal.Gui/Drivers/V2/NetInput.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ public class NetInput : ConsoleInput<ConsoleKeyInfo>, INetInput
1717
public NetInput ()
1818
{
1919
Logging.Logger.LogInformation ($"Creating {nameof (NetInput)}");
20+
21+
if (ConsoleDriver.RunningUnitTests)
22+
{
23+
return;
24+
}
25+
2026
PlatformID p = Environment.OSVersion.Platform;
2127

2228
if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows)
@@ -39,7 +45,15 @@ public NetInput ()
3945
}
4046

4147
/// <inheritdoc/>
42-
protected override bool Peek () { return Console.KeyAvailable; }
48+
protected override bool Peek ()
49+
{
50+
if (ConsoleDriver.RunningUnitTests)
51+
{
52+
return false;
53+
}
54+
55+
return Console.KeyAvailable;
56+
}
4357

4458
/// <inheritdoc/>
4559
protected override IEnumerable<ConsoleKeyInfo> Read ()

Terminal.Gui/Drivers/V2/NetOutput.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public void Write (ReadOnlySpan<char> text)
4747
/// <inheritdoc/>
4848
public void Write (IOutputBuffer buffer)
4949
{
50+
if (ConsoleDriver.RunningUnitTests)
51+
{
52+
return;
53+
}
54+
5055
if (Console.WindowHeight < 1
5156
|| buffer.Contents.Length != buffer.Rows * buffer.Cols
5257
|| buffer.Rows != Console.WindowHeight)
@@ -197,7 +202,16 @@ public void Write (IOutputBuffer buffer)
197202
}
198203

199204
/// <inheritdoc/>
200-
public Size GetWindowSize () { return new (Console.WindowWidth, Console.WindowHeight); }
205+
public Size GetWindowSize ()
206+
{
207+
if (ConsoleDriver.RunningUnitTests)
208+
{
209+
// For unit tests, we return a default size.
210+
return Size.Empty;
211+
}
212+
213+
return new (Console.WindowWidth, Console.WindowHeight);
214+
}
201215

202216
private void WriteToConsole (StringBuilder output, ref int lastCol, int row, ref int outputWidth)
203217
{

Terminal.Gui/Drivers/V2/WindowSizeMonitor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public WindowSizeMonitor (IConsoleOutput consoleOut, IOutputBuffer outputBuffer)
2020
/// <inheritdoc/>
2121
public bool Poll ()
2222
{
23+
if (ConsoleDriver.RunningUnitTests)
24+
{
25+
return false;
26+
}
27+
2328
Size size = _consoleOut.GetWindowSize ();
2429

2530
if (size != _lastSize)

Terminal.Gui/Drivers/V2/WindowsInput.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ out uint lpNumberOfEventsRead
3838
public WindowsInput ()
3939
{
4040
Logging.Logger.LogInformation ($"Creating {nameof (WindowsInput)}");
41+
42+
if (ConsoleDriver.RunningUnitTests)
43+
{
44+
return;
45+
}
46+
4147
_inputHandle = GetStdHandle (STD_INPUT_HANDLE);
4248

4349
GetConsoleMode (_inputHandle, out uint v);
@@ -110,5 +116,13 @@ protected override bool Peek ()
110116
}
111117
}
112118

113-
public override void Dispose () { SetConsoleMode (_inputHandle, _originalConsoleMode); }
119+
public override void Dispose ()
120+
{
121+
if (ConsoleDriver.RunningUnitTests)
122+
{
123+
return;
124+
}
125+
126+
SetConsoleMode (_inputHandle, _originalConsoleMode);
127+
}
114128
}

0 commit comments

Comments
 (0)