Browse Source

Merge branch 'v2_toplevel_fill' into v2_fixes_2432_Dim_AutoSize

Tig Kindel 1 year ago
parent
commit
7558b54ad2

+ 5 - 1
Terminal.Gui/Application.cs

@@ -109,7 +109,7 @@ public static partial class Application {
 	/// </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>
-	public static void Init (ConsoleDriver driver = null, string driverName = null) => InternalInit (Toplevel.Create, driver, driverName);
+	public static void Init (ConsoleDriver driver = null, string driverName = null) => InternalInit (() => new Toplevel(), driver, driverName);
 
 	internal static bool _initialized = false;
 	internal static int _mainThreadId = -1;
@@ -194,6 +194,10 @@ public static partial class Application {
 
 		Top = topLevelFactory ();
 		Current = Top;
+
+		// Ensure Top's layout is up to date.
+		Current.SetRelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows)); 
+		
 		_cachedSupportedCultures = GetSupportedCultures ();
 		_mainThreadId = Thread.CurrentThread.ManagedThreadId;
 		_initialized = true;

+ 194 - 161
Terminal.Gui/Views/Toplevel.cs

@@ -1,88 +1,173 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Linq;
 
-namespace Terminal.Gui; 
+namespace Terminal.Gui;
 
 /// <summary>
-/// Toplevel views can be modally executed. They are used for both an application's main view (filling the entire screeN and
-/// for pop-up views such as <see cref="Dialog"/>, <see cref="MessageBox"/>, and <see cref="Wizard"/>.
+/// Toplevel views are used for both an application's main view (filling the entire screen and
+/// for modal (pop-up) views such as <see cref="Dialog"/>, <see cref="MessageBox"/>, and
+/// <see cref="Wizard"/>).
 /// </summary>
 /// <remarks>
