Browse Source

Fixes #3072, #3148. `Dialog` and `MessageBox` key binding do not handle Enter correctly (#3151)

* Moved Command.Accept/Enter key binding from Toplevel to Dialog and added unit tests

* Dialog binds Esc to Command.QuitTopLevel

* Better Dialog key binding tests

* Better MessageBox key binding tests

* List of changes:
1. Removed explicit type casting for `Application.QuitKey` in `KeyBindings.Add` method calls. This indicates that `Application.QuitKey` is already of type `KeyCode`.
2. Removed explicit type casting for `Application.AlternateForwardKey` in `KeyBindings.Add` method calls. This suggests that `Application.AlternateForwardKey` is already of type `KeyCode`.
3. Removed explicit type casting for `Application.AlternateBackwardKey` in `KeyBindings.Add` method calls. This implies that `Application.AlternateBackwardKey` is already of type `KeyCode`.

References to the code changes:
1. `KeyBindings.Add((KeyCode)Application.QuitKey, QuitApplication);` changed to `KeyBindings.Add(Application.QuitKey, QuitApplication);`
2. `KeyBindings.Add((KeyCode)Application.AlternateForwardKey, MoveForward);` changed to `KeyBindings.Add(Application.AlternateForwardKey, MoveForward);`
3. `KeyBindings.Add((KeyCode)Application.AlternateBackwardKey, MoveBackward);` changed to `KeyBindings.Add(Application.AlternateBackwardKey, MoveBackward);`

* The `Command.Accept` command now directly calls the `OnClicked` method and returns `true`, effectively incorporating the behavior of the now-removed `AcceptKey` method.

* Moved Command.Accept/Enter key binding from Toplevel to Window and added unit tests
Tig 1 year ago
parent
commit
707dbda71b

+ 3 - 11
Terminal.Gui/Views/Button.cs

@@ -120,12 +120,12 @@ public class Button : View {
 
 
 		OnResizeNeeded ();
 		OnResizeNeeded ();
 
 
-		// Override default behavior of View
-		// Command.Default sets focus
+		// Override default behavior of View - Command.Default sets focus
 		AddCommand (Command.Accept, () => { OnClicked (); return true; });
 		AddCommand (Command.Accept, () => { OnClicked (); return true; });
 		KeyBindings.Add (Key.Space, Command.Default, Command.Accept);
 		KeyBindings.Add (Key.Space, Command.Default, Command.Accept);
+		KeyBindings.Add (Key.Enter, Command.Default, Command.Accept);
 	}
 	}
-
+	
 	/// <summary>
 	/// <summary>
 	/// Gets or sets whether the <see cref="Button"/> is the default action to activate in a dialog.
 	/// Gets or sets whether the <see cref="Button"/> is the default action to activate in a dialog.
 	/// </summary>
 	/// </summary>
@@ -166,14 +166,6 @@ public class Button : View {
 		}
 		}
 	}
 	}
 
 
-	bool AcceptKey ()
-	{
-		//if (!HasFocus) {
-		//	SetFocus ();
-		//}
-		OnClicked ();
-		return true;
-	}
 
 
 	/// <summary>
 	/// <summary>
 	/// Virtual method to invoke the <see cref="Clicked"/> event.
 	/// Virtual method to invoke the <see cref="Clicked"/> event.

+ 3 - 12
Terminal.Gui/Views/Dialog.cs

@@ -70,6 +70,8 @@ public class Dialog : Window {
 		Modal = true;
 		Modal = true;
 		ButtonAlignment = DefaultButtonAlignment;
 		ButtonAlignment = DefaultButtonAlignment;
 
 
+		KeyBindings.Add (Key.Esc, Command.QuitToplevel);
+
 		if (buttons != null) {
 		if (buttons != null) {
 			foreach (var b in buttons) {
 			foreach (var b in buttons) {
 				AddButton (b);
 				AddButton (b);
@@ -104,6 +106,7 @@ public class Dialog : Window {
 		//button.AutoSize = false; // BUGBUG: v2 - Hack to get around autosize not accounting for Margin?
 		//button.AutoSize = false; // BUGBUG: v2 - Hack to get around autosize not accounting for Margin?
 		buttons.Add (button);
 		buttons.Add (button);
 		Add (button);
 		Add (button);
+
 		SetNeedsDisplay ();
 		SetNeedsDisplay ();
 		if (IsInitialized) {
 		if (IsInitialized) {
 			LayoutSubviews ();
 			LayoutSubviews ();
@@ -228,16 +231,4 @@ public class Dialog : Window {
 			break;
 			break;
 		}
 		}
 	}
 	}
-
-	// BUGBUG: Why is this not handled by a key binding???
-	///<inheritdoc/>
-	public override bool OnProcessKeyDown (Key a)
-	{
-		switch (a.KeyCode) {
-		case KeyCode.Esc:
-			Application.RequestStop (this);
-			return true;
-		}
-		return false;
-	}
 }
 }

+ 21 - 31
Terminal.Gui/Views/Toplevel.cs

@@ -223,42 +223,32 @@ public partial class Toplevel : View {
 			Application.Refresh ();
 			Application.Refresh ();
 			return true;
 			return true;
 		});
 		});
-		AddCommand (Command.Accept, () => {
-			// TODO: Perhaps all views should support the concept of being default?
-			// TODO: It's bad that Toplevel is tightly coupled with Button
-			if (Subviews.FirstOrDefault (v => v is Button && ((Button)v).IsDefault && ((Button)v).Enabled) is Button defaultBtn) {
-				defaultBtn.InvokeCommand (Command.Accept);
-				return true;
-			}
-			return false;
-		});
+
 
 
 		// Default keybindings for this view
 		// Default keybindings for this view
-		KeyBindings.Add ((KeyCode)Application.QuitKey, Command.QuitToplevel);
+		KeyBindings.Add (Application.QuitKey, Command.QuitToplevel);
 
 
-		KeyBindings.Add (KeyCode.CursorRight, Command.NextView);
-		KeyBindings.Add (KeyCode.CursorDown, Command.NextView);
-		KeyBindings.Add (KeyCode.CursorLeft, Command.PreviousView);
-		KeyBindings.Add (KeyCode.CursorUp, Command.PreviousView);
+		KeyBindings.Add (Key.CursorRight, Command.NextView);
+		KeyBindings.Add (Key.CursorDown, Command.NextView);
+		KeyBindings.Add (Key.CursorLeft, Command.PreviousView);
+		KeyBindings.Add (Key.CursorUp, Command.PreviousView);
 
 
-		KeyBindings.Add (KeyCode.Tab, Command.NextView);
-		KeyBindings.Add (KeyCode.Tab | KeyCode.ShiftMask, Command.PreviousView);
-		KeyBindings.Add (KeyCode.Tab | KeyCode.CtrlMask, Command.NextViewOrTop);
-		KeyBindings.Add (KeyCode.Tab | KeyCode.ShiftMask | KeyCode.CtrlMask, Command.PreviousViewOrTop);
+		KeyBindings.Add (Key.Tab, Command.NextView);
+		KeyBindings.Add (Key.Tab.WithShift, Command.PreviousView);
+		KeyBindings.Add (Key.Tab.WithCtrl, Command.NextViewOrTop);
+		KeyBindings.Add (Key.Tab.WithShift.WithCtrl, Command.PreviousViewOrTop);
 
 
-		KeyBindings.Add (KeyCode.F5, Command.Refresh);
-		KeyBindings.Add ((KeyCode)Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
-		KeyBindings.Add ((KeyCode)Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
+		KeyBindings.Add (Key.F5, Command.Refresh);
+		KeyBindings.Add (Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
+		KeyBindings.Add (Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
 
 
 #if UNIX_KEY_BINDINGS
 #if UNIX_KEY_BINDINGS
-			KeyBindings.Add (Key.Z | Key.CtrlMask, Command.Suspend);
-			KeyBindings.Add (Key.L | Key.CtrlMask, Command.Refresh);// Unix
-			KeyBindings.Add (Key.F | Key.CtrlMask, Command.NextView);// Unix
-			KeyBindings.Add (Key.I | Key.CtrlMask, Command.NextView); // Unix
-			KeyBindings.Add (Key.B | Key.CtrlMask, Command.PreviousView);// Unix
+			KeyBindings.Add (Key.Z.WithCtrl, Command.Suspend);
+			KeyBindings.Add (Key.L.WithCtrl, Command.Refresh);// Unix
+			KeyBindings.Add (Key.F.WithCtrl, Command.NextView);// Unix
+			KeyBindings.Add (Key.I.WithCtrl, Command.NextView); // Unix
+			KeyBindings.Add (Key.B.WithCtrl, Command.PreviousView);// Unix
 #endif
 #endif
-		// This enables the default button to be activated by the Enter key.
-		KeyBindings.Add (KeyCode.Enter, Command.Accept);
 	}
 	}
 
 
 	void Application_UnGrabbingMouse (object sender, GrabMouseEventArgs e)
 	void Application_UnGrabbingMouse (object sender, GrabMouseEventArgs e)
@@ -286,7 +276,7 @@ public partial class Toplevel : View {
 	/// <param name="e"></param>
 	/// <param name="e"></param>
 	public virtual void OnAlternateForwardKeyChanged (KeyChangedEventArgs e)
 	public virtual void OnAlternateForwardKeyChanged (KeyChangedEventArgs e)
 	{
 	{
-		KeyBindings.Replace ((KeyCode)e.OldKey, (KeyCode)e.NewKey);
+		KeyBindings.Replace (e.OldKey, e.NewKey);
 		AlternateForwardKeyChanged?.Invoke (this, e);
 		AlternateForwardKeyChanged?.Invoke (this, e);
 	}
 	}
 
 
@@ -301,7 +291,7 @@ public partial class Toplevel : View {
 	/// <param name="e"></param>
 	/// <param name="e"></param>
 	public virtual void OnAlternateBackwardKeyChanged (KeyChangedEventArgs e)
 	public virtual void OnAlternateBackwardKeyChanged (KeyChangedEventArgs e)
 	{
 	{
-		KeyBindings.Replace ((KeyCode)e.OldKey, (KeyCode)e.NewKey);
+		KeyBindings.Replace (e.OldKey, e.NewKey);
 		AlternateBackwardKeyChanged?.Invoke (this, e);
 		AlternateBackwardKeyChanged?.Invoke (this, e);
 	}
 	}
 
 
@@ -316,7 +306,7 @@ public partial class Toplevel : View {
 	/// <param name="e"></param>
 	/// <param name="e"></param>
 	public virtual void OnQuitKeyChanged (KeyChangedEventArgs e)
 	public virtual void OnQuitKeyChanged (KeyChangedEventArgs e)
 	{
 	{
-		KeyBindings.Replace ((KeyCode)e.OldKey, (KeyCode)e.NewKey);
+		KeyBindings.Replace (e.OldKey, e.NewKey);
 		QuitKeyChanged?.Invoke (this, e);
 		QuitKeyChanged?.Invoke (this, e);
 	}
 	}
 
 

+ 60 - 52
Terminal.Gui/Views/Window.cs

@@ -1,60 +1,68 @@
-using System;
-using System.Collections;
+using System.Linq;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
-using System.Text;
-using Terminal.Gui;
-using static Terminal.Gui.ConfigurationManager;
 
 
-namespace Terminal.Gui {
+namespace Terminal.Gui;
 
 
+/// <summary>
+/// A <see cref="Toplevel"/> <see cref="View"/> with <see cref="View.BorderStyle"/> set to
+/// <see cref="LineStyle.Single"/>. Provides a container for other views. 
+/// </summary>
+/// <remarks>
+/// <para>
+/// If any subview is a button and the <see cref="Button.IsDefault"/> property is set to true, the Enter key
+/// will invoke the <see cref="Command.Accept"/> command on that subview.
+/// </para>
+/// </remarks>
+public class Window : Toplevel {
 	/// <summary>
 	/// <summary>
-	/// A <see cref="Toplevel"/> <see cref="View"/> with <see cref="View.BorderStyle"/> set to <see cref="LineStyle.Single"/>. 
+	/// Initializes a new instance of the <see cref="Window"/> class using
+	/// <see cref="LayoutStyle.Computed"/> positioning.
+	/// </summary>
+	public Window () => SetInitialProperties ();
+
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Window"/> class using
+	/// <see cref="LayoutStyle.Computed"/> positioning.
+	/// </summary>
+	public Window (Rect frame) : base (frame) => SetInitialProperties ();
+
+	// TODO: enable this
+	///// <summary>
+	///// The default <see cref="LineStyle"/> for <see cref="Window"/>'s border. The default is <see cref="LineStyle.Single"/>.
+	///// </summary>
+	///// <remarks>
+	///// This property can be set in a Theme to change the default <see cref="LineStyle"/> for all <see cref="Window"/>s. 
+	///// </remarks>
+	/////[SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))]
+	////public static ColorScheme DefaultColorScheme { get; set; } = Colors.Base;
+
+	/// <summary>
+	/// The default <see cref="LineStyle"/> for <see cref="Window"/>'s border. The default is
+	/// <see cref="LineStyle.Single"/>.
 	/// </summary>
 	/// </summary>
 	/// <remarks>
 	/// <remarks>
-	/// <para>
-	/// This is a helper class to simplify creating a <see cref="Toplevel"/> with a border.
-	/// </para>
+	/// This property can be set in a Theme to change the default <see cref="LineStyle"/> for all
+	/// <see cref="Window"/>s.
 	/// </remarks>
 	/// </remarks>
-	public class Window : Toplevel {
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> class using <see cref="LayoutStyle.Computed"/> positioning.
-		/// </summary>
-		public Window () : base () {
-			SetInitialProperties ();
-		}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> class using <see cref="LayoutStyle.Computed"/> positioning.
-		/// </summary>
-		public Window (Rect frame) : base (frame)
-		{
-			SetInitialProperties ();
-		}
-
-		// TODO: enable this
-		///// <summary>
-		///// The default <see cref="LineStyle"/> for <see cref="Window"/>'s border. The default is <see cref="LineStyle.Single"/>.
-		///// </summary>
-		///// <remarks>
-		///// This property can be set in a Theme to change the default <see cref="LineStyle"/> for all <see cref="Window"/>s. 
-		///// </remarks>
-		/////[SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))]
-		////public static ColorScheme DefaultColorScheme { get; set; } = Colors.Base;
-
-		/// <summary>
-		/// The default <see cref="LineStyle"/> for <see cref="Window"/>'s border. The default is <see cref="LineStyle.Single"/>.
-		/// </summary>
-		/// <remarks>
-		/// This property can be set in a Theme to change the default <see cref="LineStyle"/> for all <see cref="Window"/>s. 
-		/// </remarks>
-		[SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))]
-		public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
-
-		void SetInitialProperties ()
-		{
-			CanFocus = true;
-			ColorScheme = Colors.Base; // TODO: make this a theme property
-			BorderStyle = DefaultBorderStyle;
-		}
+	[SerializableConfigurationProperty (Scope = typeof (ThemeScope))] [JsonConverter (typeof (JsonStringEnumConverter))]
+	public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
+
+	void SetInitialProperties ()
+	{
+		CanFocus = true;
+		ColorScheme = Colors.Base; // TODO: make this a theme property
+		BorderStyle = DefaultBorderStyle;
+
+		// This enables the default button to be activated by the Enter key.
+		AddCommand (Command.Accept, () => {
+			// TODO: Perhaps all views should support the concept of being default?
+			if (Subviews.FirstOrDefault (v => v is Button { IsDefault: true, Enabled: true }) is Button defaultBtn) {
+				defaultBtn.InvokeCommand (Command.Accept);
+				return true;
+			}
+			return false;
+		});
+
+		KeyBindings.Add (Key.Enter, Command.Accept);
 	}
 	}
-}
+}

File diff suppressed because it is too large
+ 738 - 747
UnitTests/Dialogs/DialogTests.cs


+ 508 - 403
UnitTests/Dialogs/MessageBoxTests.cs

@@ -1,235 +1,231 @@
-using System.Threading.Tasks;
+using System.Text;
 using Xunit;
 using Xunit;
 using Xunit.Abstractions;
 using Xunit.Abstractions;
-using System.Text;
-using Terminal.Gui;
-using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
 
 
-namespace Terminal.Gui.DialogTests {
+namespace Terminal.Gui.DialogTests;
 
 
-	public class MessageBoxTests {
-		readonly ITestOutputHelper output;
+public class MessageBoxTests {
+	readonly ITestOutputHelper _output;
 
 
-		public MessageBoxTests (ITestOutputHelper output)
-		{
-			this.output = output;
-		}
+	public MessageBoxTests (ITestOutputHelper output) => _output = output;
 
 
-		[Fact]
-		[AutoInitShutdown]
-		public void Size_Default ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+	[Fact]
+	[AutoInitShutdown]
+	public void Size_Default ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		((FakeDriver)Application.Driver).SetBufferSize (100, 100);
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					MessageBox.Query (string.Empty, string.Empty, null);
+			if (iterations == 0) {
+				MessageBox.Query (string.Empty, string.Empty, null);
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
 
 
-					Assert.IsType<Dialog> (Application.Current);
-					// Default size is Percent(60) 
-					Assert.Equal (new Size ((int)(100 * .60), 5), Application.Current.Frame.Size);
+				Assert.IsType<Dialog> (Application.Current);
+				// Default size is Percent(60) 
+				Assert.Equal (new Size ((int)(100 * .60), 5), Application.Current.Frame.Size);
 
 
-					Application.RequestStop ();
-				}
-			};
-
-			Application.Run ();
-		}
-
-		[Fact]
-		[AutoInitShutdown]
-		public void Location_Default ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			((FakeDriver)Application.Driver).SetBufferSize (100, 100);
-
-			Application.Iteration += (s, a) => {
-				iterations++;
+				Application.RequestStop ();
+			}
+		};
 
 
-				if (iterations == 0) {
-					MessageBox.Query (string.Empty, string.Empty, null);
+		Application.Run ();
+	}
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
+	[Fact]
+	[AutoInitShutdown]
+	public void Location_Default ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		((FakeDriver)Application.Driver).SetBufferSize (100, 100);
 
 
-					Assert.IsType<Dialog> (Application.Current);
-					// Default location is centered, so
-					// X = (100 / 2) - (60 / 2) = 20
-					// Y = (100 / 2) - (5 / 2) = 47
-					Assert.Equal (new Point (20, 47), Application.Current.Frame.Location);
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-					Application.RequestStop ();
-				}
-			};
+			if (iterations == 0) {
+				MessageBox.Query (string.Empty, string.Empty, null);
 
 
-			Application.Run ();
-		}
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
 
 
-		[Theory]
-		[InlineData (0, 0)]
-		[InlineData (1, 1)]
-		[InlineData (7, 5)]
-		[InlineData (50, 50)]
-		[AutoInitShutdown]
-		public void Size_Not_Default_No_Message (int height, int width)
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+				Assert.IsType<Dialog> (Application.Current);
+				// Default location is centered, so
+				// X = (100 / 2) - (60 / 2) = 20
+				// Y = (100 / 2) - (5 / 2) = 47
+				Assert.Equal (new Point (20, 47), Application.Current.Frame.Location);
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+				Application.RequestStop ();
+			}
+		};
 
 
-				if (iterations == 0) {
-					MessageBox.Query (height, width, string.Empty, string.Empty, null);
+		Application.Run ();
+	}
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
+	[Theory]
+	[InlineData (0, 0)]
+	[InlineData (1, 1)]
+	[InlineData (7, 5)]
+	[InlineData (50, 50)]
+	[AutoInitShutdown]
+	public void Size_Not_Default_No_Message (int height, int width)
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+
+		Application.Iteration += (s, a) => {
+			iterations++;
+
+			if (iterations == 0) {
+				MessageBox.Query (height, width, string.Empty, string.Empty, null);
+
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+
+				Assert.IsType<Dialog> (Application.Current);
+				Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
+
+				Application.RequestStop ();
+			}
+		};
+	}
 
 
-					Assert.IsType<Dialog> (Application.Current);
-					Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
+	[Theory]
+	[InlineData (0, 0, "1")]
+	[InlineData (1, 1, "1")]
+	[InlineData (7, 5, "1")]
+	[InlineData (50, 50, "1")]
+	[InlineData (0, 0, "message")]
+	[InlineData (1, 1, "message")]
+	[InlineData (7, 5, "message")]
+	[InlineData (50, 50, "message")]
+	[AutoInitShutdown]
+	public void Size_Not_Default_Message (int height, int width, string message)
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+
+		Application.Iteration += (s, a) => {
+			iterations++;
+
+			if (iterations == 0) {
+				MessageBox.Query (height, width, string.Empty, message, null);
+
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+
+				Assert.IsType<Dialog> (Application.Current);
+				Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
+
+				Application.RequestStop ();
+			}
+		};
+	}
 
 
-					Application.RequestStop ();
-				}
-			};
-		}
-
-		[Theory]
-		[InlineData (0, 0, "1")]
-		[InlineData (1, 1, "1")]
-		[InlineData (7, 5, "1")]
-		[InlineData (50, 50, "1")]
-		[InlineData (0, 0, "message")]
-		[InlineData (1, 1, "message")]
-		[InlineData (7, 5, "message")]
-		[InlineData (50, 50, "message")]
-		[AutoInitShutdown]
-		public void Size_Not_Default_Message (int height, int width, string message)
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			((FakeDriver)Application.Driver).SetBufferSize (100, 100);
-
-			Application.Iteration += (s, a) => {
-				iterations++;
-
-				if (iterations == 0) {
-					MessageBox.Query (height, width, string.Empty, message, null);
-
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-
-					Assert.IsType<Dialog> (Application.Current);
-					Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
-
-					Application.RequestStop ();
-				}
-			};
-		}
-
-		[Theory]
-		[InlineData (0, 0, "1")]
-		[InlineData (1, 1, "1")]
-		[InlineData (7, 5, "1")]
-		[InlineData (50, 50, "1")]
-		[InlineData (0, 0, "message")]
-		[InlineData (1, 1, "message")]
-		[InlineData (7, 5, "message")]
-		[InlineData (50, 50, "message")]
-		[AutoInitShutdown]
-		public void Size_Not_Default_Message_Button (int height, int width, string message)
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			((FakeDriver)Application.Driver).SetBufferSize (100, 100);
-
-			Application.Iteration += (s, a) => {
-				iterations++;
-
-				if (iterations == 0) {
-					MessageBox.Query (height, width, string.Empty, message, "_Ok");
-
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-
-					Assert.IsType<Dialog> (Application.Current);
-					Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
-
-					Application.RequestStop ();
-				}
-			};
-		}
+	[Theory]
+	[InlineData (0, 0, "1")]
+	[InlineData (1, 1, "1")]
+	[InlineData (7, 5, "1")]
+	[InlineData (50, 50, "1")]
+	[InlineData (0, 0, "message")]
+	[InlineData (1, 1, "message")]
+	[InlineData (7, 5, "message")]
+	[InlineData (50, 50, "message")]
+	[AutoInitShutdown]
+	public void Size_Not_Default_Message_Button (int height, int width, string message)
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		((FakeDriver)Application.Driver).SetBufferSize (100, 100);
+
+		Application.Iteration += (s, a) => {
+			iterations++;
+
+			if (iterations == 0) {
+				MessageBox.Query (height, width, string.Empty, message, "_Ok");
+
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+
+				Assert.IsType<Dialog> (Application.Current);
+				Assert.Equal (new Size (height, width), Application.Current.Frame.Size);
+
+				Application.RequestStop ();
+			}
+		};
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Size_None_No_Buttons ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
+	[Fact]
+	[AutoInitShutdown]
+	public void Size_None_No_Buttons ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					MessageBox.Query ("Title", "Message");
+			if (iterations == 0) {
+				MessageBox.Query ("Title", "Message");
 
 
-					Application.RequestStop ();
+				Application.RequestStop ();
 
 
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@"
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
                 ┌┤Title├───────────────────────────────────────┐
                 ┌┤Title├───────────────────────────────────────┐
                 │                   Message                    │
                 │                   Message                    │
                 │                                              │
                 │                                              │
                 │                                              │
                 │                                              │
                 └──────────────────────────────────────────────┘
                 └──────────────────────────────────────────────┘
-", output);
+", _output);
 
 
-					Application.RequestStop ();
-				}
-			};
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Size_No_With_Button ()
-		{
-			Application.Top.BorderStyle = LineStyle.Double;
-			var iterations = -1;
-			Application.Begin (Application.Top);
+	[Fact]
+	[AutoInitShutdown]
+	public void Size_No_With_Button ()
+	{
+		Application.Top.BorderStyle = LineStyle.Double;
+		var iterations = -1;
+		Application.Begin (Application.Top);
 
 
-			var aboutMessage = new StringBuilder ();
-			aboutMessage.AppendLine (@"0123456789012345678901234567890123456789");
-			aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui");
-			var message = aboutMessage.ToString ();
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+		var aboutMessage = new StringBuilder ();
+		aboutMessage.AppendLine (@"0123456789012345678901234567890123456789");
+		aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui");
+		var message = aboutMessage.ToString ();
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
 
 
-			((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8);
+		((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8);
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
+			if (iterations == 0) {
 
 
-					MessageBox.Query (string.Empty, message, "_Ok");
+				MessageBox.Query (string.Empty, message, "_Ok");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ╔══════════════════════════════════════════╗
 ╔══════════════════════════════════════════╗
 ║┌────────────────────────────────────────┐║
 ║┌────────────────────────────────────────┐║
 ║│0123456789012345678901234567890123456789│║
 ║│0123456789012345678901234567890123456789│║
@@ -238,100 +234,103 @@ namespace Terminal.Gui.DialogTests {
 ║│                {btn}                │║
 ║│                {btn}                │║
 ║└────────────────────────────────────────┘║
 ║└────────────────────────────────────────┘║
 ╚══════════════════════════════════════════╝
 ╚══════════════════════════════════════════╝
-", output);
+", _output);
 
 
-					Application.RequestStop ();
-				}
-			};
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Size_Tiny_Fixed_Size ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
+	[Fact]
+	[AutoInitShutdown]
+	public void Size_Tiny_Fixed_Size ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					MessageBox.Query (7, 5, string.Empty, "Message", "_Ok");
+			if (iterations == 0) {
+				MessageBox.Query (7, 5, string.Empty, "Message", "_Ok");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
 
 
-					Assert.Equal (new Size (7, 5), Application.Current.Frame.Size);
+				Assert.Equal (new Size (7, 5), Application.Current.Frame.Size);
 
 
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
                                     ┌─────┐
                                     ┌─────┐
                                     │Messa│
                                     │Messa│
                                     │ ge  │
                                     │ ge  │
                                     │ Ok {CM.Glyphs.RightDefaultIndicator}│
                                     │ Ok {CM.Glyphs.RightDefaultIndicator}│
                                     └─────┘
                                     └─────┘
-", output);
+", _output);
 
 
-					Application.RequestStop ();
-				}
-			};
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Size_JustBigEnough_Fixed_Size ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+	[Fact]
+	[AutoInitShutdown]
+	public void Size_JustBigEnough_Fixed_Size ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					MessageBox.Query (11, 5, string.Empty, "Message", "_Ok");
+			if (iterations == 0) {
+				MessageBox.Query (11, 5, string.Empty, "Message", "_Ok");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
                                   ┌─────────┐
                                   ┌─────────┐
                                   │ Message │
                                   │ Message │
                                   │         │
                                   │         │
                                   │{btn} │
                                   │{btn} │
                                   └─────────┘
                                   └─────────┘
-", output);
+", _output);
 
 
-					Application.RequestStop ();
-				}
-			};
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Message_Long_Without_Spaces_WrapMessage_True ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			Application.Top.BorderStyle = LineStyle.Double;
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+	[Fact]
+	[AutoInitShutdown]
+	public void Message_Long_Without_Spaces_WrapMessage_True ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		Application.Top.BorderStyle = LineStyle.Double;
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
 
 
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
-			Application.Iteration += (s, a) => {
-				iterations++;
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					// 50 characters should make the height of the wrapped text 7
-					MessageBox.Query (string.Empty, new string ('f', 50), defaultButton: 0, wrapMessage: true, "btn");
+			if (iterations == 0) {
+				// 50 characters should make the height of the wrapped text 7
+				MessageBox.Query (string.Empty, new string ('f', 50), 0, true, "btn");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
 
 
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ╔══════════════════╗
 ╔══════════════════╗
 ║┌────────────────┐║
 ║┌────────────────┐║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
@@ -341,15 +340,15 @@ namespace Terminal.Gui.DialogTests {
 ║│                │║
 ║│                │║
 ║│    {btn}   │║
 ║│    {btn}   │║
 ║└────────────────┘║
 ║└────────────────┘║
-╚══════════════════╝", output);
-					Assert.Equal (new Size (20 - 2, 10 - 2), Application.Current.Frame.Size);
-					Application.RequestStop ();
-
-					// Really long text
-					MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: true, "btn");
-				} else if (iterations == 2) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+╚══════════════════╝", _output);
+				Assert.Equal (new Size (20 - 2, 10 - 2), Application.Current.Frame.Size);
+				Application.RequestStop ();
+
+				// Really long text
+				MessageBox.Query (string.Empty, new string ('f', 500), 0, true, "btn");
+			} else if (iterations == 2) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ╔┌────────────────┐╗
 ╔┌────────────────┐╗
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
@@ -359,38 +358,40 @@ namespace Terminal.Gui.DialogTests {
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│    {btn}   │║
 ║│    {btn}   │║
-╚└────────────────┘╝", output);
-					Application.RequestStop ();
-				}
-			};
+╚└────────────────┘╝", _output);
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Message_With_Spaces_WrapMessage_True ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			Application.Top.BorderStyle = LineStyle.Double;
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+	[Fact]
+	[AutoInitShutdown]
+	public void Message_With_Spaces_WrapMessage_True ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		Application.Top.BorderStyle = LineStyle.Double;
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
 
 
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					var sb = new StringBuilder ();
-					for (int i = 0; i < 17; i++)
-						sb.Append ("ff ");
+			if (iterations == 0) {
+				var sb = new StringBuilder ();
+				for (var i = 0; i < 17; i++) {
+					sb.Append ("ff ");
+				}
 
 
-					MessageBox.Query (string.Empty, sb.ToString (), defaultButton: 0, wrapMessage: true, "btn");
+				MessageBox.Query (string.Empty, sb.ToString (), 0, true, "btn");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ╔══════════════════╗
 ╔══════════════════╗
 ║ ┌──────────────┐ ║
 ║ ┌──────────────┐ ║
 ║ │ff ff ff ff ff│ ║
 ║ │ff ff ff ff ff│ ║
@@ -400,14 +401,14 @@ namespace Terminal.Gui.DialogTests {
 ║ │              │ ║
 ║ │              │ ║
 ║ │   {btn}  │ ║
 ║ │   {btn}  │ ║
 ║ └──────────────┘ ║
 ║ └──────────────┘ ║
-╚══════════════════╝", output);
-					Application.RequestStop ();
-
-					// Really long text
-					MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: true, "btn");
-				} else if (iterations == 2) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+╚══════════════════╝", _output);
+				Application.RequestStop ();
+
+				// Really long text
+				MessageBox.Query (string.Empty, new string ('f', 500), 0, true, "btn");
+			} else if (iterations == 2) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ╔┌────────────────┐╗
 ╔┌────────────────┐╗
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
@@ -417,34 +418,35 @@ namespace Terminal.Gui.DialogTests {
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│ffffffffffffffff│║
 ║│    {btn}   │║
 ║│    {btn}   │║
-╚└────────────────┘╝", output);
-					Application.RequestStop ();
-				}
-			};
+╚└────────────────┘╝", _output);
+				Application.RequestStop ();
+			}
+		};
 
 
-			Application.Run ();
-		}
+		Application.Run ();
+	}
 
 
-		[Fact, AutoInitShutdown]
-		public void Message_Without_Spaces_WrapMessage_False ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			Application.Top.BorderStyle = LineStyle.Double;
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+	[Fact]
+	[AutoInitShutdown]
+	public void Message_Without_Spaces_WrapMessage_False ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		Application.Top.BorderStyle = LineStyle.Double;
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
 
 
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
 
 
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Iteration += (s, a) => {
+			iterations++;
 
 
-				if (iterations == 0) {
-					MessageBox.Query (string.Empty, new string ('f', 50), defaultButton: 0, wrapMessage: false, "btn");
+			if (iterations == 0) {
+				MessageBox.Query (string.Empty, new string ('f', 50), 0, false, "btn");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ╔══════════════════╗
 ╔══════════════════╗
 ║                  ║
 ║                  ║
 ────────────────────
 ────────────────────
@@ -454,15 +456,15 @@ ffffffffffffffffffff
 ────────────────────
 ────────────────────
 ║                  ║
 ║                  ║
 ║                  ║
 ║                  ║
-╚══════════════════╝", output);
+╚══════════════════╝", _output);
 
 
-					Application.RequestStop ();
+				Application.RequestStop ();
 
 
-					// Really long text
-					MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: false, "btn");
-				} else if (iterations == 2) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				// Really long text
+				MessageBox.Query (string.Empty, new string ('f', 500), 0, false, "btn");
+			} else if (iterations == 2) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ╔══════════════════╗
 ╔══════════════════╗
 ║                  ║
 ║                  ║
 ────────────────────
 ────────────────────
