-
Notifications
You must be signed in to change notification settings - Fork 717
Fixes #4139. Application.Run<T> isn't initializing properly by setting the Application.ForceDriver property #4142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…setting the Application.ForceDriver property
Did you consider this? ConfigurationManager.RuntimeConfig = """
{
"ForceDriver": "v2net"
}
""";
ConfigurationManager.Enable (ConfigLocations.Runtime);
Application.Run<MyWindow>(); |
This is a good solution for a real app but in my case I using a |
If you want to temporarily force all apps on your machine to use a particular driver while testing things, simply put a {
"ForceDriver": "v2net"
} Or, you could put this in |
Thanks. The correct configuration is like bellow. With this PR works well but with the {
"Application.ForceDriver": "v2net"
}
|
You should be able to fix this easily: 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 (typeof (IConsoleDriver).IsAssignableFrom (type) && !type.IsAbstract && type.IsClass)
{
driverTypes.Add (type);
}
}
}
return driverTypes;
} |
... and if you do fix that, this code can be cleaned up in UI Catalog: Option<string> driverOption = new Option<string> ("--driver", "The IConsoleDriver to use.").FromAmong (
Application.GetDriverTypes ()
.Where (d => !typeof (IConsoleDriverFacade).IsAssignableFrom (d))
.Select (d => d!.Name)
.Union (["v2", "v2win", "v2net"])
.ToArray ()
); |
I had already thought the same think but remember the v2 drivers run his own |
I think you are overthinking this. The bug here is that when we added If you fix Of course, this needs to be done too: |
What I did meant is that the code that follow the driver check shouldn't be used if the driver is v2 type. The v2 already have it own 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 = (IConsoleDriver)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 ();
SubscribeDriverEvents ();
}
catch (InvalidOperationException ex)
{
// This is a case where the driver is unable to initialize the console.
// This can happen if the console is already in use by another process or
// if running in unit tests.
// In this case, we want to throw a more specific exception.
throw new InvalidOperationException (
"Unable to initialize the console. This can happen if the console is already in use by another process or in unit tests.",
ex
);
}
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());
// TODO: This is probably not needed
if (Popover.GetActivePopover () is View popover)
{
popover.Visible = false;
}
MainThreadId = Thread.CurrentThread.ManagedThreadId;
bool init = Initialized = true;
InitializedChanged?.Invoke (null, new (init));
} |
I just dove into this a little and I was incorrect on the simplest fix. It's def more complicated than I thought because v2win/net are not fully integrated. I'm not sure how to fully fix this, but I suggest you start by making public class UICatalog
{
- private static string _forceDriver = string.Empty;
+ private static string? _forceDriver = null;
...
private static void UICatalogMain (UICatalogCommandLineOptions options)
{
// By setting _forceDriver we ensure that if the user has specified a driver on the command line, it will be used
// regardless of what's in a config file.
- Application.ForceDriver = (_forceDriver = (string.IsNullOrEmpty(options.Driver) ? null : options.Driver))!;
+ Application.ForceDriver = _forceDriver = options.Driver; Thanks. |
Changing the |
Looks nice. Ready? |
Thanks. I think I can do a little better by removing the additional code in the |
I've finished this now. The |
Fixes
Application.ForceDriver
property #4139Proposed Changes/Todos
InternalInit
methodPull Request checklist:
CTRL-K-D
to automatically reformat your files before committing.dotnet test
before commit///
style comments)