-///   <para>
-///     Toplevels can be modally executing views, started by calling <see cref="Application.Run(Toplevel, Func{Exception, bool})"/>. 
-///     They return control to the caller when <see cref="Application.RequestStop(Toplevel)"/> has 
-///     been called (which sets the <see cref="Toplevel.Running"/> property to <c>false</c>). 
-///   </para>
-///   <para>
-///     A Toplevel is created when an application initializes Terminal.Gui by calling <see cref="Application.Init"/>.
-///     The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional Toplevels can be created 
-///     and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and 
-///     call <see cref="Application.Run(Toplevel, Func{Exception, bool})"/>.
-///   </para>
+///         <para>
+///         Toplevels can run as modal (popup) views, started by calling
+///         <see cref="Application.Run(Toplevel, System.Func{System.Exception,bool}(System.Exception))"/>.
+///         They return control to the caller when <see cref="Application.RequestStop(Toplevel)"/> has
+///         been called (which sets the <see cref="Toplevel.Running"/> property to <c>false</c>).
+///         </para>
+///         <para>
+///         A Toplevel is created when an application initializes Terminal.Gui by calling
+///         <see cref="Application.Init"/>.
+///         The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional
+///         Toplevels can be created
+///         and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and
+///         call <see cref="Application.Run(Toplevel, System.Func{System.Exception,bool}(System.Exception))"/>.
+///         </para>
 /// </remarks>
 public partial class Toplevel : View {
+	internal static Point? _dragPosition;
+	Point _startGrabPoint;
+
+	// BUGBUG: Remove; Toplevel should be ComputedLayout
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Toplevel"/> class with the specified
+	/// <see cref="LayoutStyle.Absolute"/> layout.
+	/// </summary>
+	/// <param name="frame">
+	/// A Superview-relative rectangle specifying the location and size for the new
+	/// Toplevel
+	/// </param>
+	public Toplevel (Rect frame) : base (frame) => SetInitialProperties ();
+
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Toplevel"/> class with
+	/// <see cref="LayoutStyle.Computed"/> layout, defaulting to full screen. The <see cref="View.Width"/> and <see cref="View.Height"/> properties
+	/// will be set to the dimensions of the terminal using <see cref="Dim.Fill"/>.
+	/// </summary>
+	public Toplevel ()
+	{
+		SetInitialProperties ();
+		Width = Dim.Fill ();
+		Height = Dim.Fill ();
+	}
+
 	/// <summary>
-	/// Gets or sets whether the main loop for this <see cref="Toplevel"/> is running or not. 
+	/// Gets or sets whether the main loop for this <see cref="Toplevel"/> is running or not.
 	/// </summary>
 	/// <remarks>
-	///    Setting this property directly is discouraged. Use <see cref="Application.RequestStop"/> instead. 
+	/// Setting this property directly is discouraged. Use <see cref="Application.RequestStop"/>
+	/// instead.
 	/// </remarks>
 	public bool Running { get; set; }
 
+	/// <summary>
+	/// Gets or sets a value indicating whether this <see cref="Toplevel"/> can focus.
+	/// </summary>
+	/// <value><c>true</c> if can focus; otherwise, <c>false</c>.</value>
+	public override bool CanFocus => SuperView == null ? true : base.CanFocus;
+
+	/// <summary>
+	/// Determines whether the <see cref="Toplevel"/> is modal or not.
+	/// If set to <c>false</c> (the default):
+	/// <list type="bullet">
+	///         <item>
+	///                 <description><see cref="View.OnKeyDown"/> events will propagate keys upwards.</description>
+	///         </item>
+	///         <item>
+	///                 <description>The Toplevel will act as an embedded view (not a modal/pop-up).</description>
+	///         </item>
+	/// </list>
+	/// If set to <c>true</c>:
+	/// <list type="bullet">
+	///         <item>
+	///                 <description><see cref="View.OnKeyDown"/> events will NOT propagate keys upwards.</description>
+	///         </item>
+	///         <item>
+	///                 <description>
+	///                 The Toplevel will and look like a modal (pop-up) (e.g. see
+	///                 <see cref="Dialog"/>.
+	///                 </description>
+	///         </item>
+	/// </list>
+	/// </summary>
+	public bool Modal { get; set; }
+
+	/// <summary>
+	/// Gets or sets the menu for this Toplevel.
+	/// </summary>
+	public virtual MenuBar MenuBar { get; set; }
+
+	/// <summary>
+	/// Gets or sets the status bar for this Toplevel.
+	/// </summary>
+	public virtual StatusBar StatusBar { get; set; }
+
+	/// <summary>
+	/// <see langword="true"/> if was already loaded by the <see cref="Application.Begin(Toplevel)"/>
+	/// <see langword="false"/>, otherwise.
+	/// </summary>
+	public bool IsLoaded { get; private set; }
+
 	/// <summary>
 	/// Invoked when the <see cref="Toplevel"/> <see cref="RunState"/> has begun to be loaded.
-	/// A Loaded event handler is a good place to finalize initialization before calling 
+	/// A Loaded event handler is a good place to finalize initialization before calling
 	/// <see cref="Application.RunLoop(RunState)"/>.
 	/// </summary>
 	public event EventHandler Loaded;
 
 	/// <summary>
 	/// Invoked when the <see cref="Toplevel"/> main loop has started it's first iteration.
-	/// Subscribe to this event to perform tasks when the <see cref="Toplevel"/> has been laid out and focus has been set.
-	/// changes. 
-	/// <para>A Ready event handler is a good place to finalize initialization after calling 
-	/// <see cref="Application.Run(Func{Exception, bool})"/> on this <see cref="Toplevel"/>.</para>
+	/// Subscribe to this event to perform tasks when the <see cref="Toplevel"/> has been laid out and
+	/// focus has been set.
+	/// changes.
+	/// <para>
+	/// A Ready event handler is a good place to finalize initialization after calling
+	/// <see cref="Application.Run(Func{Exception, bool})"/> on this <see cref="Toplevel"/>.
+	/// </para>
 	/// </summary>
 	public event EventHandler Ready;
 
 	/// <summary>
 	/// Invoked when the Toplevel <see cref="RunState"/> has been unloaded.
-	/// A Unloaded event handler is a good place to dispose objects after calling <see cref="Application.End(RunState)"/>.
+	/// A Unloaded event handler is a good place to dispose objects after calling
+	/// <see cref="Application.End(RunState)"/>.
 	/// </summary>
 	public event EventHandler Unloaded;
 
 	/// <summary>
-	/// Invoked when the Toplevel <see cref="RunState"/> becomes the <see cref="Application.Current"/> Toplevel.
+	/// Invoked when the Toplevel <see cref="RunState"/> becomes the <see cref="Application.Current"/>
+	/// Toplevel.
 	/// </summary>
 	public event EventHandler<ToplevelEventArgs> Activate;
 
 	/// <summary>
-	/// Invoked when the Toplevel<see cref="RunState"/> ceases to be the <see cref="Application.Current"/> Toplevel.
+	/// Invoked when the Toplevel<see cref="RunState"/> ceases to be the <see cref="Application.Current"/>
+	/// Toplevel.
 	/// </summary>
 	public event EventHandler<ToplevelEventArgs> Deactivate;
 
 	/// <summary>
-	/// Invoked when a child of the Toplevel <see cref="RunState"/> is closed by  
+	/// Invoked when a child of the Toplevel <see cref="RunState"/> is closed by
 	/// <see cref="Application.End(RunState)"/>.
 	/// </summary>
 	public event EventHandler<ToplevelEventArgs> ChildClosed;
 
 	/// <summary>
-	/// Invoked when the last child of the Toplevel <see cref="RunState"/> is closed from 
+	/// Invoked when the last child of the Toplevel <see cref="RunState"/> is closed from
 	/// by <see cref="Application.End(RunState)"/>.
 	/// </summary>
 	public event EventHandler AllChildClosed;
 
 	/// <summary>
-	/// Invoked when the Toplevel's <see cref="RunState"/> is being closed by  
+	/// Invoked when the Toplevel's <see cref="RunState"/> is being closed by
 	/// <see cref="Application.RequestStop(Toplevel)"/>.
 	/// </summary>
 	public event EventHandler<ToplevelClosingEventArgs> Closing;
 
 	/// <summary>
-	/// Invoked when the Toplevel's <see cref="RunState"/> is closed by <see cref="Application.End(RunState)"/>.
+	/// Invoked when the Toplevel's <see cref="RunState"/> is closed by
+	/// <see cref="Application.End(RunState)"/>.
 	/// </summary>
 	public event EventHandler<ToplevelEventArgs> Closed;
 
@@ -131,7 +216,8 @@ public partial class Toplevel : View {
 	internal virtual void OnActivate (Toplevel deactivated) => Activate?.Invoke (this, new ToplevelEventArgs (deactivated));
 
 	/// <summary>
-	/// Called from <see cref="Application.Begin(Toplevel)"/> before the <see cref="Toplevel"/> redraws for the first time. 
+	/// Called from <see cref="Application.Begin(Toplevel)"/> before the <see cref="Toplevel"/> redraws for
+	/// the first time.
 	/// </summary>
 	public virtual void OnLoaded ()
 	{
@@ -143,7 +229,7 @@ public partial class Toplevel : View {
 	}
 
 	/// <summary>
-	/// Called from <see cref="Application.RunLoop"/> after the <see cref="Toplevel"/> has entered the 
+	/// Called from <see cref="Application.RunLoop"/> after the <see cref="Toplevel"/> has entered the
 	/// first iteration of the loop.
 	/// </summary>
 	internal virtual void OnReady ()
@@ -165,23 +251,6 @@ public partial class Toplevel : View {
 		Unloaded?.Invoke (this, EventArgs.Empty);
 	}
 
-	/// <summary>
-	/// Initializes a new instance of the <see cref="Toplevel"/> class with the specified <see cref="LayoutStyle.Absolute"/> layout.
-	/// </summary>
-	/// <param name="frame">A Superview-relative rectangle specifying the location and size for the new Toplevel</param>
-	public Toplevel (Rect frame) : base (frame) => SetInitialProperties ();
-
-	/// <summary>
-	/// Initializes a new instance of the <see cref="Toplevel"/> class with <see cref="LayoutStyle.Computed"/> layout, 
-	/// defaulting to full screen.
-	/// </summary>
-	public Toplevel () : base ()
-	{
-		SetInitialProperties ();
-		Width = Dim.Fill ();
-		Height = Dim.Fill ();
-	}
-
 	void SetInitialProperties ()
 	{
 		ColorScheme = Colors.TopLevel;
@@ -247,7 +316,7 @@ public partial class Toplevel : View {
 		KeyBindings.Add (KeyCode.Tab | KeyCode.ShiftMask | KeyCode.CtrlMask, Command.PreviousViewOrTop);
 
 		KeyBindings.Add (KeyCode.F5, Command.Refresh);
-		KeyBindings.Add ((KeyCode)Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
+		KeyBindings.Add ((KeyCode)Application.AlternateForwardKey, Command.NextViewOrTop);     // Needed on Unix
 		KeyBindings.Add ((KeyCode)Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
 
 #if UNIX_KEY_BINDINGS
@@ -320,60 +389,6 @@ public partial class Toplevel : View {
 		QuitKeyChanged?.Invoke (this, e);
 	}
 
-	/// <summary>
-	/// Convenience factory method that creates a new Toplevel with the current terminal dimensions.
-	/// </summary>
-	/// <returns>The created Toplevel.</returns>
-	public static Toplevel Create () => new Toplevel (new Rect (0, 0, Driver.Cols, Driver.Rows));
-
-	/// <summary>
-	/// Gets or sets a value indicating whether this <see cref="Toplevel"/> can focus.
-	/// </summary>
-	/// <value><c>true</c> if can focus; otherwise, <c>false</c>.</value>
-	public override bool CanFocus => SuperView == null ? true : base.CanFocus;
-
-	/// <summary>
-	/// Determines whether the <see cref="Toplevel"/> is modal or not. 
-	/// If set to <c>false</c> (the default):
-	/// 
-	/// <list type="bullet">
-	///   <item>
-	///		<description><see cref="View.OnKeyDown"/> events will propagate keys upwards.</description>
-	///   </item>
-	///   <item>
-	///		<description>The Toplevel will act as an embedded view (not a modal/pop-up).</description>
-	///   </item>
-	/// </list>
-	///
-	/// If set to <c>true</c>:
-	/// 
-	/// <list type="bullet">
-	///   <item>
-	///		<description><see cref="View.OnKeyDown"/> events will NOT propagate keys upwards.</description>
-	///	  </item>
-	///   <item>
-	///		<description>The Toplevel will and look like a modal (pop-up) (e.g. see <see cref="Dialog"/>.</description>
-	///   </item>
-	/// </list>
-	/// </summary>
-	public bool Modal { get; set; }
-
-	/// <summary>
-	/// Gets or sets the menu for this Toplevel.
-	/// </summary>
-	public virtual MenuBar MenuBar { get; set; }
-
-	/// <summary>
-	/// Gets or sets the status bar for this Toplevel.
-	/// </summary>
-	public virtual StatusBar StatusBar { get; set; }
-
-	/// <summary>
-	/// <see langword="true"/> if was already loaded by the <see cref="Application.Begin(Toplevel)"/>
-	/// <see langword="false"/>, otherwise.
-	/// </summary>
-	public bool IsLoaded { get; private set; }
-
 	void MovePreviousViewOrTop ()
 	{
 		if (Application.OverlappedTop == null) {
@@ -461,9 +476,9 @@ public partial class Toplevel : View {
 			return;
 		}
 
-		bool found = false;
-		bool focusProcessed = false;
-		int idx = 0;
+		var found = false;
+		var focusProcessed = false;
+		var idx = 0;
 
 		foreach (var v in views) {
 			if (v == this) {
@@ -538,13 +553,16 @@ public partial class Toplevel : View {
 	}
 
 	/// <summary>
-	///  Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the <paramref name="top"/>'s 
-	///  <see cref="View.SuperView"/> (e.g. for dragging a Window).
-	///  The `out` parameters are the new X and Y coordinates.
+	/// Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the
+	/// <paramref name="top"/>'s
+	/// <see cref="View.SuperView"/> (e.g. for dragging a Window).
+	/// The `out` parameters are the new X and Y coordinates.
 	/// </summary>
 	/// <remarks>
-	/// If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not <see cref="Application.Top"/>
-	/// the position will be bound by the <see cref="ConsoleDriver.Cols"/> and <see cref="ConsoleDriver.Rows"/>.
+	/// If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
+	/// <see cref="Application.Top"/>
+	/// the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
+	/// <see cref="ConsoleDriver.Rows"/>.
 	/// </remarks>
 	/// <param name="top">The Toplevel that is to be moved.</param>
 	/// <param name="targetX">The target x location.</param>
@@ -554,11 +572,17 @@ public partial class Toplevel : View {
 	/// <param name="menuBar">The new top most menuBar</param>
 	/// <param name="statusBar">The new top most statusBar</param>
 	/// <returns>
-	///  Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
-	///  <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
-	///  </returns>
-	internal View GetLocationThatFits (Toplevel top, int targetX, int targetY,
-					out int nx, out int ny, out MenuBar menuBar, out StatusBar statusBar)
+	/// Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
+	/// <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the
+	/// correct View.
+	/// </returns>
+	internal View GetLocationThatFits (Toplevel top,
+					   int targetX,
+					   int targetY,
+					   out int nx,
+					   out int ny,
+					   out MenuBar menuBar,
+					   out StatusBar statusBar)
 	{
 		int maxWidth;
 		View superView;
@@ -645,21 +669,22 @@ public partial class Toplevel : View {
 
 	/// <summary>
 	/// Adjusts the location and size of <paramref name="top"/> within this Toplevel.
-	/// Virtual method enabling implementation of specific positions for inherited <see cref="Toplevel"/> views.
+	/// Virtual method enabling implementation of specific positions for inherited <see cref="Toplevel"/>
+	/// views.
 	/// </summary>
 	/// <param name="top">The Toplevel to adjust.</param>
 	public virtual void PositionToplevel (Toplevel top)
 	{
 		var superView = GetLocationThatFits (top, top.Frame.X, top.Frame.Y,
-			out int nx, out int ny, out _, out var sb);
-		bool layoutSubviews = false;
-		int maxWidth = 0;
+			out var nx, out var ny, out _, out var sb);
+		var layoutSubviews = false;
+		var maxWidth = 0;
 		if (superView.Margin != null && superView == top.SuperView) {
 			maxWidth -= superView.GetFramesThickness ().Left + superView.GetFramesThickness ().Right;
 		}
-		if ((superView != top || top?.SuperView != null || top != Application.Top && top.Modal
-			|| top?.SuperView == null && top.IsOverlapped)
-		&& (top.Frame.X + top.Frame.Width > maxWidth || ny > top.Frame.Y) && top.LayoutStyle == LayoutStyle.Computed) {
+		if ((superView != top || top?.SuperView != null || top != Application.Top && top.Modal || top?.SuperView == null && top.IsOverlapped) &&
+		    (top.Frame.X + top.Frame.Width > maxWidth || ny > top.Frame.Y) &&
+		    top.LayoutStyle == LayoutStyle.Computed) {
 
 			if ((top.X == null || top.X is Pos.PosAbsolute) && top.Frame.X != nx) {
 				top.X = nx;
@@ -672,8 +697,7 @@ public partial class Toplevel : View {
 		}
 
 		// TODO: v2 - This is a hack to get the StatusBar to be positioned correctly.
-		if (sb != null && !top.Subviews.Contains (sb) && ny + top.Frame.Height != superView.Frame.Height - (sb.Visible ? 1 : 0)
-		&& top.Height is Dim.DimFill && -top.Height.Anchor (0) < 1) {
+		if (sb != null && !top.Subviews.Contains (sb) && ny + top.Frame.Height != superView.Frame.Height - (sb.Visible ? 1 : 0) && top.Height is Dim.DimFill && -top.Height.Anchor (0) < 1) {
 
 			top.Height = Dim.Fill (sb.Visible ? 1 : 0);
 			layoutSubviews = true;
@@ -741,9 +765,6 @@ public partial class Toplevel : View {
 		return false;
 	}
 
-	internal static Point? _dragPosition;
-	Point _startGrabPoint;
-
 	///<inheritdoc/>
 	public override bool MouseEvent (MouseEvent mouseEvent)
 	{
@@ -754,9 +775,7 @@ public partial class Toplevel : View {
 		//System.Diagnostics.Debug.WriteLine ($"dragPosition before: {dragPosition.HasValue}");
 
 		int nx, ny;
-		if (!_dragPosition.HasValue && (mouseEvent.Flags == MouseFlags.Button1Pressed
-						|| mouseEvent.Flags == MouseFlags.Button2Pressed
-						|| mouseEvent.Flags == MouseFlags.Button3Pressed)) {
+		if (!_dragPosition.HasValue && (mouseEvent.Flags == MouseFlags.Button1Pressed || mouseEvent.Flags == MouseFlags.Button2Pressed || mouseEvent.Flags == MouseFlags.Button3Pressed)) {
 
 			SetFocus ();
 			Application.BringOverlappedTopToFront ();
@@ -774,8 +793,9 @@ public partial class Toplevel : View {
 
 			//System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
 			return true;
-		} else if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
-			mouseEvent.Flags == MouseFlags.Button3Pressed) {
+		}
+		if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
+		    mouseEvent.Flags == MouseFlags.Button3Pressed) {
 			if (_dragPosition.HasValue) {
 				if (SuperView == null) {
 					// Redraw the entire app window using just our Frame. Since we are 
@@ -813,15 +833,14 @@ public partial class Toplevel : View {
 	}
 
 	/// <summary>
-	/// Stops and closes this <see cref="Toplevel"/>. If this Toplevel is the top-most Toplevel, 
+	/// Stops and closes this <see cref="Toplevel"/>. If this Toplevel is the top-most Toplevel,
 	/// <see cref="Application.RequestStop(Toplevel)"/> will be called, causing the application to exit.
 	/// </summary>
 	public virtual void RequestStop ()
 	{
-		if (IsOverlappedContainer && Running
-					&& (Application.Current == this
-					|| Application.Current?.Modal == false
-					|| Application.Current?.Modal == true && Application.Current?.Running == false)) {
+		if (IsOverlappedContainer &&
+		    Running &&
+		    (Application.Current == this || Application.Current?.Modal == false || Application.Current?.Modal == true && Application.Current?.Running == false)) {
 
 			foreach (var child in Application.OverlappedChildren) {
 				var ev = new ToplevelClosingEventArgs (this);
@@ -852,7 +871,8 @@ public partial class Toplevel : View {
 	}
 
 	/// <summary>
-	/// Stops and closes the <see cref="Toplevel"/> specified by <paramref name="top"/>. If <paramref name="top"/> is the top-most Toplevel, 
+	/// Stops and closes the <see cref="Toplevel"/> specified by <paramref name="top"/>. If
+	/// <paramref name="top"/> is the top-most Toplevel,
 	/// <see cref="Application.RequestStop(Toplevel)"/> will be called, causing the application to exit.
 	/// </summary>
 	/// <param name="top">The Toplevel to request stop.</param>
@@ -902,69 +922,82 @@ public partial class Toplevel : View {
 		base.Dispose (disposing);
 	}
 }
+
 /// <summary>
 /// Implements the <see cref="IEqualityComparer{T}"/> for comparing two <see cref="Toplevel"/>s
 /// used by <see cref="StackExtensions"/>.
 /// </summary>
 public class ToplevelEqualityComparer : IEqualityComparer<Toplevel> {
 	/// <summary>Determines whether the specified objects are equal.</summary>
-	/// <param name="x">The first object of type <see cref="Toplevel" /> to compare.</param>
-	/// <param name="y">The second object of type <see cref="Toplevel" /> to compare.</param>
+	/// <param name="x">The first object of type <see cref="Toplevel"/> to compare.</param>
+	/// <param name="y">The second object of type <see cref="Toplevel"/> to compare.</param>
 	/// <returns>
-	///     <see langword="true" /> if the specified objects are equal; otherwise, <see langword="false" />.</returns>
+	/// <see langword="true"/> if the specified objects are equal; otherwise, <see langword="false"/>.
+	/// </returns>
 	public bool Equals (Toplevel x, Toplevel y)
 	{
 		if (y == null && x == null) {
 			return true;
-		} else if (x == null || y == null) {
+		}
+		if (x == null || y == null) {
 			return false;
-		} else if (x.Id == y.Id) {
+		}
+		if (x.Id == y.Id) {
 			return true;
-		} else {
-			return false;
 		}
+		return false;
 	}
 
 	/// <summary>Returns a hash code for the specified object.</summary>
-	/// <param name="obj">The <see cref="Toplevel" /> for which a hash code is to be returned.</param>
+	/// <param name="obj">The <see cref="Toplevel"/> for which a hash code is to be returned.</param>
 	/// <returns>A hash code for the specified object.</returns>
-	/// <exception cref="ArgumentNullException">The type of <paramref name="obj" /> 
-	/// is a reference type and <paramref name="obj" /> is <see langword="null" />.</exception>
+	/// <exception cref="ArgumentNullException">
+	/// The type of <paramref name="obj"/>
+	/// is a reference type and <paramref name="obj"/> is <see langword="null"/>.
+	/// </exception>
 	public int GetHashCode (Toplevel obj)
 	{
 		if (obj == null) {
 			throw new ArgumentNullException ();
 		}
 
-		int hCode = 0;
-		if (int.TryParse (obj.Id, out int result)) {
+		var hCode = 0;
+		if (int.TryParse (obj.Id, out var result)) {
 			hCode = result;
 		}
 		return hCode.GetHashCode ();
 	}
 }
+
 /// <summary>
-/// Implements the <see cref="IComparer{T}"/> to sort the <see cref="Toplevel"/> 
+/// Implements the <see cref="IComparer{T}"/> to sort the <see cref="Toplevel"/>
 /// from the <see cref="Application.OverlappedChildren"/> if needed.
 /// </summary>
 public sealed class ToplevelComparer : IComparer<Toplevel> {
-	/// <summary>Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.</summary>
+	/// <summary>
+	/// Compares two objects and returns a value indicating whether one is less than, equal to, or
+	/// greater than the other.
+	/// </summary>
 	/// <param name="x">The first object to compare.</param>
 	/// <param name="y">The second object to compare.</param>
-	/// <returns>A signed integer that indicates the relative values of <paramref name="x" /> and <paramref name="y" />, as shown in the following table.Value Meaning Less than zero
-	///             <paramref name="x" /> is less than <paramref name="y" />.Zero
-	///             <paramref name="x" /> equals <paramref name="y" />.Greater than zero
-	///             <paramref name="x" /> is greater than <paramref name="y" />.</returns>
+	/// <returns>
+	/// A signed integer that indicates the relative values of <paramref name="x"/> and
+	/// <paramref name="y"/>, as shown in the following table.Value Meaning Less than zero
+	/// <paramref name="x"/> is less than <paramref name="y"/>.Zero
+	/// <paramref name="x"/> equals <paramref name="y"/>.Greater than zero
+	/// <paramref name="x"/> is greater than <paramref name="y"/>.
+	/// </returns>
 	public int Compare (Toplevel x, Toplevel y)
 	{
 		if (ReferenceEquals (x, y)) {
 			return 0;
-		} else if (x == null) {
+		}
+		if (x == null) {
 			return -1;
-		} else if (y == null) {
+		}
+		if (y == null) {
 			return 1;
-		} else {
-			return string.Compare (x.Id, y.Id);
 		}
+		return string.Compare (x.Id, y.Id);
 	}
 }

+ 137 - 183
Terminal.Gui/Views/ToplevelOverlapped.cs

@@ -1,226 +1,180 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Linq;
 
-namespace Terminal.Gui {
-	public partial class Toplevel {
-		/// <summary>
-		/// Gets or sets if this Toplevel is a container for overlapped children.
-		/// </summary>
-		public bool IsOverlappedContainer { get; set; }
-
-		/// <summary>
-		/// Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.
-		/// </summary>
-		public bool IsOverlapped {
-			get {
-				return Application.OverlappedTop != null && Application.OverlappedTop != this && !Modal;
-			}
-		}
-
-	}
+namespace Terminal.Gui;
 
-	public static partial class Application {
-
-		/// <summary>
-		/// Gets the list of the Overlapped children which are not modal <see cref="Toplevel"/> from the <see cref="OverlappedTop"/>.
-		/// </summary>
-		public static List<Toplevel> OverlappedChildren {
-			get {
-				if (OverlappedTop != null) {
-					List<Toplevel> _overlappedChildren = new List<Toplevel> ();
-					foreach (var top in _topLevels) {
-						if (top != OverlappedTop && !top.Modal) {
-							_overlappedChildren.Add (top);
-						}
-					}
-					return _overlappedChildren;
-				}
-				return null;
-			}
-		}
-
-		/// <summary>
-		/// The <see cref="Toplevel"/> object used for the application on startup which <see cref="Toplevel.IsOverlappedContainer"/> is true.
-		/// </summary>
-		public static Toplevel OverlappedTop {
-			get {
-				if (Top.IsOverlappedContainer) {
-					return Top;
-				}
-				return null;
-			}
-		}
-
-
-		static View FindDeepestOverlappedView (View start, int x, int y, out int resx, out int resy)
-		{
-			if (start.GetType ().BaseType != typeof (Toplevel)
-				&& !((Toplevel)start).IsOverlappedContainer) {
-				resx = 0;
-				resy = 0;
-				return null;
-			}
+public partial class Toplevel {
+	/// <summary>
+	/// Gets or sets if this Toplevel is a container for overlapped children.
+	/// </summary>
+	public bool IsOverlappedContainer { get; set; }
 
-			var startFrame = start.Frame;
-
-			if (!startFrame.Contains (x, y)) {
-				resx = 0;
-				resy = 0;
-				return null;
-			}
+	/// <summary>
+	/// Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.
+	/// </summary>
+	public bool IsOverlapped => Application.OverlappedTop != null && Application.OverlappedTop != this && !Modal;
+}
 
-			int count = _topLevels.Count;
-			for (int i = count - 1; i >= 0; i--) {
+public static partial class Application {
+	/// <summary>
+	/// Gets the list of the Overlapped children which are not modal <see cref="Toplevel"/> from the
+	/// <see cref="OverlappedTop"/>.
+	/// </summary>
+	public static List<Toplevel> OverlappedChildren {
+		get {
+			if (OverlappedTop != null) {
+				var _overlappedChildren = new List<Toplevel> ();
 				foreach (var top in _topLevels) {
-					var rx = x - startFrame.X;
-					var ry = y - startFrame.Y;
-					if (top.Visible && top.Frame.Contains (rx, ry)) {
-						var deep = View.FindDeepestView (top, rx, ry, out resx, out resy);
-						if (deep == null)
-							return FindDeepestOverlappedView (top, rx, ry, out resx, out resy);
-						if (deep != OverlappedTop)
-							return deep;
+					if (top != OverlappedTop && !top.Modal) {
+						_overlappedChildren.Add (top);
 					}
 				}
+				return _overlappedChildren;
 			}
-			resx = x - startFrame.X;
-			resy = y - startFrame.Y;
-			return start;
+			return null;
 		}
+	}
 
-		static bool OverlappedChildNeedsDisplay ()
-		{
-			if (OverlappedTop == null) {
-				return false;
+	/// <summary>
+	/// The <see cref="Toplevel"/> object used for the application on startup which
+	/// <see cref="Toplevel.IsOverlappedContainer"/> is true.
+	/// </summary>
+	public static Toplevel OverlappedTop {
+		get {
+			if (Top.IsOverlappedContainer) {
+				return Top;
 			}
+			return null;
+		}
+	}
 
-			foreach (var top in _topLevels) {
-				if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded)) {
-					OverlappedTop.SetSubViewNeedsDisplay ();
-					return true;
-				}
-			}
+	static bool OverlappedChildNeedsDisplay ()
+	{
+		if (OverlappedTop == null) {
 			return false;
 		}
 
-
-		static bool SetCurrentOverlappedAsTop ()
-		{
-			if (OverlappedTop == null && Current != Top && Current?.SuperView == null && Current?.Modal == false) {
-				if (Current.Frame != new Rect (0, 0, Driver.Cols, Driver.Rows)) {
-					Current.Frame = new Rect (0, 0, Driver.Cols, Driver.Rows);
-				}
-				Top = Current;
+		foreach (var top in _topLevels) {
+			if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded)) {
+				OverlappedTop.SetSubViewNeedsDisplay ();
 				return true;
 			}
-			return false;
 		}
+		return false;
+	}
 
-		/// <summary>
-		/// Move to the next Overlapped child from the <see cref="OverlappedTop"/>.
-		/// </summary>
-		public static void OverlappedMoveNext ()
-		{
-			if (OverlappedTop != null && !Current.Modal) {
-				lock (_topLevels) {
-					_topLevels.MoveNext ();
-					var isOverlapped = false;
-					while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
-						if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
-							isOverlapped = true;
-						} else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
-							MoveCurrent (Top);
-							break;
-						}
-						_topLevels.MoveNext ();
+
+	static bool SetCurrentOverlappedAsTop ()
+	{
+		if (OverlappedTop == null && Current != Top && Current?.SuperView == null && Current?.Modal == false) {
+			Top = Current;
+			return true;
+		}
+		return false;
+	}
+
+	/// <summary>
+	/// Move to the next Overlapped child from the <see cref="OverlappedTop"/>.
+	/// </summary>
+	public static void OverlappedMoveNext ()
+	{
+		if (OverlappedTop != null && !Current.Modal) {
+			lock (_topLevels) {
+				_topLevels.MoveNext ();
+				var isOverlapped = false;
+				while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
+					if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
+						isOverlapped = true;
+					} else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
+						MoveCurrent (Top);
+						break;
 					}
-					Current = _topLevels.Peek ();
+					_topLevels.MoveNext ();
 				}
+				Current = _topLevels.Peek ();
 			}
 		}
+	}
 
-		/// <summary>
-		/// Move to the previous Overlapped child from the <see cref="OverlappedTop"/>.
-		/// </summary>
-		public static void OverlappedMovePrevious ()
-		{
-			if (OverlappedTop != null && !Current.Modal) {
-				lock (_topLevels) {
-					_topLevels.MovePrevious ();
-					var isOverlapped = false;
-					while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
-						if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
-							isOverlapped = true;
-						} else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
-							MoveCurrent (Top);
-							break;
-						}
-						_topLevels.MovePrevious ();
+	/// <summary>
+	/// Move to the previous Overlapped child from the <see cref="OverlappedTop"/>.
+	/// </summary>
+	public static void OverlappedMovePrevious ()
+	{
+		if (OverlappedTop != null && !Current.Modal) {
+			lock (_topLevels) {
+				_topLevels.MovePrevious ();
+				var isOverlapped = false;
+				while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
+					if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
+						isOverlapped = true;
+					} else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
+						MoveCurrent (Top);
+						break;
 					}
-					Current = _topLevels.Peek ();
+					_topLevels.MovePrevious ();
 				}
+				Current = _topLevels.Peek ();
 			}
 		}
+	}
 
-		/// <summary>
-		/// Move to the next Overlapped child from the <see cref="OverlappedTop"/> and set it as the <see cref="Top"/> if it is not already.
-		/// </summary>
-		/// <param name="top"></param>
-		/// <returns></returns>
-		public static bool MoveToOverlappedChild (Toplevel top)
-		{
-			if (top.Visible && OverlappedTop != null && Current?.Modal == false) {
-				lock (_topLevels) {
-					_topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
-					Current = top;
-				}
-				return true;
-			}
-			return false;
+	/// <summary>
+	/// Move to the next Overlapped child from the <see cref="OverlappedTop"/> and set it as the
+	/// <see cref="Top"/> if it is not already.
+	/// </summary>
+	/// <param name="top"></param>
+	/// <returns></returns>
+	public static bool MoveToOverlappedChild (Toplevel top)
+	{
+		if (top.Visible && OverlappedTop != null && Current?.Modal == false) {
+			lock (_topLevels) {
+				_topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
+				Current = top;
+			}
+			return true;
 		}
+		return false;
+	}
 
 
-		/// <summary>
-		/// Brings the superview of the most focused overlapped view is on front.
-		/// </summary>
-		public static void BringOverlappedTopToFront ()
-		{
-			if (OverlappedTop != null) {
-				return;
-			}
-			var top = FindTopFromView (Top?.MostFocused);
-			if (top != null && Top.Subviews.Count > 1 && Top.Subviews [Top.Subviews.Count - 1] != top) {
-				Top.BringSubviewToFront (top);
-			}
+	/// <summary>
+	/// Brings the superview of the most focused overlapped view is on front.
+	/// </summary>
+	public static void BringOverlappedTopToFront ()
+	{
+		if (OverlappedTop != null) {
+			return;
 		}
+		var top = FindTopFromView (Top?.MostFocused);
+		if (top != null && Top.Subviews.Count > 1 && Top.Subviews [Top.Subviews.Count - 1] != top) {
+			Top.BringSubviewToFront (top);
+		}
+	}
 
 
-		/// <summary>
-		/// Gets the current visible Toplevel overlapped child that matches the arguments pattern.
-		/// </summary>
-		/// <param name="type">The type.</param>
-		/// <param name="exclude">The strings to exclude.</param>
-		/// <returns>The matched view.</returns>
-		public static Toplevel GetTopOverlappedChild (Type type = null, string [] exclude = null)
-		{
-			if (Application.OverlappedTop == null) {
-				return null;
-			}
+	/// <summary>
+	/// Gets the current visible Toplevel overlapped child that matches the arguments pattern.
+	/// </summary>
+	/// <param name="type">The type.</param>
+	/// <param name="exclude">The strings to exclude.</param>
+	/// <returns>The matched view.</returns>
+	public static Toplevel GetTopOverlappedChild (Type type = null, string [] exclude = null)
+	{
+		if (OverlappedTop == null) {
+			return null;
+		}
 
-			foreach (var top in Application.OverlappedChildren) {
-				if (type != null && top.GetType () == type
-					&& exclude?.Contains (top.Data.ToString ()) == false) {
-					return top;
-				} else if ((type != null && top.GetType () != type)
-					|| (exclude?.Contains (top.Data.ToString ()) == true)) {
-					continue;
-				}
+		foreach (var top in OverlappedChildren) {
+			if (type != null && top.GetType () == type && exclude?.Contains (top.Data.ToString ()) == false) {
 				return top;
 			}
-			return null;
+			if (type != null && top.GetType () != type || exclude?.Contains (top.Data.ToString ()) == true) {
+				continue;
+			}
+			return top;
 		}
-
+		return null;
 	}
-}
+}

+ 0 - 2
UnitTests/Application/ApplicationTests.cs

@@ -570,8 +570,6 @@ public class ApplicationTests {
 	public void Begin_Sets_Application_Top_To_Console_Size ()
 	{
 		Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame);
-
-		((FakeDriver)Application.Driver).SetBufferSize (5, 5);
 		Application.Begin (Application.Top);
 		Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame);
 		((FakeDriver)Application.Driver).SetBufferSize (5, 5);

+ 1 - 1
UnitTests/View/NavigationTests.cs

@@ -1001,7 +1001,7 @@ namespace Terminal.Gui.ViewTests {
 		{
 			// Arrange
 			Application.Init ();
-			using var top = Toplevel.Create ();
+			using var top = new Toplevel ();
 			using var view = new View (
 				x: 0,
 				y: 1,

+ 54 - 0
UnitTests/Views/MenuBarTests.cs

@@ -2755,4 +2755,58 @@ wo
 		var exception = Record.Exception (() => Assert.True (menu.NewKeyDownEvent (new Key (KeyCode.AltMask | KeyCode.Q))));
 		Assert.Null (exception);
 	}
+
+	[Fact]
+	public void RemoveAndThenAddMenuBar_ShouldNotChangeWidth ()
+	{
+		MenuBar menuBar;
+		MenuBar menuBar2;
+
+		// TODO: When https: //github.com/gui-cs/Terminal.Gui/issues/3136 is fixed, 
+		// TODO: Change this to Window
+		var w = new View ();
+		menuBar2 = new Terminal.Gui.MenuBar ();
+		menuBar = new Terminal.Gui.MenuBar ();
+		w.Width = Dim.Fill (0);
+		w.Height = Dim.Fill (0);
+		w.X = 0;
+		w.Y = 0;
+
+		w.Visible = true;
+		// TODO: When https: //github.com/gui-cs/Terminal.Gui/issues/3136 is fixed, 
+		// TODO: uncomment this.
+		//w.Modal = false;
+		w.Title = "";
+		menuBar.Width = Dim.Fill (0);
+		menuBar.Height = 1;
+		menuBar.X = 0;
+		menuBar.Y = 0;
+		menuBar.Visible = true;
+		w.Add (menuBar);
+
+		menuBar2.Width = Dim.Fill (0);
+		menuBar2.Height = 1;
+		menuBar2.X = 0;
+		menuBar2.Y = 4;
+		menuBar2.Visible = true;
+		w.Add (menuBar2);
+
+
+		var menuBars = w.Subviews.OfType<MenuBar> ().ToArray ();
+		Assert.Equal (2, menuBars.Length);
+
+		Assert.Equal (Dim.Fill (0), menuBars [0].Width);
+		Assert.Equal (Dim.Fill (0), menuBars [1].Width);
+
+		// Goes wrong here
+		w.Remove (menuBar);
+		w.Remove (menuBar2);
+
+		w.Add (menuBar);
+		w.Add (menuBar2);
+
+		// These assertions fail
+		Assert.Equal (Dim.Fill (0), menuBars [0].Width);
+		Assert.Equal (Dim.Fill (0), menuBars [1].Width);
+	}
 }

+ 0 - 749
UnitTests/Views/OverlappedTests.cs

@@ -1,749 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Terminal.Gui;
-using Xunit;
-using Xunit.Abstractions;
-
-// Alias Console to MockConsole so we don't accidentally use Console
-using Console = Terminal.Gui.FakeConsole;
-
-namespace Terminal.Gui.ViewsTests {
-	public class OverlappedTests {
-		readonly ITestOutputHelper output;
-
-		public OverlappedTests (ITestOutputHelper output)
-		{
-			this.output = output;
-#if DEBUG_IDISPOSABLE
-			Responder.Instances.Clear ();
-			RunState.Instances.Clear ();
-			this.output = output;
-
-#endif
-		}
-
-		[Fact, TestRespondersDisposed]
-		public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
-		{
-			Application.Init (new FakeDriver ());
-
-			var top = new Toplevel ();
-			var rs = Application.Begin (top);
-#if DEBUG_IDISPOSABLE
-			Assert.Equal (4, Responder.Instances.Count);
-#endif
-
-			Application.End (rs);
-			Application.Shutdown ();
-
-#if DEBUG_IDISPOSABLE
-			Assert.Empty (Responder.Instances);
-#endif
-		}
-
-		[Fact, TestRespondersDisposed]
-		public void Dispose_Toplevel_IsOverlappedContainer_True_With_Begin ()
-		{
-			Application.Init (new FakeDriver ());
-
-			var overlapped = new Toplevel { IsOverlappedContainer = true };
-			var rs = Application.Begin (overlapped);
-			Application.End (rs);
-
-			Application.Shutdown ();
-		}
-
-		[Fact, AutoInitShutdown]
-		public void Application_RequestStop_With_Params_On_A_Not_OverlappedContainer_Always_Use_Application_Current ()
-		{
-			var top1 = new Toplevel ();
-			var top2 = new Toplevel ();
-			var top3 = new Window ();
-			var top4 = new Window ();
-			var d = new Dialog ();
-
-			// top1, top2, top3, d1 = 4
-			var iterations = 4;
-
-			top1.Ready += (s, e) => {
-				Assert.Null (Application.OverlappedChildren);
-				Application.Run (top2);
-			};
-			top2.Ready += (s, e) => {
-				Assert.Null (Application.OverlappedChildren);
-				Application.Run (top3);
-			};
-			top3.Ready += (s, e) => {
-				Assert.Null (Application.OverlappedChildren);
-				Application.Run (top4);
-			};
-			top4.Ready += (s, e) => {
-				Assert.Null (Application.OverlappedChildren);
-				Application.Run (d);
-			};
-
-			d.Ready += (s, e) => {
-				Assert.Null (Application.OverlappedChildren);
-				// This will close the d because on a not OverlappedContainer the Application.Current it always used.
-				Application.RequestStop (top1);
-				Assert.True (Application.Current == d);
-			};
-
-			d.Closed += (s, e) => Application.RequestStop (top1);
-
-			Application.Iteration += (s, a) => {
-				Assert.Null (Application.OverlappedChildren);
-				if (iterations == 4) Assert.True (Application.Current == d);
-				else if (iterations == 3) Assert.True (Application.Current == top4);
-				else if (iterations == 2) Assert.True (Application.Current == top3);
-				else if (iterations == 1) Assert.True (Application.Current == top2);
-				else Assert.True (Application.Current == top1);
-				Application.RequestStop (top1);
-				iterations--;
-			};
-
-			Application.Run (top1);
-
-			Assert.Null (Application.OverlappedChildren);
-		}
-
-		class Overlapped : Toplevel {
-			public Overlapped ()
-			{
-				IsOverlappedContainer = true;
-			}
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void OverlappedContainer_With_Toplevel_RequestStop_Balanced ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d = new Dialog ();
-
-			// OverlappedChild = c1, c2, c3
-			// d1 = 1
-			var iterations = 4;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d);
-			};
-
-			// More easy because the Overlapped Container handles all at once
-			d.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				// This will not close the OverlappedContainer because d is a modal Toplevel and will be closed.
-				overlapped.RequestStop ();
-			};
-
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			d.Closed += (s, e) => {
-				overlapped.RequestStop ();
-			};
-
-			Application.Iteration += (s, a) => {
-				if (iterations == 4) {
-					// The Dialog was not closed before and will be closed now.
-					Assert.True (Application.Current == d);
-					Assert.False (d.Running);
-				} else {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					for (int i = 0; i < iterations; i++) Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_With_Params ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d = new Dialog ();
-
-			// OverlappedChild = c1, c2, c3
-			// d1 = 1
-			var iterations = 4;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d);
-			};
-
-			// Also easy because the Overlapped Container handles all at once
-			d.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				// This will not close the OverlappedContainer because d is a modal Toplevel
-				Application.RequestStop (overlapped);
-			};
-
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			d.Closed += (s, e) => Application.RequestStop (overlapped);
-
-			Application.Iteration += (s, a) => {
-				if (iterations == 4) {
-					// The Dialog was not closed before and will be closed now.
-					Assert.True (Application.Current == d);
-					Assert.False (d.Running);
-				} else {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					for (int i = 0; i < iterations; i++) Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_Without_Params ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d = new Dialog ();
-
-			// OverlappedChild = c1, c2, c3 = 3
-			// d1 = 1
-			var iterations = 4;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d);
-			};
-
-			//More harder because it's sequential.
-			d.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				// Close the Dialog
-				Application.RequestStop ();
-			};
-
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			d.Closed += (s, e) => Application.RequestStop (overlapped);
-
-			Application.Iteration += (s, a) => {
-				if (iterations == 4) {
-					// The Dialog still is the current top and we can't request stop to OverlappedContainer
-					// because we are not using parameter calls.
-					Assert.True (Application.Current == d);
-					Assert.False (d.Running);
-				} else {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					for (int i = 0; i < iterations; i++) Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void IsOverlappedChild_Testing ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d = new Dialog ();
-
-			Application.Iteration += (s, a) => {
-				Assert.False (overlapped.IsOverlapped);
-				Assert.True (c1.IsOverlapped);
-				Assert.True (c2.IsOverlapped);
-				Assert.True (c3.IsOverlapped);
-				Assert.False (d.IsOverlapped);
-
-				overlapped.RequestStop ();
-			};
-
-			Application.Run (overlapped);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void Modal_Toplevel_Can_Open_Another_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d1 = new Dialog ();
-			var d2 = new Dialog ();
-
-			// OverlappedChild = c1, c2, c3 = 3
-			// d1, d2 = 2
-			var iterations = 5;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d1);
-			};
-			d1.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d2);
-			};
-
-			d2.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Assert.True (Application.Current == d2);
-				Assert.True (Application.Current.Running);
-				// Trying to close the Dialog1
-				d1.RequestStop ();
-			};
-
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			d1.Closed += (s, e) => {
-				Assert.True (Application.Current == d1);
-				Assert.False (Application.Current.Running);
-				overlapped.RequestStop ();
-			};
-
-			Application.Iteration += (s, a) => {
-				if (iterations == 5) {
-					// The Dialog2 still is the current top and we can't request stop to OverlappedContainer
-					// because Dialog2 and Dialog1 must be closed first.
-					// Dialog2 will be closed in this iteration.
-					Assert.True (Application.Current == d2);
-					Assert.False (Application.Current.Running);
-					Assert.False (d1.Running);
-				} else if (iterations == 4) {
-					// Dialog1 will be closed in this iteration.
-					Assert.True (Application.Current == d1);
-					Assert.False (Application.Current.Running);
-				} else {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					for (int i = 0; i < iterations; i++) Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void Modal_Toplevel_Can_Open_Another_Not_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-			var d1 = new Dialog ();
-			var c4 = new Toplevel ();
-
-			// OverlappedChild = c1, c2, c3, c4 = 4
-			// d1 = 1
-			var iterations = 5;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (d1);
-			};
-			d1.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				Application.Run (c4);
-			};
-
-			c4.Ready += (s, e) => {
-				Assert.Equal (4, Application.OverlappedChildren.Count);
-				// Trying to close the Dialog1
-				d1.RequestStop ();
-			};
-
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			d1.Closed += (s, e) => {
-				overlapped.RequestStop ();
-			};
-
-			Application.Iteration += (s, a) => {
-				if (iterations == 5) {
-					// The Dialog2 still is the current top and we can't request stop to OverlappedContainer
-					// because Dialog2 and Dialog1 must be closed first.
-					// Using request stop here will call the Dialog again without need
-					Assert.True (Application.Current == d1);
-					Assert.False (Application.Current.Running);
-					Assert.True (c4.Running);
-				} else {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					for (int i = 0; i < iterations; i++) Assert.Equal ((iterations - i + (iterations == 4 && i == 0 ? 2 : 1)).ToString (),
-							Application.OverlappedChildren [i].Id);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void MoveCurrent_Returns_False_If_The_Current_And_Top_Parameter_Are_Both_With_Running_Set_To_False ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-
-			// OverlappedChild = c1, c2, c3
-			var iterations = 3;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				c3.RequestStop ();
-				c1.RequestStop ();
-			};
-			// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
-			c1.Closed += (s, e) => {
-				overlapped.RequestStop ();
-			};
-			Application.Iteration += (s, a) => {
-				if (iterations == 3) {
-					// The Current still is c3 because Current.Running is false.
-					Assert.True (Application.Current == c3);
-					Assert.False (Application.Current.Running);
-					// But the Children order were reorder by Running = false
-					Assert.True (Application.OverlappedChildren [0] == c3);
-					Assert.True (Application.OverlappedChildren [1] == c1);
-					Assert.True (Application.OverlappedChildren [^1] == c2);
-				} else if (iterations == 2) {
-					// The Current is c1 and Current.Running is false.
-					Assert.True (Application.Current == c1);
-					Assert.False (Application.Current.Running);
-					Assert.True (Application.OverlappedChildren [0] == c1);
-					Assert.True (Application.OverlappedChildren [^1] == c2);
-				} else if (iterations == 1) {
-					// The Current is c2 and Current.Running is false.
-					Assert.True (Application.Current == c2);
-					Assert.False (Application.Current.Running);
-					Assert.True (Application.OverlappedChildren [^1] == c2);
-				} else {
-					// The Current is overlapped.
-					Assert.True (Application.Current == overlapped);
-					Assert.Empty (Application.OverlappedChildren);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void OverlappedContainer_Throws_If_More_Than_One ()
-		{
-			var overlapped = new Overlapped ();
-			var overlapped2 = new Overlapped ();
-
-			overlapped.Ready += (s, e) => {
-				Assert.Throws<InvalidOperationException> (() => Application.Run (overlapped2));
-				overlapped.RequestStop ();
-			};
-
-			Application.Run (overlapped);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void OverlappedContainer_Open_And_Close_Modal_And_Open_Not_Modal_Toplevels_Randomly ()
-		{
-			var overlapped = new Overlapped ();
-			var logger = new Toplevel ();
-
-			var iterations = 1; // The logger
-			var running = true;
-			var stageCompleted = true;
-			var allStageClosed = false;
-			var overlappedRequestStop = false;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (logger);
-			};
-
-			logger.Ready += (s, e) => Assert.Single (Application.OverlappedChildren);
-
-			Application.Iteration += (s, a) => {
-				if (stageCompleted && running) {
-					stageCompleted = false;
-					var stage = new Window () { Modal = true };
-
-					stage.Ready += (s, e) => {
-						Assert.Equal (iterations, Application.OverlappedChildren.Count);
-						stage.RequestStop ();
-					};
-
-					stage.Closed += (_, _) => {
-						if (iterations == 11) allStageClosed = true;
-						Assert.Equal (iterations, Application.OverlappedChildren.Count);
-						if (running) {
-							stageCompleted = true;
-
-							var rpt = new Window ();
-
-							rpt.Ready += (s, e) => {
-								iterations++;
-								Assert.Equal (iterations, Application.OverlappedChildren.Count);
-							};
-
-							Application.Run (rpt);
-						}
-					};
-
-					Application.Run (stage);
-
-				} else if (iterations == 11 && running) {
-					running = false;
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-
-				} else if (!overlappedRequestStop && running && !allStageClosed) Assert.Equal (iterations, Application.OverlappedChildren.Count);
-				else if (!overlappedRequestStop && !running && allStageClosed) {
-					Assert.Equal (iterations, Application.OverlappedChildren.Count);
-					overlappedRequestStop = true;
-					overlapped.RequestStop ();
-				} else Assert.Empty (Application.OverlappedChildren);
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void AllChildClosed_Event_Test ()
-		{
-			var overlapped = new Overlapped ();
-			var c1 = new Toplevel ();
-			var c2 = new Window ();
-			var c3 = new Window ();
-
-			// OverlappedChild = c1, c2, c3
-			var iterations = 3;
-
-			overlapped.Ready += (s, e) => {
-				Assert.Empty (Application.OverlappedChildren);
-				Application.Run (c1);
-			};
-			c1.Ready += (s, e) => {
-				Assert.Single (Application.OverlappedChildren);
-				Application.Run (c2);
-			};
-			c2.Ready += (s, e) => {
-				Assert.Equal (2, Application.OverlappedChildren.Count);
-				Application.Run (c3);
-			};
-			c3.Ready += (s, e) => {
-				Assert.Equal (3, Application.OverlappedChildren.Count);
-				c3.RequestStop ();
-				c2.RequestStop ();
-				c1.RequestStop ();
-			};
-			// Now this will close the OverlappedContainer when all OverlappedChildren was closed
-			overlapped.AllChildClosed += (s, e) => {
-				overlapped.RequestStop ();
-			};
-			Application.Iteration += (s, a) => {
-				if (iterations == 3) {
-					// The Current still is c3 because Current.Running is false.
-					Assert.True (Application.Current == c3);
-					Assert.False (Application.Current.Running);
-					// But the Children order were reorder by Running = false
-					Assert.True (Application.OverlappedChildren [0] == c3);
-					Assert.True (Application.OverlappedChildren [1] == c2);
-					Assert.True (Application.OverlappedChildren [^1] == c1);
-				} else if (iterations == 2) {
-					// The Current is c2 and Current.Running is false.
-					Assert.True (Application.Current == c2);
-					Assert.False (Application.Current.Running);
-					Assert.True (Application.OverlappedChildren [0] == c2);
-					Assert.True (Application.OverlappedChildren [^1] == c1);
-				} else if (iterations == 1) {
-					// The Current is c1 and Current.Running is false.
-					Assert.True (Application.Current == c1);
-					Assert.False (Application.Current.Running);
-					Assert.True (Application.OverlappedChildren [^1] == c1);
-				} else {
-					// The Current is overlapped.
-					Assert.True (Application.Current == overlapped);
-					Assert.False (Application.Current.Running);
-					Assert.Empty (Application.OverlappedChildren);
-				}
-				iterations--;
-			};
-
-			Application.Run (overlapped);
-
-			Assert.Empty (Application.OverlappedChildren);
-		}
-
-		[Fact]
-		public void MoveToOverlappedChild_Throw_NullReferenceException_Passing_Null_Parameter ()
-		{
-			Assert.Throws<NullReferenceException> (delegate { Application.MoveToOverlappedChild (null); });
-		}
-
-
-		[Fact, AutoInitShutdown]
-		public void Visible_False_Does_Not_Clear ()
-		{
-			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);
-			var rs = Application.Begin (overlapped);
-			Application.Begin (win1);
-			Application.Begin (win2);
-			Assert.Equal (win2, Application.Current);
-			var firstIteration = false;
-			Application.RunIteration (ref rs, ref firstIteration);
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
- ┌───┐
- │   │
- │   │
- │   │
- └───┘", output);
-			var attributes = new Attribute [] {
-				// 0
-				Colors.TopLevel.Normal,
-				// 1
-				Colors.Base.Normal
-			};
-			TestHelpers.AssertDriverColorsAre (@"
-0000000000
-0111110000
-0111110000
-0111110000
-0111110000
-0111110000
-0000000000
-0000000000
-0000000000
-0000000000", null, attributes);
-
-			Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed }));
-			Assert.Equal (win2, Application.MouseGrabView);
-			Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { X = 2, Y = 2, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }));
-			// Need to fool MainLoop into thinking it's running
-			Application.MainLoop.Running = true;
-			Application.RunIteration (ref rs, ref firstIteration);
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-  ┌───┐
-  │   │
-  │   │
-  │   │
-  └───┘", output);
-			TestHelpers.AssertDriverColorsAre (@"
-0000000000
-0000000000
-0011111000
-0011111000
-0011111000
-0011111000
-0011111000
-0000000000
-0000000000
-0000000000", null, attributes);
-
-			Application.Shutdown ();
-		}
-	}
-}

+ 758 - 0
UnitTests/Views/Toplevel/OverlappedTests.cs

@@ -0,0 +1,758 @@
+using System;
+using Terminal.Gui;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace TerminalGui.ViewsTests;
+
+public class OverlappedTests {
+	readonly ITestOutputHelper _output;
+
+	public OverlappedTests (ITestOutputHelper output)
+	{
+		_output = output;
+#if DEBUG_IDISPOSABLE
+		Responder.Instances.Clear ();
+		RunState.Instances.Clear ();
+#endif
+	}
+
+	[Fact]
+	[TestRespondersDisposed]
+	public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
+	{
+		Application.Init (new FakeDriver ());
+
+		var top = new Toplevel ();
+		var rs = Application.Begin (top);
+#if DEBUG_IDISPOSABLE
+		Assert.Equal (4, Responder.Instances.Count);
+#endif
+
+		Application.End (rs);
+		Application.Shutdown ();
+
+#if DEBUG_IDISPOSABLE
+		Assert.Empty (Responder.Instances);
+#endif
+	}
+
+	[Fact]
+	[TestRespondersDisposed]
+	public void Dispose_Toplevel_IsOverlappedContainer_True_With_Begin ()
+	{
+		Application.Init (new FakeDriver ());
+
+		var overlapped = new Toplevel { IsOverlappedContainer = true };
+		var rs = Application.Begin (overlapped);
+		Application.End (rs);
+
+		Application.Shutdown ();
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void Application_RequestStop_With_Params_On_A_Not_OverlappedContainer_Always_Use_Application_Current ()
+	{
+		var top1 = new Toplevel ();
+		var top2 = new Toplevel ();
+		var top3 = new Window ();
+		var top4 = new Window ();
+		var d = new Dialog ();
+
+		// top1, top2, top3, d1 = 4
+		var iterations = 4;
+
+		top1.Ready += (s, e) => {
+			Assert.Null (Application.OverlappedChildren);
+			Application.Run (top2);
+		};
+		top2.Ready += (s, e) => {
+			Assert.Null (Application.OverlappedChildren);
+			Application.Run (top3);
+		};
+		top3.Ready += (s, e) => {
+			Assert.Null (Application.OverlappedChildren);
+			Application.Run (top4);
+		};
+		top4.Ready += (s, e) => {
+			Assert.Null (Application.OverlappedChildren);
+			Application.Run (d);
+		};
+
+		d.Ready += (s, e) => {
+			Assert.Null (Application.OverlappedChildren);
+			// This will close the d because on a not OverlappedContainer the Application.Current it always used.
+			Application.RequestStop (top1);
+			Assert.True (Application.Current == d);
+		};
+
+		d.Closed += (s, e) => Application.RequestStop (top1);
+
+		Application.Iteration += (s, a) => {
+			Assert.Null (Application.OverlappedChildren);
+			if (iterations == 4) {
+				Assert.True (Application.Current == d);
+			} else if (iterations == 3) {
+				Assert.True (Application.Current == top4);
+			} else if (iterations == 2) {
+				Assert.True (Application.Current == top3);
+			} else if (iterations == 1) {
+				Assert.True (Application.Current == top2);
+			} else {
+				Assert.True (Application.Current == top1);
+			}
+			Application.RequestStop (top1);
+			iterations--;
+		};
+
+		Application.Run (top1);
+
+		Assert.Null (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OverlappedContainer_With_Toplevel_RequestStop_Balanced ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d = new Dialog ();
+
+		// OverlappedChild = c1, c2, c3
+		// d1 = 1
+		var iterations = 4;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d);
+		};
+
+		// More easy because the Overlapped Container handles all at once
+		d.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			// This will not close the OverlappedContainer because d is a modal Toplevel and will be closed.
+			overlapped.RequestStop ();
+		};
+
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		d.Closed += (s, e) => {
+			overlapped.RequestStop ();
+		};
+
+		Application.Iteration += (s, a) => {
+			if (iterations == 4) {
+				// The Dialog was not closed before and will be closed now.
+				Assert.True (Application.Current == d);
+				Assert.False (d.Running);
+			} else {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				for (var i = 0; i < iterations; i++) {
+					Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
+				}
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_With_Params ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d = new Dialog ();
+
+		// OverlappedChild = c1, c2, c3
+		// d1 = 1
+		var iterations = 4;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d);
+		};
+
+		// Also easy because the Overlapped Container handles all at once
+		d.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			// This will not close the OverlappedContainer because d is a modal Toplevel
+			Application.RequestStop (overlapped);
+		};
+
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		d.Closed += (s, e) => Application.RequestStop (overlapped);
+
+		Application.Iteration += (s, a) => {
+			if (iterations == 4) {
+				// The Dialog was not closed before and will be closed now.
+				Assert.True (Application.Current == d);
+				Assert.False (d.Running);
+			} else {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				for (var i = 0; i < iterations; i++) {
+					Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
+				}
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_Without_Params ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d = new Dialog ();
+
+		// OverlappedChild = c1, c2, c3 = 3
+		// d1 = 1
+		var iterations = 4;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d);
+		};
+
+		//More harder because it's sequential.
+		d.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			// Close the Dialog
+			Application.RequestStop ();
+		};
+
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		d.Closed += (s, e) => Application.RequestStop (overlapped);
+
+		Application.Iteration += (s, a) => {
+			if (iterations == 4) {
+				// The Dialog still is the current top and we can't request stop to OverlappedContainer
+				// because we are not using parameter calls.
+				Assert.True (Application.Current == d);
+				Assert.False (d.Running);
+			} else {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				for (var i = 0; i < iterations; i++) {
+					Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
+				}
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void IsOverlappedChild_Testing ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d = new Dialog ();
+
+		Application.Iteration += (s, a) => {
+			Assert.False (overlapped.IsOverlapped);
+			Assert.True (c1.IsOverlapped);
+			Assert.True (c2.IsOverlapped);
+			Assert.True (c3.IsOverlapped);
+			Assert.False (d.IsOverlapped);
+
+			overlapped.RequestStop ();
+		};
+
+		Application.Run (overlapped);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void Modal_Toplevel_Can_Open_Another_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d1 = new Dialog ();
+		var d2 = new Dialog ();
+
+		// OverlappedChild = c1, c2, c3 = 3
+		// d1, d2 = 2
+		var iterations = 5;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d1);
+		};
+		d1.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d2);
+		};
+
+		d2.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Assert.True (Application.Current == d2);
+			Assert.True (Application.Current.Running);
+			// Trying to close the Dialog1
+			d1.RequestStop ();
+		};
+
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		d1.Closed += (s, e) => {
+			Assert.True (Application.Current == d1);
+			Assert.False (Application.Current.Running);
+			overlapped.RequestStop ();
+		};
+
+		Application.Iteration += (s, a) => {
+			if (iterations == 5) {
+				// The Dialog2 still is the current top and we can't request stop to OverlappedContainer
+				// because Dialog2 and Dialog1 must be closed first.
+				// Dialog2 will be closed in this iteration.
+				Assert.True (Application.Current == d2);
+				Assert.False (Application.Current.Running);
+				Assert.False (d1.Running);
+			} else if (iterations == 4) {
+				// Dialog1 will be closed in this iteration.
+				Assert.True (Application.Current == d1);
+				Assert.False (Application.Current.Running);
+			} else {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				for (var i = 0; i < iterations; i++) {
+					Assert.Equal ((iterations - i + 1).ToString (), Application.OverlappedChildren [i].Id);
+				}
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void Modal_Toplevel_Can_Open_Another_Not_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+		var d1 = new Dialog ();
+		var c4 = new Toplevel ();
+
+		// OverlappedChild = c1, c2, c3, c4 = 4
+		// d1 = 1
+		var iterations = 5;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (d1);
+		};
+		d1.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			Application.Run (c4);
+		};
+
+		c4.Ready += (s, e) => {
+			Assert.Equal (4, Application.OverlappedChildren.Count);
+			// Trying to close the Dialog1
+			d1.RequestStop ();
+		};
+
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		d1.Closed += (s, e) => {
+			overlapped.RequestStop ();
+		};
+
+		Application.Iteration += (s, a) => {
+			if (iterations == 5) {
+				// The Dialog2 still is the current top and we can't request stop to OverlappedContainer
+				// because Dialog2 and Dialog1 must be closed first.
+				// Using request stop here will call the Dialog again without need
+				Assert.True (Application.Current == d1);
+				Assert.False (Application.Current.Running);
+				Assert.True (c4.Running);
+			} else {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				for (var i = 0; i < iterations; i++) {
+					Assert.Equal ((iterations - i + (iterations == 4 && i == 0 ? 2 : 1)).ToString (),
+						Application.OverlappedChildren [i].Id);
+				}
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void MoveCurrent_Returns_False_If_The_Current_And_Top_Parameter_Are_Both_With_Running_Set_To_False ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+
+		// OverlappedChild = c1, c2, c3
+		var iterations = 3;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			c3.RequestStop ();
+			c1.RequestStop ();
+		};
+		// Now this will close the OverlappedContainer propagating through the OverlappedChildren.
+		c1.Closed += (s, e) => {
+			overlapped.RequestStop ();
+		};
+		Application.Iteration += (s, a) => {
+			if (iterations == 3) {
+				// The Current still is c3 because Current.Running is false.
+				Assert.True (Application.Current == c3);
+				Assert.False (Application.Current.Running);
+				// But the Children order were reorder by Running = false
+				Assert.True (Application.OverlappedChildren [0] == c3);
+				Assert.True (Application.OverlappedChildren [1] == c1);
+				Assert.True (Application.OverlappedChildren [^1] == c2);
+			} else if (iterations == 2) {
+				// The Current is c1 and Current.Running is false.
+				Assert.True (Application.Current == c1);
+				Assert.False (Application.Current.Running);
+				Assert.True (Application.OverlappedChildren [0] == c1);
+				Assert.True (Application.OverlappedChildren [^1] == c2);
+			} else if (iterations == 1) {
+				// The Current is c2 and Current.Running is false.
+				Assert.True (Application.Current == c2);
+				Assert.False (Application.Current.Running);
+				Assert.True (Application.OverlappedChildren [^1] == c2);
+			} else {
+				// The Current is overlapped.
+				Assert.True (Application.Current == overlapped);
+				Assert.Empty (Application.OverlappedChildren);
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OverlappedContainer_Throws_If_More_Than_One ()
+	{
+		var overlapped = new Overlapped ();
+		var overlapped2 = new Overlapped ();
+
+		overlapped.Ready += (s, e) => {
+			Assert.Throws<InvalidOperationException> (() => Application.Run (overlapped2));
+			overlapped.RequestStop ();
+		};
+
+		Application.Run (overlapped);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OverlappedContainer_Open_And_Close_Modal_And_Open_Not_Modal_Toplevels_Randomly ()
+	{
+		var overlapped = new Overlapped ();
+		var logger = new Toplevel ();
+
+		var iterations = 1; // The logger
+		var running = true;
+		var stageCompleted = true;
+		var allStageClosed = false;
+		var overlappedRequestStop = false;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (logger);
+		};
+
+		logger.Ready += (s, e) => Assert.Single (Application.OverlappedChildren);
+
+		Application.Iteration += (s, a) => {
+			if (stageCompleted && running) {
+				stageCompleted = false;
+				var stage = new Window { Modal = true };
+
+				stage.Ready += (s, e) => {
+					Assert.Equal (iterations, Application.OverlappedChildren.Count);
+					stage.RequestStop ();
+				};
+
+				stage.Closed += (_, _) => {
+					if (iterations == 11) {
+						allStageClosed = true;
+					}
+					Assert.Equal (iterations, Application.OverlappedChildren.Count);
+					if (running) {
+						stageCompleted = true;
+
+						var rpt = new Window ();
+
+						rpt.Ready += (s, e) => {
+							iterations++;
+							Assert.Equal (iterations, Application.OverlappedChildren.Count);
+						};
+
+						Application.Run (rpt);
+					}
+				};
+
+				Application.Run (stage);
+
+			} else if (iterations == 11 && running) {
+				running = false;
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+
+			} else if (!overlappedRequestStop && running && !allStageClosed) {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+			} else if (!overlappedRequestStop && !running && allStageClosed) {
+				Assert.Equal (iterations, Application.OverlappedChildren.Count);
+				overlappedRequestStop = true;
+				overlapped.RequestStop ();
+			} else {
+				Assert.Empty (Application.OverlappedChildren);
+			}
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void AllChildClosed_Event_Test ()
+	{
+		var overlapped = new Overlapped ();
+		var c1 = new Toplevel ();
+		var c2 = new Window ();
+		var c3 = new Window ();
+
+		// OverlappedChild = c1, c2, c3
+		var iterations = 3;
+
+		overlapped.Ready += (s, e) => {
+			Assert.Empty (Application.OverlappedChildren);
+			Application.Run (c1);
+		};
+		c1.Ready += (s, e) => {
+			Assert.Single (Application.OverlappedChildren);
+			Application.Run (c2);
+		};
+		c2.Ready += (s, e) => {
+			Assert.Equal (2, Application.OverlappedChildren.Count);
+			Application.Run (c3);
+		};
+		c3.Ready += (s, e) => {
+			Assert.Equal (3, Application.OverlappedChildren.Count);
+			c3.RequestStop ();
+			c2.RequestStop ();
+			c1.RequestStop ();
+		};
+		// Now this will close the OverlappedContainer when all OverlappedChildren was closed
+		overlapped.AllChildClosed += (s, e) => {
+			overlapped.RequestStop ();
+		};
+		Application.Iteration += (s, a) => {
+			if (iterations == 3) {
+				// The Current still is c3 because Current.Running is false.
+				Assert.True (Application.Current == c3);
+				Assert.False (Application.Current.Running);
+				// But the Children order were reorder by Running = false
+				Assert.True (Application.OverlappedChildren [0] == c3);
+				Assert.True (Application.OverlappedChildren [1] == c2);
+				Assert.True (Application.OverlappedChildren [^1] == c1);
+			} else if (iterations == 2) {
+				// The Current is c2 and Current.Running is false.
+				Assert.True (Application.Current == c2);
+				Assert.False (Application.Current.Running);
+				Assert.True (Application.OverlappedChildren [0] == c2);
+				Assert.True (Application.OverlappedChildren [^1] == c1);
+			} else if (iterations == 1) {
+				// The Current is c1 and Current.Running is false.
+				Assert.True (Application.Current == c1);
+				Assert.False (Application.Current.Running);
+				Assert.True (Application.OverlappedChildren [^1] == c1);
+			} else {
+				// The Current is overlapped.
+				Assert.True (Application.Current == overlapped);
+				Assert.False (Application.Current.Running);
+				Assert.Empty (Application.OverlappedChildren);
+			}
+			iterations--;
+		};
+
+		Application.Run (overlapped);
+
+		Assert.Empty (Application.OverlappedChildren);
+	}
+
+	[Fact]
+	public void MoveToOverlappedChild_Throw_NullReferenceException_Passing_Null_Parameter () => Assert.Throws<NullReferenceException> (delegate { Application.MoveToOverlappedChild (null); });
+
+	[Fact]
+	[AutoInitShutdown]
+	public void Visible_False_Does_Not_Clear ()
+	{
+		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);
+		var rs = Application.Begin (overlapped);
+		Application.Begin (win1);
+		Application.Begin (win2);
+		Assert.Equal (win2, Application.Current);
+		var firstIteration = false;
+		Application.RunIteration (ref rs, ref firstIteration);
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
+ ┌───┐
+ │   │
+ │   │
+ │   │
+ └───┘", _output);
+		var attributes = new [] {
+			// 0
+			Colors.TopLevel.Normal,
+			// 1
+			Colors.Base.Normal
+		};
+		TestHelpers.AssertDriverColorsAre (@"
+0000000000
+0111110000
+0111110000
+0111110000
+0111110000
+0111110000
+0000000000
+0000000000
+0000000000
+0000000000", null, attributes);
+
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed }));
+		Assert.Equal (win2, Application.MouseGrabView);
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }));
+		// Need to fool MainLoop into thinking it's running
+		Application.MainLoop.Running = true;
+		Application.RunIteration (ref rs, ref firstIteration);
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
+  ┌───┐
+  │   │
+  │   │
+  │   │
+  └───┘", _output);
+		TestHelpers.AssertDriverColorsAre (@"
+0000000000
+0000000000
+0011111000
+0011111000
+0011111000
+0011111000
+0011111000
+0000000000
+0000000000
+0000000000", null, attributes);
+
+		Application.Shutdown ();
+	}
+
+	class Overlapped : Toplevel {
+		public Overlapped () => IsOverlappedContainer = true;
+	}
+}

+ 132 - 99
UnitTests/Views/ToplevelTests.cs → UnitTests/Views/Toplevel/ToplevelTests.cs

@@ -1,13 +1,14 @@
 using System;
+using Terminal.Gui;
 using Xunit;
 using Xunit.Abstractions;
 
-namespace Terminal.Gui.ViewsTests;
+namespace TerminalGui.ViewsTests;
 
 public class ToplevelTests {
-	readonly ITestOutputHelper output;
+	readonly ITestOutputHelper _output;
 
-	public ToplevelTests (ITestOutputHelper output) => this.output = output;
+	public ToplevelTests (ITestOutputHelper output) => _output = output;
 
 	[Fact]
 	[AutoInitShutdown]
@@ -24,16 +25,33 @@ public class ToplevelTests {
 		Assert.Null (top.StatusBar);
 		Assert.False (top.IsOverlappedContainer);
 		Assert.False (top.IsOverlapped);
+
+		// Because Toplevel is LayoutStyle.Computed, SetRelativeLayout needs to be called
+		// to set the Frame.
+		top.SetRelativeLayout (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows));
+		Assert.Equal (new Rect (0,          0, Application.Driver.Cols, Application.Driver.Rows), top.Frame);
 	}
 
 	[Fact]
 	[AutoInitShutdown]
 	public void Create_Toplevel ()
 	{
-		var top = Toplevel.Create ();
-		top.BeginInit ();
-		top.EndInit ();
-		Assert.Equal (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), top.Bounds);
+		var top = new Toplevel ();
+
+		Assert.Equal (Colors.TopLevel, top.ColorScheme);
+		Assert.Equal ("Fill(0)",       top.Width.ToString ());
+		Assert.Equal ("Fill(0)",       top.Height.ToString ());
+		Assert.False (top.Running);
+		Assert.False (top.Modal);
+		Assert.Null (top.MenuBar);
+		Assert.Null (top.StatusBar);
+		Assert.False (top.IsOverlappedContainer);
+		Assert.False (top.IsOverlapped);
+
+		// Because Toplevel is LayoutStyle.Computed, SetRelativeLayout needs to be called
+		// to set the Frame.
+		top.SetRelativeLayout (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows));
+		Assert.Equal (new Rect (0,          0, Application.Driver.Cols, Application.Driver.Rows), top.Frame);
 	}
 
 #if BROKE_IN_2927
@@ -157,7 +175,7 @@ public class ToplevelTests {
 	{
 		var top = new Toplevel ();
 
-		string eventInvoked = "";
+		var eventInvoked = "";
 
 		top.ChildUnloaded += (s, e) => eventInvoked = "ChildUnloaded";
 		top.OnChildUnloaded (top);
@@ -206,7 +224,7 @@ public class ToplevelTests {
 		Assert.Equal (top, Application.Top);
 
 		// Application.Top without menu and status bar.
-		var supView = top.GetLocationThatFits (top, 2, 2, out int nx, out int ny, out var mb, out var sb);
+		var supView = top.GetLocationThatFits (top, 2, 2, out var nx, out var ny, out var mb, out var sb);
 		Assert.Equal (Application.Top, supView);
 		Assert.Equal (0, nx);
 		Assert.Equal (0, ny);
@@ -251,7 +269,7 @@ public class ToplevelTests {
 		Assert.Null (top.StatusBar);
 		Assert.Null (top.MenuBar);
 
-		var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () };
+		var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
 		top.Add (win);
 		top.LayoutSubviews ();
 
@@ -297,7 +315,7 @@ public class ToplevelTests {
 
 		top.Remove (win);
 
-		win = new Window () { Width = 60, Height = 15 };
+		win = new Window { Width = 60, Height = 15 };
 		top.Add (win);
 
 		// Application.Top without menu and status bar.
@@ -331,12 +349,12 @@ public class ToplevelTests {
 		Assert.Equal (new Rect (0, 1, 60, 15), win.Frame);
 
 		Assert.Null (Toplevel._dragPosition);
-		win.MouseEvent (new MouseEvent () { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
+		win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
 		Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
-		win.MouseEvent (new MouseEvent () { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
+		win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
 		Assert.Null (Toplevel._dragPosition);
 		win.CanFocus = false;
-		win.MouseEvent (new MouseEvent () { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
+		win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
 		Assert.Null (Toplevel._dragPosition);
 	}
 
@@ -344,22 +362,22 @@ public class ToplevelTests {
 	[AutoInitShutdown]
 	public void KeyBindings_Command ()
 	{
-		bool isRunning = false;
+		var isRunning = false;
 
-		var win1 = new Window () { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
+		var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
 		var lblTf1W1 = new Label ("Enter text in TextField on Win1:") { Id = "lblTf1W1" };
 		var tf1W1 = new TextField ("Text1 on Win1") { Id = "tf1W1", X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () };
 		var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Id = "lblTvW1", Y = Pos.Bottom (lblTf1W1) + 1 };
-		var tvW1 = new TextView () { Id = "tvW1", X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
+		var tvW1 = new TextView { Id = "tvW1", X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
 		var lblTf2W1 = new Label ("Enter text in TextField on Win1:") { Id = "lblTf2W1", Y = Pos.Bottom (lblTvW1) + 1 };
 		var tf2W1 = new TextField ("Text2 on Win1") { Id = "tf2W1", X = Pos.Left (tf1W1), Width = Dim.Fill () };
 		win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
 
-		var win2 = new Window () { Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill () };
+		var win2 = new Window { Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill () };
 		var lblTf1W2 = new Label ("Enter text in TextField on Win2:") { Id = "lblTf1W2" };
 		var tf1W2 = new TextField ("Text1 on Win2") { Id = "tf1W2", X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () };
 		var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Id = "lblTvW2", Y = Pos.Bottom (lblTf1W2) + 1 };
-		var tvW2 = new TextView () { Id = "tvW2", X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
+		var tvW2 = new TextView { Id = "tvW2", X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
 		var lblTf2W2 = new Label ("Enter text in TextField on Win2:") { Id = "lblTf2W2", Y = Pos.Bottom (lblTvW2) + 1 };
 		var tf2W2 = new TextField ("Text2 on Win2") { Id = "tf2W2", X = Pos.Left (tf1W2), Width = Dim.Fill () };
 		win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
@@ -472,22 +490,22 @@ public class ToplevelTests {
 		Application.Begin (top);
 		Assert.Equal (Application.Top, Application.OverlappedTop);
 
-		bool isRunning = true;
+		var isRunning = true;
 
-		var win1 = new Window () { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
+		var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
 		var lblTf1W1 = new Label ("Enter text in TextField on Win1:");
 		var tf1W1 = new TextField ("Text1 on Win1") { X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () };
 		var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Y = Pos.Bottom (lblTf1W1) + 1 };
-		var tvW1 = new TextView () { X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
+		var tvW1 = new TextView { X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
 		var lblTf2W1 = new Label ("Enter text in TextField on Win1:") { Y = Pos.Bottom (lblTvW1) + 1 };
 		var tf2W1 = new TextField ("Text2 on Win1") { X = Pos.Left (tf1W1), Width = Dim.Fill () };
 		win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
 
-		var win2 = new Window () { Id = "win2", Width = Dim.Percent (50f), Height = Dim.Fill () };
+		var win2 = new Window { Id = "win2", Width = Dim.Percent (50f), Height = Dim.Fill () };
 		var lblTf1W2 = new Label ("Enter text in TextField on Win2:");
 		var tf1W2 = new TextField ("Text1 on Win2") { X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () };
 		var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Y = Pos.Bottom (lblTf1W2) + 1 };
-		var tvW2 = new TextView () { X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
+		var tvW2 = new TextView { X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
 		var lblTf2W2 = new Label ("Enter text in TextField on Win2:") { Y = Pos.Bottom (lblTvW2) + 1 };
 		var tf2W2 = new TextField ("Text2 on Win2") { X = Pos.Left (tf1W2), Width = Dim.Fill () };
 		win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
@@ -620,7 +638,7 @@ public class ToplevelTests {
 		Key alternateForwardKey = default;
 		Key alternateBackwardKey = default;
 		Key quitKey = default;
-		bool wasAdded = false;
+		var wasAdded = false;
 
 		var view = new View ();
 		view.Added += View_Added;
@@ -707,7 +725,7 @@ public class ToplevelTests {
 		var win = new Window ();
 		var top = Application.Top;
 		top.Add (win);
-		int iterations = -1;
+		var iterations = -1;
 		Window testWindow;
 
 		Application.Iteration += (s, a) => {
@@ -715,7 +733,7 @@ public class ToplevelTests {
 			if (iterations == 0) {
 				((FakeDriver)Application.Driver).SetBufferSize (15, 7);
 				// Don't use MessageBox here; it's too complicated for this unit test; just use Window
-				testWindow = new Window () {
+				testWindow = new Window {
 					Text = "Hello",
 					X = 2,
 					Y = 2,
@@ -725,7 +743,7 @@ public class ToplevelTests {
 				Application.Run (testWindow);
 
 			} else if (iterations == 1) {
-				TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌─────────────┐
 │             │
 │ ┌────────┐  │
@@ -733,11 +751,11 @@ public class ToplevelTests {
 │ └────────┘  │
 │             │
 └─────────────┘
-", output);
+", _output);
 			} else if (iterations == 2) {
 				Assert.Null (Application.MouseGrabView);
 				// Grab the mouse
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = 3,
 					Y = 2,
 					Flags = MouseFlags.Button1Pressed
@@ -749,7 +767,7 @@ public class ToplevelTests {
 			} else if (iterations == 3) {
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 				// Drag to left
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = 2,
 					Y = 2,
 					Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -762,20 +780,20 @@ public class ToplevelTests {
 			} else if (iterations == 4) {
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 
-				TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌─────────────┐
 │             │
 │┌────────┐   │
 ││Hello   │   │
 │└────────┘   │
 │             │
-└─────────────┘", output);
+└─────────────┘", _output);
 
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 			} else if (iterations == 5) {
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 				// Drag up
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = 2,
 					Y = 1,
 					Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -788,14 +806,14 @@ public class ToplevelTests {
 			} else if (iterations == 6) {
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 
-				TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌─────────────┐
 │┌────────┐   │
 ││Hello   │   │
 │└────────┘   │
 │             │
 │             │
-└─────────────┘", output);
+└─────────────┘", _output);
 
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 				Assert.Equal (new Rect (1, 1, 10, 3), Application.MouseGrabView.Frame);
@@ -803,7 +821,7 @@ public class ToplevelTests {
 			} else if (iterations == 7) {
 				Assert.Equal (Application.Current, Application.MouseGrabView);
 				// Ungrab the mouse
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = 2,
 					Y = 1,
 					Flags = MouseFlags.Button1Released
@@ -826,7 +844,7 @@ public class ToplevelTests {
 	[AutoInitShutdown]
 	public void Mouse_Drag_On_Top_With_Superview_Not_Null ()
 	{
-		var win = new Window () {
+		var win = new Window {
 			X = 3,
 			Y = 2,
 			Width = 10,
@@ -835,10 +853,10 @@ public class ToplevelTests {
 		var top = Application.Top;
 		top.Add (win);
 
-		int iterations = -1;
+		var iterations = -1;
 
-		int movex = 0;
-		int movey = 0;
+		var movex = 0;
+		var movey = 0;
 
 		var location = new Rect (win.Frame.X, win.Frame.Y, 7, 3);
 
@@ -851,7 +869,7 @@ public class ToplevelTests {
 
 				Assert.Null (Application.MouseGrabView);
 				// Grab the mouse
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = win.Frame.X,
 					Y = win.Frame.Y,
 					Flags = MouseFlags.Button1Pressed
@@ -864,7 +882,7 @@ public class ToplevelTests {
 				// Drag to left
 				movex = 1;
 				movey = 0;
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = win.Frame.X + movex,
 					Y = win.Frame.Y + movey,
 					Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -884,7 +902,7 @@ public class ToplevelTests {
 				// Drag up
 				movex = 0;
 				movey = -1;
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = win.Frame.X + movex,
 					Y = win.Frame.Y + movey,
 					Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -903,7 +921,7 @@ public class ToplevelTests {
 				// Ungrab the mouse
 				movex = 0;
 				movey = 0;
-				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+				Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 					X = win.Frame.X + movex,
 					Y = win.Frame.Y + movey,
 					Flags = MouseFlags.Button1Released
@@ -936,8 +954,8 @@ public class ToplevelTests {
 	[AutoInitShutdown]
 	public void OnEnter_OnLeave_Triggered_On_Application_Begin_End ()
 	{
-		bool isEnter = false;
-		bool isLeave = false;
+		var isEnter = false;
+		var isLeave = false;
 		var v = new View ();
 		v.Enter += (s, _) => isEnter = true;
 		v.Leave += (s, _) => isLeave = true;
@@ -975,10 +993,10 @@ public class ToplevelTests {
 	[AutoInitShutdown]
 	public void OnEnter_OnLeave_Triggered_On_Application_Begin_End_With_More_Toplevels ()
 	{
-		int iterations = 0;
-		int [] steps = new int [5];
-		bool isEnterTop = false;
-		bool isLeaveTop = false;
+		var iterations = 0;
+		var steps = new int [5];
+		var isEnterTop = false;
+		var isLeaveTop = false;
 		var vt = new View ();
 		var top = Application.Top;
 		var diag = new Dialog ();
@@ -1015,8 +1033,8 @@ public class ToplevelTests {
 		Assert.False (isLeaveTop);
 
 		isEnterTop = false;
-		bool isEnterDiag = false;
-		bool isLeaveDiag = false;
+		var isEnterDiag = false;
+		var isLeaveDiag = false;
 		var vd = new View ();
 		vd.Enter += (s, e) => {
 			iterations++;
@@ -1067,7 +1085,7 @@ public class ToplevelTests {
 	public void PositionCursor_SetCursorVisibility_To_Invisible_If_Focused_Is_Null ()
 	{
 		var tf = new TextField ("test") { Width = 5 };
-		var view = new View () { Width = 10, Height = 10 };
+		var view = new View { Width = 10, Height = 10 };
 		view.Add (tf);
 		Application.Top.Add (view);
 		Application.Begin (Application.Top);
@@ -1137,14 +1155,14 @@ public class ToplevelTests {
 	[AutoInitShutdown]
 	public void Toplevel_Inside_ScrollView_MouseGrabView ()
 	{
-		var scrollView = new ScrollView () {
+		var scrollView = new ScrollView {
 			X = 3,
 			Y = 3,
 			Width = 40,
 			Height = 16,
 			ContentSize = new Size (200, 100)
 		};
-		var win = new Window () { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) };
+		var win = new Window { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) };
 		scrollView.Add (win);
 		var top = Application.Top;
 		top.Add (scrollView);
@@ -1170,9 +1188,9 @@ public class ToplevelTests {
       │                                   ░
       │                                   ░
       │                                   ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output);
+   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 6,
 			Y = 6,
 			Flags = MouseFlags.Button1Pressed
@@ -1180,7 +1198,7 @@ public class ToplevelTests {
 		Assert.Equal (win, Application.MouseGrabView);
 		Assert.Equal (new Rect (3, 3, 194, 94), win.Frame);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 9,
 			Y = 9,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1206,9 +1224,9 @@ public class ToplevelTests {
          │                                ░
          │                                ░
          │                                ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output);
+   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 5,
 			Y = 5,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1234,16 +1252,16 @@ public class ToplevelTests {
      │                                    ░
      │                                    ░
      │                                    ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output);
+   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 5,
 			Y = 5,
 			Flags = MouseFlags.Button1Released
 		}));
 		Assert.Null (Application.MouseGrabView);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 4,
 			Y = 4,
 			Flags = MouseFlags.ReportMousePosition
@@ -1256,22 +1274,22 @@ public class ToplevelTests {
 	public void Window_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Left_Right_And_Bottom ()
 	{
 		var top = Application.Top;
-		var window = new Window () { Width = 20, Height = 3 };
+		var window = new Window { Width = 20, Height = 3 };
 		Application.Begin (top);
 		((FakeDriver)Application.Driver).SetBufferSize (40, 10);
 		Application.Begin (window);
 		Application.Refresh ();
 		Assert.Equal (new Rect (0, 0, 40, 10), top.Frame);
 		Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
-		TestHelpers.AssertDriverContentsWithFrameAre (@$"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 │                  │
 └──────────────────┘
-", output);
+", _output);
 
 		Assert.Null (Application.MouseGrabView);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 0,
 			Y = 0,
 			Flags = MouseFlags.Button1Pressed
@@ -1279,7 +1297,7 @@ public class ToplevelTests {
 
 		Assert.Equal (window, Application.MouseGrabView);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = -11,
 			Y = -4,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1288,15 +1306,15 @@ public class ToplevelTests {
 		Application.Refresh ();
 		Assert.Equal (new Rect (0, 0, 40, 10), top.Frame);
 		Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
-		TestHelpers.AssertDriverContentsWithFrameAre (@$"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 │                  │
 └──────────────────┘
-", output);
+", _output);
 
 		// Changes Top size to same size as Dialog more menu and scroll bar
 		((FakeDriver)Application.Driver).SetBufferSize (20, 3);
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = -1,
 			Y = -1,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1305,15 +1323,15 @@ public class ToplevelTests {
 		Application.Refresh ();
 		Assert.Equal (new Rect (0, 0, 20, 3), top.Frame);
 		Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
-		TestHelpers.AssertDriverContentsWithFrameAre (@$"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 │                  │
 └──────────────────┘
-", output);
+", _output);
 
 		// Changes Top size smaller than Dialog size
 		((FakeDriver)Application.Driver).SetBufferSize (19, 2);
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = -1,
 			Y = -1,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1322,12 +1340,12 @@ public class ToplevelTests {
 		Application.Refresh ();
 		Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
 		Assert.Equal (new Rect (-1, 0, 20, 3), window.Frame);
-		TestHelpers.AssertDriverContentsWithFrameAre (@$"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ──────────────────┐
-", output);
+", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 18,
 			Y = 1,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1337,10 +1355,10 @@ public class ToplevelTests {
 		Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
 		Assert.Equal (new Rect (18, 1, 20, 3), window.Frame);
 		TestHelpers.AssertDriverContentsWithFrameAre (@"
-                  ┌", output);
+                  ┌", _output);
 
 		// On a real app we can't go beyond the SuperView bounds
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 19,
 			Y = 2,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1349,7 +1367,7 @@ public class ToplevelTests {
 		Application.Refresh ();
 		Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
 		Assert.Equal (new Rect (19, 2, 20, 3), window.Frame);
-		TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
+		TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
 	}
 
 	[Fact]
@@ -1357,7 +1375,7 @@ public class ToplevelTests {
 	public void Modal_As_Top_Will_Drag_Cleanly ()
 	{
 		// Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
-		var window = new Window () { Width = 10, Height = 3};
+		var window = new Window { Width = 10, Height = 3 };
 		window.Add (new Label (
 			"Test") {
 			X = Pos.Center (),
@@ -1376,15 +1394,15 @@ public class ToplevelTests {
 		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌────────┐
 │  Test  │
-└────────┘", output);
+└────────┘", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 0,
 			Y = 0,
 			Flags = MouseFlags.Button1Pressed
 		}));
 
-		bool firstIteration = false;
+		var firstIteration = false;
 		Application.RunIteration (ref rs, ref firstIteration);
 		Assert.Equal (window, Application.MouseGrabView);
 
@@ -1392,9 +1410,9 @@ public class ToplevelTests {
 		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌────────┐
 │  Test  │
-└────────┘", output);
+└────────┘", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 1,
 			Y = 1,
 			Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
@@ -1403,15 +1421,30 @@ public class ToplevelTests {
 		firstIteration = false;
 		Application.RunIteration (ref rs, ref firstIteration);
 		Assert.Equal (window, Application.MouseGrabView);
-		Assert.Equal (new Rect (1, 1, 10,3), window.Frame);
+		Assert.Equal (new Rect (1, 1, 10, 3), window.Frame);
 		TestHelpers.AssertDriverContentsWithFrameAre (@"
  ┌────────┐
  │  Test  │
- └────────┘", output);
+ └────────┘", _output);
 
 		Application.End (rs);
 	}
 
+	[Fact]
+	[AutoInitShutdown]
+	public void Begin_With_Window_Sets_Size_Correctly ()
+	{
+		var top = Application.Top;
+		Application.Begin (top);
+		((FakeDriver)Application.Driver).SetBufferSize (20, 20);
+
+		var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
+		Assert.Equal (new Rect (2, 1, 15, 10), testWindow.Frame);
+
+		var rs = Application.Begin (testWindow);
+		Assert.Equal (new Rect (2, 1, 15, 10), testWindow.Frame);
+	}
+
 	// Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
 	[Fact]
 	[AutoInitShutdown]
@@ -1444,14 +1477,14 @@ public class ToplevelTests {
 │                  │
 │                  │
 │                  │
-└──────────────────┘", output);
+└──────────────────┘", _output);
 
 		var btnPopup = new Button ("Popup");
-		var testWindow = new Window () { X = 2, Y = 1, Width = 15, Height = 10 };
+		var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
 		testWindow.Add (btnPopup);
 		btnPopup.Clicked += (s, e) => {
 			var viewToScreen = btnPopup.BoundsToScreen (top.Frame);
-			var viewAddedToTop = new View () {
+			var viewAddedToTop = new View {
 				Text = "viewAddedToTop",
 				X = 1,
 				Y = viewToScreen.Y + 1,
@@ -1504,16 +1537,16 @@ public class ToplevelTests {
 │                  │
 │                  │
 │                  │
-└──────────────────┘", output);
+└──────────────────┘", _output);
 
-		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () {
+		Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
 			X = 5,
 			Y = 2,
 			Flags = MouseFlags.Button1Clicked
 		}));
 		Application.Top.Draw ();
 
-		bool firstIteration = false;
+		var firstIteration = false;
 		Application.RunIteration (ref rs, ref firstIteration);
 		TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ┌──────────────────┐
@@ -1535,7 +1568,7 @@ public class ToplevelTests {
 ││Two             ││
 ││Three           ││
 │└────────────────┘│
-└──────────────────┘", output);
+└──────────────────┘", _output);
 
 		Application.End (rs);
 	}
@@ -1571,9 +1604,9 @@ public class ToplevelTests {
 
 		int count = 0, count1 = 0, count2 = 0;
 		bool log = false, log1 = false, log2 = false;
-		bool fromTopStillKnowFirstIsRunning = false;
-		bool fromTopStillKnowSecondIsRunning = false;
-		bool fromFirstStillKnowSecondIsRunning = false;
+		var fromTopStillKnowFirstIsRunning = false;
+		var fromTopStillKnowSecondIsRunning = false;
+		var fromFirstStillKnowSecondIsRunning = false;
 
 		Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => {
 			count++;

+ 208 - 0
UnitTests/Views/Toplevel/WindowTests.cs

@@ -0,0 +1,208 @@
+using Terminal.Gui;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace TerminalGui.ViewsTests;
+
+public class WindowTests {
+	readonly ITestOutputHelper _output;
+
+	public WindowTests (ITestOutputHelper output) => _output = output;
+
+	[Fact]
+	public void New_Initializes ()
+	{
+		// Parameterless
+		var r = new Window ();
+		Assert.NotNull (r);
+		Assert.Equal (string.Empty, r.Title);
+		Assert.Equal (LayoutStyle.Computed, r.LayoutStyle);
+		Assert.Equal ("Window()(0,0,0,0)", r.ToString ());
+		Assert.True (r.CanFocus);
+		Assert.False (r.HasFocus);
+		Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
+		Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
+		Assert.Null (r.Focused);
+		Assert.NotNull (r.ColorScheme);
+		Assert.Equal (Dim.Fill (), r.Width);
+		Assert.Equal (Dim.Fill (), r.Height);
+		Assert.Null (r.X);
+		Assert.Null (r.Y);
+		Assert.False (r.IsCurrentTop);
+		Assert.Empty (r.Id);
+		Assert.False (r.WantContinuousButtonPressed);
+		Assert.False (r.WantMousePositionReports);
+		Assert.Null (r.SuperView);
+		Assert.Null (r.MostFocused);
+		Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
+
+		// Empty Rect
+		r = new Window (Rect.Empty) { Title = "title" };
+		Assert.NotNull (r);
+		Assert.Equal ("title", r.Title);
+		Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
+		Assert.Equal ("Window(title)(0,0,0,0)", r.ToString ());
+		Assert.True (r.CanFocus);
+		Assert.False (r.HasFocus);
+		Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
+		Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
+		Assert.Null (r.Focused);
+		Assert.NotNull (r.ColorScheme);
+		Assert.Null (r.Width);  // All view Dim are initialized now in the IsAdded setter,
+		Assert.Null (r.Height); // avoiding Dim errors.
+		Assert.Null (r.X);      // All view Pos are initialized now in the IsAdded setter,
+		Assert.Null (r.Y);      // avoiding Pos errors.
+		Assert.False (r.IsCurrentTop);
+		Assert.Equal (r.Title, r.Id);
+		Assert.False (r.WantContinuousButtonPressed);
+		Assert.False (r.WantMousePositionReports);
+		Assert.Null (r.SuperView);
+		Assert.Null (r.MostFocused);
+		Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
+
+		// Rect with values
+		r = new Window (new Rect (1, 2, 3, 4)) { Title = "title" };
+		Assert.Equal ("title", r.Title);
+		Assert.NotNull (r);
+		Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
+		Assert.Equal ("Window(title)(1,2,3,4)", r.ToString ());
+		Assert.True (r.CanFocus);
+		Assert.False (r.HasFocus);
+		Assert.Equal (new Rect (0, 0, 1, 2), r.Bounds);
+		Assert.Equal (new Rect (1, 2, 3, 4), r.Frame);
+		Assert.Null (r.Focused);
+		Assert.NotNull (r.ColorScheme);
+		Assert.Null (r.Width);
+		Assert.Null (r.Height);
+		Assert.Null (r.X);
+		Assert.Null (r.Y);
+		Assert.False (r.IsCurrentTop);
+		Assert.Equal (r.Title, r.Id);
+		Assert.False (r.WantContinuousButtonPressed);
+		Assert.False (r.WantMousePositionReports);
+		Assert.Null (r.SuperView);
+		Assert.Null (r.MostFocused);
+		Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
+		r.Dispose ();
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void MenuBar_And_StatusBar_Inside_Window ()
+	{
+		var menu = new MenuBar (new MenuBarItem [] {
+			new ("File", new MenuItem [] {
+				new ("Open", "", null),
+				new ("Quit", "", null)
+			}),
+			new ("Edit", new MenuItem [] {
+				new ("Copy", "", null)
+			})
+		});
+
+		var sb = new StatusBar (new StatusItem [] {
+			new (KeyCode.CtrlMask | KeyCode.Q, "~^Q~ Quit", null),
+			new (KeyCode.CtrlMask | KeyCode.O, "~^O~ Open", null),
+			new (KeyCode.CtrlMask | KeyCode.C, "~^C~ Copy", null)
+		});
+
+		var fv = new FrameView ("Frame View") {
+			Y = 1,
+			Width = Dim.Fill (),
+			Height = Dim.Fill (1)
+		};
+		var win = new Window ();
+		win.Add (menu, sb, fv);
+		var top = Application.Top;
+		top.Add (win);
+		Application.Begin (top);
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
+┌──────────────────┐
+│ File  Edit       │
+│┌┤Frame View├────┐│
+││                ││
+││                ││
+││                ││
+││                ││
+│└────────────────┘│
+│ ^Q Quit │ ^O Open│
+└──────────────────┘", _output);
+
+		((FakeDriver)Application.Driver).SetBufferSize (40, 20);
+
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
+┌──────────────────────────────────────┐
+│ File  Edit                           │
+│┌┤Frame View├────────────────────────┐│
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+││                                    ││
+│└────────────────────────────────────┘│
+│ ^Q Quit │ ^O Open │ ^C Copy          │
+└──────────────────────────────────────┘", _output);
+
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
+┌──────────────────┐
+│ File  Edit       │
+│┌┤Frame View├────┐│
+││                ││
+││                ││
+││                ││
+││                ││
+│└────────────────┘│
+│ ^Q Quit │ ^O Open│
+└──────────────────┘", _output);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void OnCanFocusChanged_Only_Must_ContentView_Forces_SetFocus_After_IsInitialized_Is_True ()
+	{
+		var win1 = new Window { Id = "win1", Width = 10, Height = 1 };
+		var view1 = new View { Id = "view1", Width = Dim.Fill (), Height = Dim.Fill (), CanFocus = true };
+		var win2 = new Window { Id = "win2", Y = 6, Width = 10, Height = 1 };
+		var view2 = new View { Id = "view2", Width = Dim.Fill (), Height = Dim.Fill (), CanFocus = true };
+		win2.Add (view2);
+		win1.Add (view1, win2);
+
+		Application.Begin (win1);
+
+		Assert.True (win1.HasFocus);
+		Assert.True (view1.HasFocus);
+		Assert.False (win2.HasFocus);
+		Assert.False (view2.HasFocus);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
+	{
+		var menu = new MenuBar (new MenuBarItem [] {
+			new ("Child", new MenuItem [] {
+				new ("_Create Child", "", null)
+			})
+		});
+		var win = new Window ();
+		win.Add (menu);
+		Application.Top.Add (win);
+		Application.Begin (Application.Top);
+
+		var exception = Record.Exception (() => win.NewKeyDownEvent (new Key (KeyCode.AltMask)));
+		Assert.Null (exception);
+	}
+}

+ 0 - 213
UnitTests/Views/WindowTests.cs

@@ -1,213 +0,0 @@
-using System;
-using Xunit;
-using Xunit.Abstractions;
-//using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
-
-// Alias Console to MockConsole so we don't accidentally use Console
-using Console = Terminal.Gui.FakeConsole;
-using System.Text;
-
-namespace Terminal.Gui.ViewsTests {
-	public class WindowTests {
-		readonly ITestOutputHelper output;
-
-		public WindowTests (ITestOutputHelper output)
-		{
-			this.output = output;
-		}
-
-		[Fact]
-		public void New_Initializes ()
-		{
-			// Parameterless
-			var r = new Window ();
-			Assert.NotNull (r);
-			Assert.Equal (string.Empty, r.Title);
-			Assert.Equal (LayoutStyle.Computed, r.LayoutStyle);
-			Assert.Equal ("Window()(0,0,0,0)", r.ToString ());
-			Assert.True (r.CanFocus);
-			Assert.False (r.HasFocus);
-			Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
-			Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
-			Assert.Null (r.Focused);
-			Assert.NotNull (r.ColorScheme);
-			Assert.Equal (Dim.Fill (0), r.Width);
-			Assert.Equal (Dim.Fill (0), r.Height);
-			Assert.Null (r.X);
-			Assert.Null (r.Y);
-			Assert.False (r.IsCurrentTop);
-			Assert.Empty (r.Id);
-			Assert.False (r.WantContinuousButtonPressed);
-			Assert.False (r.WantMousePositionReports);
-			Assert.Null (r.SuperView);
-			Assert.Null (r.MostFocused);
-			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
-
-			// Empty Rect
-			r = new Window (Rect.Empty) { Title = "title" };
-			Assert.NotNull (r);
-			Assert.Equal ("title", r.Title);
-			Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
-			Assert.Equal ("Window(title)(0,0,0,0)", r.ToString ());
-			Assert.True (r.CanFocus);
-			Assert.False (r.HasFocus);
-			Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
-			Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
-			Assert.Null (r.Focused);
-			Assert.NotNull (r.ColorScheme);
-			Assert.Null (r.Width);       // All view Dim are initialized now in the IsAdded setter,
-			Assert.Null (r.Height);      // avoiding Dim errors.
-			Assert.Null (r.X);           // All view Pos are initialized now in the IsAdded setter,
-			Assert.Null (r.Y);           // avoiding Pos errors.
-			Assert.False (r.IsCurrentTop);
-			Assert.Equal (r.Title, r.Id);
-			Assert.False (r.WantContinuousButtonPressed);
-			Assert.False (r.WantMousePositionReports);
-			Assert.Null (r.SuperView);
-			Assert.Null (r.MostFocused);
-			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
-
-			// Rect with values
-			r = new Window (new Rect (1, 2, 3, 4)) { Title = "title" };
-			Assert.Equal ("title", r.Title);
-			Assert.NotNull (r);
-			Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
-			Assert.Equal ("Window(title)(1,2,3,4)", r.ToString ());
-			Assert.True (r.CanFocus);
-			Assert.False (r.HasFocus);
-			Assert.Equal (new Rect (0, 0, 1, 2), r.Bounds);
-			Assert.Equal (new Rect (1, 2, 3, 4), r.Frame);
-			Assert.Null (r.Focused);
-			Assert.NotNull (r.ColorScheme);
-			Assert.Null (r.Width);
-			Assert.Null (r.Height);
-			Assert.Null (r.X);
-			Assert.Null (r.Y);
-			Assert.False (r.IsCurrentTop);
-			Assert.Equal (r.Title, r.Id);
-			Assert.False (r.WantContinuousButtonPressed);
-			Assert.False (r.WantMousePositionReports);
-			Assert.Null (r.SuperView);
-			Assert.Null (r.MostFocused);
-			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
-			r.Dispose ();
-		}
-
-		[Fact, AutoInitShutdown]
-		public void MenuBar_And_StatusBar_Inside_Window ()
-		{
-			var menu = new MenuBar (new MenuBarItem [] {
-				new MenuBarItem ("File", new MenuItem [] {
-					new MenuItem ("Open", "", null),
-					new MenuItem ("Quit", "", null),
-				}),
-				new MenuBarItem ("Edit", new MenuItem [] {
-					new MenuItem ("Copy", "", null),
-				})
-			});
-
-			var sb = new StatusBar (new StatusItem [] {
-				new StatusItem (KeyCode.CtrlMask | KeyCode.Q, "~^Q~ Quit", null),
-				new StatusItem (KeyCode.CtrlMask | KeyCode.O, "~^O~ Open", null),
-				new StatusItem (KeyCode.CtrlMask | KeyCode.C, "~^C~ Copy", null),
-			});
-
-			var fv = new FrameView ("Frame View") {
-				Y = 1,
-				Width = Dim.Fill (),
-				Height = Dim.Fill (1)
-			};
-			var win = new Window ();
-			win.Add (menu, sb, fv);
-			var top = Application.Top;
-			top.Add (win);
-			Application.Begin (top);
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
-
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-┌──────────────────┐
-│ File  Edit       │
-│┌┤Frame View├────┐│
-││                ││
-││                ││
-││                ││
-││                ││
-│└────────────────┘│
-│ ^Q Quit │ ^O Open│
-└──────────────────┘", output);
-
-			((FakeDriver)Application.Driver).SetBufferSize (40, 20);
-
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-┌──────────────────────────────────────┐
-│ File  Edit                           │
-│┌┤Frame View├────────────────────────┐│
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-││                                    ││
-│└────────────────────────────────────┘│
-│ ^Q Quit │ ^O Open │ ^C Copy          │
-└──────────────────────────────────────┘", output);
-
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
-
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-┌──────────────────┐
-│ File  Edit       │
-│┌┤Frame View├────┐│
-││                ││
-││                ││
-││                ││
-││                ││
-│└────────────────┘│
-│ ^Q Quit │ ^O Open│
-└──────────────────┘", output);
-		}
-
-		[Fact, AutoInitShutdown]
-		public void OnCanFocusChanged_Only_Must_ContentView_Forces_SetFocus_After_IsInitialized_Is_True ()
-		{
-			var win1 = new Window () { Id = "win1", Width = 10, Height = 1 };
-			var view1 = new View () { Id = "view1", Width = Dim.Fill (), Height = Dim.Fill (), CanFocus = true };
-			var win2 = new Window () { Id = "win2", Y = 6, Width = 10, Height = 1 };
-			var view2 = new View () { Id = "view2", Width = Dim.Fill (), Height = Dim.Fill (), CanFocus = true };
-			win2.Add (view2);
-			win1.Add (view1, win2);
-
-			Application.Begin (win1);
-
-			Assert.True (win1.HasFocus);
-			Assert.True (view1.HasFocus);
-			Assert.False (win2.HasFocus);
-			Assert.False (view2.HasFocus);
-		}
-
-		[Fact, AutoInitShutdown]
-		public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
-		{
-			var menu = new MenuBar (new MenuBarItem [] {
-				new MenuBarItem ("Child", new MenuItem [] {
-					new MenuItem ("_Create Child", "", null)
-				})
-			});
-			var win = new Window ();
-			win.Add (menu);
-			Application.Top.Add (win);
-			Application.Begin (Application.Top);
-
-			var exception = Record.Exception (() => win.NewKeyDownEvent (new (KeyCode.AltMask)));
-			Assert.Null (exception);
-		}
-	}
-}

+ 9 - 1
pull_request_template.md

@@ -1,4 +1,12 @@
-Fixes #_____ - Include a terse summary of the change or which issue is fixed.
+## Fixes:
+
+(Include a list of issues that this PR fixes. If this PR is a work in progress, include a list of issues that this PR is related to. Use the format `Fixes #issue` to automatically close the issue when this PR is merged.)
+
+- Fixes #____ 
+
+## Todos:
+
+- [ ] - Include a list of tasks that need to be completed for this PR to be considered complete.
 
 ## Pull Request checklist: