diff --git a/Terminal.Gui/Core.cs b/Terminal.Gui/Core.cs
index e31fe0b5c..036804e6b 100644
--- a/Terminal.Gui/Core.cs
+++ b/Terminal.Gui/Core.cs
@@ -2125,23 +2125,25 @@ namespace Terminal.Gui {
{
if (_initialized) return;
- var p = Environment.OSVersion.Platform;
- Mono.Terminal.IMainLoopDriver mainLoopDriver;
+ if (Driver == null) {
+ var p = Environment.OSVersion.Platform;
+ Mono.Terminal.IMainLoopDriver mainLoopDriver;
- if (UseSystemConsole) {
- mainLoopDriver = new Mono.Terminal.NetMainLoop ();
- Driver = new NetDriver ();
- } else if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows) {
- var windowsDriver = new WindowsDriver ();
- mainLoopDriver = windowsDriver;
- Driver = windowsDriver;
- } else {
- mainLoopDriver = new Mono.Terminal.UnixMainLoop ();
- Driver = new CursesDriver ();
+ if (UseSystemConsole) {
+ mainLoopDriver = new Mono.Terminal.NetMainLoop ();
+ Driver = new NetDriver ();
+ } else if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows) {
+ var windowsDriver = new WindowsDriver ();
+ mainLoopDriver = windowsDriver;
+ Driver = windowsDriver;
+ } else {
+ mainLoopDriver = new Mono.Terminal.UnixMainLoop ();
+ Driver = new CursesDriver ();
+ }
+ Driver.Init (TerminalResized);
+ MainLoop = new Mono.Terminal.MainLoop (mainLoopDriver);
+ SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
}
- Driver.Init (TerminalResized);
- MainLoop = new Mono.Terminal.MainLoop (mainLoopDriver);
- SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
Top = topLevelFactory ();
Current = Top;
CurrentView = Top;
@@ -2152,6 +2154,8 @@ namespace Terminal.Gui {
/// Captures the execution state for the provided view.
///
public class RunState : IDisposable {
+ internal bool closeDriver = true;
+
internal RunState (Toplevel view)
{
Toplevel = view;
@@ -2168,7 +2172,7 @@ namespace Terminal.Gui {
/// was occupying.
public void Dispose ()
{
- Dispose (true);
+ Dispose (closeDriver);
GC.SuppressFinalize (this);
}
@@ -2180,7 +2184,7 @@ namespace Terminal.Gui {
protected virtual void Dispose (bool disposing)
{
if (Toplevel != null) {
- End (Toplevel);
+ End (Toplevel, disposing);
Toplevel = null;
}
}
@@ -2373,14 +2377,14 @@ namespace Terminal.Gui {
///
/// Building block API: Prepares the provided for execution.
///
- /// The runstate handle that needs to be passed to the method upon completion.
+ /// The runstate handle that needs to be passed to the method upon completion.
/// Toplevel to prepare execution for.
///
/// This method prepares the provided toplevel for running with the focus,
/// it adds this to the list of toplevels, sets up the mainloop to process the
/// event, lays out the subviews, focuses the first element, and draws the
/// toplevel in the screen. This is usually followed by executing
- /// the method, and then the method upon termination which will
+ /// the method, and then the method upon termination which will
/// undo these changes.
///
public static RunState Begin (Toplevel toplevel)
@@ -2417,19 +2421,21 @@ namespace Terminal.Gui {
/// Building block API: completes the execution of a that was started with .
///
/// The runstate returned by the method.
- public static void End (RunState runState)
+ /// trueCloses the application.falseCloses the toplevels only.
+ public static void End (RunState runState, bool closeDriver = true)
{
if (runState == null)
throw new ArgumentNullException (nameof (runState));
+ runState.closeDriver = closeDriver;
runState.Dispose ();
- runState = null;
}
///
- /// Shutdown an application initalized with
+ /// Shutdown an application initialized with
///
- public static void Shutdown ()
+ /// /// trueCloses the application.falseCloses toplevels only.
+ public static void Shutdown (bool closeDriver = true)
{
// Shutdown is the bookend for Init. As such it needs to clean up all resources
// Init created. Apps that do any threading will need to code defensively for this.
@@ -2443,10 +2449,12 @@ namespace Terminal.Gui {
CurrentView = null;
Top = null;
- //
- MainLoop = null;
+ // Closes the application if it's true.
+ if (closeDriver) {
+ MainLoop = null;
+ Driver.End ();
+ }
- Driver.End ();
_initialized = false;
}
@@ -2480,13 +2488,13 @@ namespace Terminal.Gui {
Driver.Refresh ();
}
- internal static void End (View view)
+ internal static void End (View view, bool closeDriver = true)
{
if (toplevels.Peek () != view)
throw new ArgumentException ("The view that you end with must be balanced");
toplevels.Pop ();
if (toplevels.Count == 0)
- Shutdown ();
+ Shutdown (closeDriver);
else {
Current = toplevels.Peek ();
Refresh ();
@@ -2545,7 +2553,7 @@ namespace Terminal.Gui {
}
///
- /// Runs the application by calling with the value of
+ /// Runs the application by calling with the value of
///
public static void Run ()
{
@@ -2553,7 +2561,7 @@ namespace Terminal.Gui {
}
///
- /// Runs the application by calling with a new instance of the specified -derived class
+ /// Runs the application by calling with a new instance of the specified -derived class
///
public static void Run () where T : Toplevel, new()
{
@@ -2571,11 +2579,11 @@ namespace Terminal.Gui {
/// run other modal s such as boxes.
///
///
- /// To make a stop execution, call .
+ /// To make a stop execution, call .
///
///
- /// Calling is equivalent to calling , followed by ,
- /// and then calling .
+ /// Calling is equivalent to calling , followed by ,
+ /// and then calling .
///
///
/// Alternatively, to have a program control the main loop and
@@ -2585,11 +2593,11 @@ namespace Terminal.Gui {
/// then return control immediately.
///
///
- public static void Run (Toplevel view)
+ public static void Run (Toplevel view, bool closeDriver = true)
{
var runToken = Begin (view);
RunLoop (runToken);
- End (runToken);
+ End (runToken, closeDriver);
}
///
diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs
index f8b22cb68..f422bdefa 100644
--- a/UICatalog/Scenario.cs
+++ b/UICatalog/Scenario.cs
@@ -195,11 +195,8 @@ namespace UICatalog {
///
public virtual void Run ()
{
- Application.Run (Top);
-
- // Every call to Application.Init must be bound by a call to Shutdown
- // or Init doesn't do anything
- Application.Shutdown ();
+ // This method already performs a later automatic shutdown.
+ Application.Run (Top, false);
}
///
diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs
index 29cacd3d8..baff0e932 100644
--- a/UICatalog/UICatalog.cs
+++ b/UICatalog/UICatalog.cs
@@ -79,6 +79,8 @@ namespace UICatalog {
scenario.Run ();
scenario = GetScenarioToRun ();
}
+ // Now closes the driver too.
+ Application.Shutdown ();
}
///
@@ -197,7 +199,7 @@ namespace UICatalog {
};
#endif
- Application.Run (_top);
+ Application.Run (_top, false);
return _runningScenario;
}