@@ -472,38 +474,40 @@ ffffffffffffffffffff
 ────────────────────
 ────────────────────
 ║                  ║
 ║                  ║
 ║                  ║
 ║                  ║
-╚══════════════════╝", output);
+╚══════════════════╝", _output);
 
 
-					Application.RequestStop ();
-				}
-			};
-
-			Application.Run ();
-		}
+				Application.RequestStop ();
+			}
+		};
 
 
-		[Fact, AutoInitShutdown]
-		public void Message_With_Spaces_WrapMessage_False ()
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-			Application.Top.BorderStyle = LineStyle.Double;
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
-			var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
-
-			Application.Iteration += (s, a) => {
-				iterations++;
+		Application.Run ();
+	}
 
 
-				if (iterations == 0) {
-					var sb = new StringBuilder ();
-					for (int i = 0; i < 17; i++)
-						sb.Append ("ff ");
+	[Fact]
+	[AutoInitShutdown]
+	public void Message_With_Spaces_WrapMessage_False ()
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+		Application.Top.BorderStyle = LineStyle.Double;
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+		var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+
+		Application.Iteration += (s, a) => {
+			iterations++;
+
+			if (iterations == 0) {
+				var sb = new StringBuilder ();
+				for (var i = 0; i < 17; i++) {
+					sb.Append ("ff ");
+				}
 
 
-					MessageBox.Query (string.Empty, sb.ToString (), defaultButton: 0, wrapMessage: false, "btn");
+				MessageBox.Query (string.Empty, sb.ToString (), 0, false, "btn");
 
 
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ╔══════════════════╗
 ╔══════════════════╗
 ║                  ║
 ║                  ║
 ────────────────────
 ────────────────────
@@ -513,14 +517,14 @@ ff ff ff ff ff ff ff
 ────────────────────
 ────────────────────
 ║                  ║
 ║                  ║
 ║                  ║
 ║                  ║
-╚══════════════════╝", output);
-					Application.RequestStop ();
-
-					// Really long text
-					MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: false, "btn");
-				} else if (iterations == 2) {
-					Application.Refresh ();
-					TestHelpers.AssertDriverContentsWithFrameAre (@$"
+╚══════════════════╝", _output);
+				Application.RequestStop ();
+
+				// Really long text
+				MessageBox.Query (string.Empty, new string ('f', 500), 0, false, "btn");
+			} else if (iterations == 2) {
+				Application.Refresh ();
+				TestHelpers.AssertDriverContentsWithFrameAre (@"
 ╔══════════════════╗
 ╔══════════════════╗
 ║                  ║
 ║                  ║
 ────────────────────
 ────────────────────
@@ -530,58 +534,159 @@ ffffffffffffffffffff
 ────────────────────
 ────────────────────
 ║                  ║
 ║                  ║
 ║                  ║
 ║                  ║
-╚══════════════════╝", output);
-					Application.RequestStop ();
-				}
-			};
-
-			Application.Run ();
-		}
-
-		[Theory, AutoInitShutdown]
-		[InlineData (" ", true, 1)]
-		[InlineData (" ", false, 1)]
-		[InlineData ("", true, 1)]
-		[InlineData ("", false, 1)]
-		[InlineData ("\n", true, 1)]
-		[InlineData ("\n", false, 1)]
-		[InlineData (" \n", true, 1)]
-		[InlineData (" \n", false, 2)]
-		public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage, int linesLength)
-		{
-			var iterations = -1;
-			Application.Begin (Application.Top);
-
-			Application.Iteration += (s, a) => {
-				iterations++;
-
-				if (iterations == 0) {
-					MessageBox.Query (string.Empty, message, 0, wrapMessage, "ok");
-
-					Application.RequestStop ();
-				} else if (iterations == 1) {
-					Application.Refresh ();
-					if (linesLength == 1) {
-						TestHelpers.AssertDriverContentsWithFrameAre (@$"
+╚══════════════════╝", _output);
+				Application.RequestStop ();
+			}
+		};
+
+		Application.Run ();
+	}
+
+	[Theory]
+	[AutoInitShutdown]
+	[InlineData (" ", true, 1)]
+	[InlineData (" ", false, 1)]
+	[InlineData ("", true, 1)]
+	[InlineData ("", false, 1)]
+	[InlineData ("\n", true, 1)]
+	[InlineData ("\n", false, 1)]
+	[InlineData (" \n", true, 1)]
+	[InlineData (" \n", false, 2)]
+	public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage, int linesLength)
+	{
+		var iterations = -1;
+		Application.Begin (Application.Top);
+
+		Application.Iteration += (s, a) => {
+			iterations++;
+
+			if (iterations == 0) {
+				MessageBox.Query (string.Empty, message, 0, wrapMessage, "ok");
+
+				Application.RequestStop ();
+			} else if (iterations == 1) {
+				Application.Refresh ();
+				if (linesLength == 1) {
+					TestHelpers.AssertDriverContentsWithFrameAre (@$"
                 ┌──────────────────────────────────────────────┐
                 ┌──────────────────────────────────────────────┐
                 │                                              │
                 │                                              │
                 │                                              │
                 │                                              │
                 │                   {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}                   │
                 │                   {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}                   │
-                └──────────────────────────────────────────────┘", output);
-					} else {
-						TestHelpers.AssertDriverContentsWithFrameAre (@$"
+                └──────────────────────────────────────────────┘", _output);
+				} else {
+					TestHelpers.AssertDriverContentsWithFrameAre (@$"
                 ┌──────────────────────────────────────────────┐
                 ┌──────────────────────────────────────────────┐
                 │                                              │
                 │                                              │
                 │                                              │
                 │                                              │
                 │                                              │
                 │                                              │
                 │                   {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}                   │
                 │                   {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}                   │
-                └──────────────────────────────────────────────┘", output);
-					}
-					Application.RequestStop ();
+                └──────────────────────────────────────────────┘", _output);
 				}
 				}
-			};
+				Application.RequestStop ();
+			}
+		};
+
+		Application.Run ();
+	}
+
+
+	[Fact]
+	[AutoInitShutdown]
+	public void KeyBindings_Esc_Closes ()
+	{
+		Application.Begin (Application.Top);
+
+		var result = 999;
+
+		var iteration = 0;
+		Application.Iteration += (s, a) => {
+			iteration++;
+			switch (iteration) {
+			case 1:
+				result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
+				Application.RequestStop ();
+				break;
+
+			case 2:
+				Application.OnKeyDown (Key.Esc);
+				break;
+
+			default:
+				Assert.Fail ();
+				break;
+
+			}
+		};
+		Application.Run ();
+
+		Assert.Equal (-1, result);
+	}
+
+	[Fact]
+	[AutoInitShutdown]
+	public void KeyBindings_Enter_Causes_Focused_Button_Click ()
+	{
+		Application.Begin (Application.Top);
+
+		var result = -1;
+
+		var iteration = 0;
+		Application.Iteration += (s, a) => {
+			iteration++;
+			switch (iteration) {
+			case 1:
+				result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
+				Application.RequestStop ();
+				break;
+
+			case 2:
+				// Tab to btn2
+				Application.OnKeyDown (Key.Tab);
+				Application.OnKeyDown (Key.Enter);
+				break;
+			
+			default:
+				Assert.Fail ();
+				break;
+
+			}
+		};
+		Application.Run ();
+
+		Assert.Equal (1, result);
+	}
 
 
-			Application.Run ();
-		}
+	[Fact]
+	[AutoInitShutdown]
+	public void KeyBindings_Space_Causes_Focused_Button_Click ()
+	{
+		Application.Begin (Application.Top);
+
+		var result = -1;
+
+		var iteration = 0;
+		Application.Iteration += (s, a) => {
+			iteration++;
+			switch (iteration) {
+			case 1:
+				result = MessageBox.Query (title: string.Empty, message: string.Empty, defaultButton: 0, wrapMessage: false, "btn0", "btn1");
+				Application.RequestStop ();
+				break;
+				
+			case 2:
+				// Tab to btn2
+				Application.OnKeyDown (Key.Tab);
+				Application.OnKeyDown (Key.Space);
+				break;
+
+			default:
+				Assert.Fail ();
+				break;
+
+			}
+		};
+		Application.Run ();
+
+		Assert.Equal (1, result);
 	}
 	}
-}
+}

+ 27 - 9
UnitTests/Views/ButtonTests.cs

@@ -78,39 +78,57 @@ namespace Terminal.Gui.ViewsTests {
 			Application.Top.Add (btn);
 			Application.Top.Add (btn);
 			Application.Begin (Application.Top);
 			Application.Begin (Application.Top);
 
 
+			// Hot key. Both alone and with alt
 			Assert.Equal (KeyCode.T, btn.HotKey);
 			Assert.Equal (KeyCode.T, btn.HotKey);
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.T)));
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.T)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
+
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.T | KeyCode.AltMask)));
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.T | KeyCode.AltMask)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
+
+			Assert.True (btn.NewKeyDownEvent (btn.HotKey));
+			Assert.True (clicked);
+			clicked = false;
+
+			// IsDefault = false
+			// Space and Enter should work
 			Assert.False (btn.IsDefault);
 			Assert.False (btn.IsDefault);
-			Assert.False (btn.NewKeyDownEvent (new (KeyCode.Enter)));
-			Assert.False (clicked);
-			btn.IsDefault = true;
-			Assert.False (btn.NewKeyDownEvent (new (KeyCode.Enter)));
-			Assert.True (Application.Top.NewKeyDownEvent (new (KeyCode.Enter)));
+			Assert.True (btn.NewKeyDownEvent (new (KeyCode.Enter)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
-			Assert.True (btn.NewKeyDownEvent (new (KeyCode.AltMask | KeyCode.T)));
+
+			// IsDefault = true
+			// Space and Enter should work
+			btn.IsDefault = true;
+			Assert.True (btn.NewKeyDownEvent (new (KeyCode.Enter)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
+
+			// Toplevel does not handle Enter, so it should get passed on to button
 			Assert.True (Application.Top.NewKeyDownEvent (new (KeyCode.Enter)));
 			Assert.True (Application.Top.NewKeyDownEvent (new (KeyCode.Enter)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
+
+			// Direct
+			Assert.True (btn.NewKeyDownEvent (new (KeyCode.Enter)));
+			Assert.True (clicked);
+			clicked = false;
+
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.Space)));
 			Assert.True (btn.NewKeyDownEvent (new (KeyCode.Space)));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
+
 			Assert.True (btn.NewKeyDownEvent (new ((KeyCode)'T')));
 			Assert.True (btn.NewKeyDownEvent (new ((KeyCode)'T')));
 			Assert.True (clicked);
 			Assert.True (clicked);
 			clicked = false;
 			clicked = false;
-			Assert.True (btn.NewKeyDownEvent (btn.HotKey));
-			Assert.True (clicked);
+
+			// Change hotkey:
 			btn.Text = "Te_st";
 			btn.Text = "Te_st";
-			clicked = false;
 			Assert.True (btn.NewKeyDownEvent (btn.HotKey));
 			Assert.True (btn.NewKeyDownEvent (btn.HotKey));
 			Assert.True (clicked);
 			Assert.True (clicked);
+			clicked = false;
 		}
 		}
 
 
 		[Fact]
 		[Fact]

+ 195 - 170
UnitTests/Views/WindowTests.cs

@@ -1,130 +1,122 @@
-using System;
-using Xunit;
+using Xunit;
 using Xunit.Abstractions;
 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 (@"
+
+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 (), 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       │
 │ File  Edit       │
 │┌┤Frame View├────┐│
 │┌┤Frame View├────┐│
@@ -134,11 +126,11 @@ namespace Terminal.Gui.ViewsTests {
 ││                ││
 ││                ││
 │└────────────────┘│
 │└────────────────┘│
 │ ^Q Quit │ ^O Open│
 │ ^Q Quit │ ^O Open│
-└──────────────────┘", output);
+└──────────────────┘", _output);
 
 
-			((FakeDriver)Application.Driver).SetBufferSize (40, 20);
+		((FakeDriver)Application.Driver).SetBufferSize (40, 20);
 
 
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────────────────────────┐
 ┌──────────────────────────────────────┐
 │ File  Edit                           │
 │ File  Edit                           │
 │┌┤Frame View├────────────────────────┐│
 │┌┤Frame View├────────────────────────┐│
@@ -158,11 +150,11 @@ namespace Terminal.Gui.ViewsTests {
 ││                                    ││
 ││                                    ││
 │└────────────────────────────────────┘│
 │└────────────────────────────────────┘│
 │ ^Q Quit │ ^O Open │ ^C Copy          │
 │ ^Q Quit │ ^O Open │ ^C Copy          │
-└──────────────────────────────────────┘", output);
+└──────────────────────────────────────┘", _output);
 
 
-			((FakeDriver)Application.Driver).SetBufferSize (20, 10);
+		((FakeDriver)Application.Driver).SetBufferSize (20, 10);
 
 
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
+		TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 ┌──────────────────┐
 │ File  Edit       │
 │ File  Edit       │
 │┌┤Frame View├────┐│
 │┌┤Frame View├────┐│
@@ -172,42 +164,75 @@ namespace Terminal.Gui.ViewsTests {
 ││                ││
 ││                ││
 │└────────────────┘│
 │└────────────────┘│
 │ ^Q Quit │ ^O Open│
 │ ^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);
-		}
+└──────────────────┘", _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);
+	}
+
+	public static TheoryData<Toplevel> ButtonContainers =>
+		new () {
+			{ new Window () },
+			{ new Dialog () }
+		};
+
+
+	[Theory, AutoInitShutdown]
+	[MemberData (nameof (ButtonContainers))]
+	public void With_Default_Button_Enter_Invokes_Accept_Action (Toplevel container)
+	{
+		var view = new View () { CanFocus = true };
+		var btnOk = new Button ("Accept") { IsDefault = true };
+		btnOk.Clicked += (s, e) => view.Text = "Test";
+		var btnCancel = new Button ("Cancel");
+		btnCancel.Clicked += (s, e) => view.Text = "";
+
+		container.Add (view, btnOk, btnCancel);
+		var rs = Application.Begin (container);
+
+		Assert.True (view.HasFocus);
+		Assert.Equal ("", view.Text);
+		Assert.True (Application.OnKeyDown (new Key (KeyCode.Enter)));
+		Assert.True (view.HasFocus);
+		Assert.Equal ("Test", view.Text);
+
+		btnOk.IsDefault = false;
+		btnCancel.IsDefault = true;
+		Assert.True (Application.OnKeyDown (new Key (KeyCode.Enter)));
+		Assert.True (view.HasFocus);
+		Assert.Equal ("", view.Text);
+		Application.End (rs);
 	}
 	}
-}
+}

Some files were not shown because too many files changed in this diff