Bläddra i källkod

lots of fixes

Tigger Kindel 1 år sedan
förälder
incheckning
05e203c7a4

+ 29 - 0
Terminal.Gui/Configuration/ConfigurationManager.cs

@@ -15,6 +15,31 @@ using System.Text.Json.Serialization;
 #nullable enable
 #nullable enable
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
+
+/// <summary>
+/// <para>
+/// Classes should implement this interface on any class that should be notified when the configuration changes.
+/// This is an alternative to using the <see cref="ConfigurationManager.Updated"/> and
+/// <see cref="ConfigurationManager.Applied"/> events.
+/// <para>
+/// When the configuration has changed, the <see cref="ConfigurationManager"/> will call the <see cref="OnUpdated"/>
+/// method. When the configuration is being applied, the <see cref="OnApplied"/> method will be called.
+/// 
+/// </para>
+/// </summary>
+public interface ISupportConfigChanges {
+
+	/// <summary>
+	/// Called when the configuration has been updated.
+	/// </summary>
+	public void OnUpdated ();
+
+	/// <summary>
+	/// Called when the configuration is being applied.
+	/// </summary>
+	public void OnApplied ();
+}
+
 /// <summary>
 /// <summary>
 /// Provides settings and configuration management for Terminal.Gui applications. 
 /// Provides settings and configuration management for Terminal.Gui applications. 
 /// <para>
 /// <para>
@@ -326,6 +351,10 @@ public static partial class ConfigurationManager {
 	{
 	{
 		Debug.WriteLine ($"ConfigurationManager.OnApplied()");
 		Debug.WriteLine ($"ConfigurationManager.OnApplied()");
 		Applied?.Invoke (null, new ConfigurationManagerEventArgs ());
 		Applied?.Invoke (null, new ConfigurationManagerEventArgs ());
+
+		// TODO: Refactor ConfigurationManager to not use an event handler for this.
+		// Instead, have it call a method on any class appropriately attributed
+		// to update the cached values. See Issue #2871
 	}
 	}
 
 
 	/// <summary>
 	/// <summary>

+ 60 - 41
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -14,6 +14,7 @@ using System.Management;
 using static Terminal.Gui.WindowsConsole;
 using static Terminal.Gui.WindowsConsole;
 using static Unix.Terminal.Curses;
 using static Unix.Terminal.Curses;
 using System.Drawing;
 using System.Drawing;
+using static Terminal.Gui.SpinnerStyle;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
 
 
@@ -841,6 +842,8 @@ internal class WindowsDriver : ConsoleDriver {
 #pragma warning restore CA1416 // Validate platform compatibility
 #pragma warning restore CA1416 // Validate platform compatibility
 	}
 	}
 
 
+	WindowsMainLoop _mainLoop;
+
 	public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
 	public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
 	{
 	{
 		_keyHandler = keyHandler;
 		_keyHandler = keyHandler;
@@ -848,29 +851,25 @@ internal class WindowsDriver : ConsoleDriver {
 		_keyUpHandler = keyUpHandler;
 		_keyUpHandler = keyUpHandler;
 		_mouseHandler = mouseHandler;
 		_mouseHandler = mouseHandler;
 
 
-		var mLoop = mainLoop.MainLoopDriver as WindowsMainLoop;
-
-		mLoop.ProcessInput = (e) => ProcessInput (e);
-
-		mLoop.WinChanged = (s, e) => {
-			ChangeWin (e.Size);
-		};
+		_mainLoop = mainLoop.MainLoopDriver as WindowsMainLoop;
+		_mainLoop.ProcessInput += ProcessInput;
+		_mainLoop.WinChanged += ChangeWin;
 	}
 	}
 
 
-	private void ChangeWin (Size e)
+	private void ChangeWin (Object s, SizeChangedEventArgs e)
 	{
 	{
-		var w = e.Width;
-		if (w == Cols - 3 && e.Height < Rows) {
+		var w = e.Size.Width;
+		if (w == Cols - 3 && e.Size.Height < Rows) {
 			w += 3;
 			w += 3;
 		}
 		}
 		Left = 0;
 		Left = 0;
 		Top = 0;
 		Top = 0;
-		Cols = e.Width;
-		Rows = e.Height;
+		Cols = e.Size.Width;
+		Rows = e.Size.Height;
 
 
 		if (!RunningUnitTests) {
 		if (!RunningUnitTests) {
 			var newSize = WinConsole.SetConsoleWindow (
 			var newSize = WinConsole.SetConsoleWindow (
-				(short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
+				(short)Math.Max (w, 16), (short)Math.Max (e.Size.Height, 0));
 
 
 			Cols = newSize.Width;
 			Cols = newSize.Width;
 			Rows = newSize.Height;
 			Rows = newSize.Height;
@@ -1739,6 +1738,13 @@ internal class WindowsDriver : ConsoleDriver {
 
 
 	public override void End ()
 	public override void End ()
 	{
 	{
+		if (_mainLoop != null) {
+			_mainLoop.ProcessInput -= ProcessInput;
+			_mainLoop.WinChanged -= ChangeWin;
+			_mainLoop.Dispose ();
+		}
+		_mainLoop = null;
+		
 		WinConsole?.Cleanup ();
 		WinConsole?.Cleanup ();
 		WinConsole = null;
 		WinConsole = null;
 
 
@@ -1763,7 +1769,7 @@ internal class WindowsDriver : ConsoleDriver {
 /// <remarks>
 /// <remarks>
 /// This implementation is used for WindowsDriver.
 /// This implementation is used for WindowsDriver.
 /// </remarks>
 /// </remarks>
-internal class WindowsMainLoop : IMainLoopDriver {
+internal class WindowsMainLoop : IMainLoopDriver, IDisposable {
 	ManualResetEventSlim _eventReady = new ManualResetEventSlim (false);
 	ManualResetEventSlim _eventReady = new ManualResetEventSlim (false);
 	ManualResetEventSlim _waitForProbe = new ManualResetEventSlim (false);
 	ManualResetEventSlim _waitForProbe = new ManualResetEventSlim (false);
 	ManualResetEventSlim _winChange = new ManualResetEventSlim (false);
 	ManualResetEventSlim _winChange = new ManualResetEventSlim (false);
@@ -1772,8 +1778,8 @@ internal class WindowsMainLoop : IMainLoopDriver {
 	WindowsConsole _winConsole;
 	WindowsConsole _winConsole;
 	bool _winChanged;
 	bool _winChanged;
 	Size _windowSize;
 	Size _windowSize;
-	CancellationTokenSource _tokenSource = new CancellationTokenSource ();
-
+	CancellationTokenSource _eventReadyTokenSource = new CancellationTokenSource ();
+	
 	// The records that we keep fetching
 	// The records that we keep fetching
 	Queue<WindowsConsole.InputRecord []> _resultQueue = new Queue<WindowsConsole.InputRecord []> ();
 	Queue<WindowsConsole.InputRecord []> _resultQueue = new Queue<WindowsConsole.InputRecord []> ();
 
 
@@ -1799,10 +1805,10 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		Task.Run (WindowsInputHandler);
 		Task.Run (WindowsInputHandler);
 		Task.Run (CheckWinChange);
 		Task.Run (CheckWinChange);
 	}
 	}
-
+	
 	void WindowsInputHandler ()
 	void WindowsInputHandler ()
 	{
 	{
-		while (true) {
+		while (_mainLoop != null) {
 			_waitForProbe.Wait ();
 			_waitForProbe.Wait ();
 			_waitForProbe.Reset ();
 			_waitForProbe.Reset ();
 
 
@@ -1816,27 +1822,24 @@ internal class WindowsMainLoop : IMainLoopDriver {
 
 
 	void CheckWinChange ()
 	void CheckWinChange ()
 	{
 	{
-		while (true) {
+		while (_mainLoop != null) {
 			_winChange.Wait ();
 			_winChange.Wait ();
 			_winChange.Reset ();
 			_winChange.Reset ();
-			WaitWinChange ();
+			
+			while (_mainLoop != null) {
+				Task.Delay (500).Wait ();
+				_windowSize = _winConsole.GetConsoleBufferWindow (out _);
+				if (_windowSize != Size.Empty && (_windowSize.Width != _consoleDriver.Cols
+								|| _windowSize.Height != _consoleDriver.Rows)) {
+					break;
+				}
+			}
+			
 			_winChanged = true;
 			_winChanged = true;
 			_eventReady.Set ();
 			_eventReady.Set ();
 		}
 		}
 	}
 	}
-
-	void WaitWinChange ()
-	{
-		while (true) {
-			Task.Delay (500).Wait ();
-			_windowSize = _winConsole.GetConsoleBufferWindow (out _);
-			if (_windowSize != Size.Empty && (_windowSize.Width != _consoleDriver.Cols
-			    || _windowSize.Height != _consoleDriver.Rows)) {
-				return;
-			}
-		}
-	}
-
+	
 	void IMainLoopDriver.Wakeup ()
 	void IMainLoopDriver.Wakeup ()
 	{
 	{
 		//tokenSource.Cancel ();
 		//tokenSource.Cancel ();
@@ -1853,8 +1856,8 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		}
 		}
 
 
 		try {
 		try {
-			if (!_tokenSource.IsCancellationRequested) {
-				_eventReady.Wait (waitTimeout, _tokenSource.Token);
+			if (!_eventReadyTokenSource.IsCancellationRequested) {
+				_eventReady.Wait (waitTimeout, _eventReadyTokenSource.Token);
 			}
 			}
 		} catch (OperationCanceledException) {
 		} catch (OperationCanceledException) {
 			return true;
 			return true;
@@ -1862,20 +1865,20 @@ internal class WindowsMainLoop : IMainLoopDriver {
 			_eventReady.Reset ();
 			_eventReady.Reset ();
 		}
 		}
 
 
-		if (!_tokenSource.IsCancellationRequested) {
+		if (!_eventReadyTokenSource.IsCancellationRequested) {
 			return _resultQueue.Count > 0 || CheckTimers (wait, out _) || _winChanged;
 			return _resultQueue.Count > 0 || CheckTimers (wait, out _) || _winChanged;
 		}
 		}
 
 
-		_tokenSource.Dispose ();
-		_tokenSource = new CancellationTokenSource ();
+		_eventReadyTokenSource.Dispose ();
+		_eventReadyTokenSource = new CancellationTokenSource ();
 		return true;
 		return true;
 	}
 	}
-
+	
 	bool CheckTimers (bool wait, out int waitTimeout)
 	bool CheckTimers (bool wait, out int waitTimeout)
 	{
 	{
 		long now = DateTime.UtcNow.Ticks;
 		long now = DateTime.UtcNow.Ticks;
 
 
-		if (_mainLoop.timeouts.Count > 0) {
+		if (_mainLoop?.timeouts.Count > 0) {
 			waitTimeout = (int)((_mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 			waitTimeout = (int)((_mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 			if (waitTimeout < 0)
 			if (waitTimeout < 0)
 				return true;
 				return true;
@@ -1883,9 +1886,14 @@ internal class WindowsMainLoop : IMainLoopDriver {
 			waitTimeout = -1;
 			waitTimeout = -1;
 		}
 		}
 
 
-		if (!wait)
+		if (!wait) {
 			waitTimeout = 0;
 			waitTimeout = 0;
+		}
 
 
+		if (_mainLoop == null) {
+			return false;
+		}
+		
 		int ic;
 		int ic;
 		lock (_mainLoop.idleHandlers) {
 		lock (_mainLoop.idleHandlers) {
 			ic = _mainLoop.idleHandlers.Count;
 			ic = _mainLoop.idleHandlers.Count;
@@ -1908,6 +1916,17 @@ internal class WindowsMainLoop : IMainLoopDriver {
 			WinChanged?.Invoke (this, new SizeChangedEventArgs (_windowSize));
 			WinChanged?.Invoke (this, new SizeChangedEventArgs (_windowSize));
 		}
 		}
 	}
 	}
+	public void Dispose ()
+	{
+		_eventReadyTokenSource?.Cancel ();
+		_eventReadyTokenSource?.Dispose ();
+		_eventReady?.Dispose ();
+
+		_mainLoop = null;
+		_winChange?.Dispose ();
+		_waitForProbe?.Dispose ();
+
+	}
 }
 }
 
 
 class WindowsClipboard : ClipboardBase {
 class WindowsClipboard : ClipboardBase {

+ 10 - 1
Terminal.Gui/Drawing/LineCanvas.cs

@@ -65,12 +65,15 @@ namespace Terminal.Gui {
 	/// Facilitates box drawing and line intersection detection
 	/// Facilitates box drawing and line intersection detection
 	/// and rendering.  Does not support diagonal lines.
 	/// and rendering.  Does not support diagonal lines.
 	/// </summary>
 	/// </summary>
-	public class LineCanvas {
+	public class LineCanvas : IDisposable {
 		/// <summary>
 		/// <summary>
 		/// Creates a new instance.
 		/// Creates a new instance.
 		/// </summary>
 		/// </summary>
 		public LineCanvas()
 		public LineCanvas()
 		{
 		{
+			// TODO: Refactor ConfigurationManager to not use an event handler for this.
+			// Instead, have it call a method on any class appropriately attributed
+			// to update the cached values. See Issue #2871
 			ConfigurationManager.Applied += ConfigurationManager_Applied;
 			ConfigurationManager.Applied += ConfigurationManager_Applied;
 		}
 		}
 
 
@@ -732,6 +735,12 @@ namespace Terminal.Gui {
 				AddLine (line);
 				AddLine (line);
 			}
 			}
 		}
 		}
+		
+		/// <inheritdoc />
+		public void Dispose ()
+		{
+			ConfigurationManager.Applied -= ConfigurationManager_Applied;
+		}
 	}
 	}
 	internal class IntersectionDefinition {
 	internal class IntersectionDefinition {
 		/// <summary>
 		/// <summary>

+ 4 - 3
Terminal.Gui/Input/Responder.cs

@@ -276,12 +276,13 @@ namespace Terminal.Gui {
 					// TODO: dispose managed state (managed objects)
 					// TODO: dispose managed state (managed objects)
 				}
 				}
 
 
-				// TODO: free unmanaged resources (unmanaged objects) and override finalizer
-				// TODO: set large fields to null
+#if DEBUG_IDISPOSABLE
+				Instances.Remove (this);
+#endif                               
 				disposedValue = true;
 				disposedValue = true;
 			}
 			}
 		}
 		}
-
+		
 		/// <summary>
 		/// <summary>
 		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.
 		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.
 		/// </summary>
 		/// </summary>

+ 0 - 13
Terminal.Gui/View/Frame.cs

@@ -55,19 +55,6 @@ namespace Terminal.Gui {
 			Parent?.SuperView?.ViewToScreen (rcol, rrow, out rcol, out rrow, clipped);
 			Parent?.SuperView?.ViewToScreen (rcol, rrow, out rcol, out rrow, clipped);
 		}
 		}
 
 
-		/// <summary>
-		/// Frames only render to their Parent or Parent's SuperView's LineCanvas,
-		/// so this always throws an <see cref="InvalidOperationException"/>.
-		/// </summary>
-		public override LineCanvas LineCanvas {
-			get {
-				throw new NotImplementedException ();
-			}
-			set {
-				throw new NotImplementedException ();
-			}
-		}
-
 		/// <summary>
 		/// <summary>
 		/// Does nothing for Frame
 		/// Does nothing for Frame
 		/// </summary>
 		/// </summary>

+ 3 - 0
Terminal.Gui/View/View.cs

@@ -494,6 +494,8 @@ namespace Terminal.Gui {
 		/// <inheritdoc/>
 		/// <inheritdoc/>
 		protected override void Dispose (bool disposing)
 		protected override void Dispose (bool disposing)
 		{
 		{
+			LineCanvas.Dispose ();
+			
 			Margin?.Dispose ();
 			Margin?.Dispose ();
 			Margin = null;
 			Margin = null;
 			Border?.Dispose ();
 			Border?.Dispose ();
@@ -506,6 +508,7 @@ namespace Terminal.Gui {
 				Remove (subview);
 				Remove (subview);
 				subview.Dispose ();
 				subview.Dispose ();
 			}
 			}
+			
 			base.Dispose (disposing);
 			base.Dispose (disposing);
 		}
 		}
 	}
 	}

+ 1 - 1
Terminal.Gui/View/ViewDrawing.cs

@@ -288,7 +288,7 @@ namespace Terminal.Gui {
 		/// The canvas that any line drawing that is to be shared by subviews of this view should add lines to.
 		/// The canvas that any line drawing that is to be shared by subviews of this view should add lines to.
 		/// </summary>
 		/// </summary>
 		/// <remarks><see cref="Border"/> adds border lines to this LineCanvas.</remarks>
 		/// <remarks><see cref="Border"/> adds border lines to this LineCanvas.</remarks>
-		public virtual LineCanvas LineCanvas { get; set; } = new LineCanvas ();
+		public virtual LineCanvas LineCanvas { get; internal set; } = new LineCanvas ();
 
 
 		/// <summary>
 		/// <summary>
 		/// Gets or sets whether this View will use it's SuperView's <see cref="LineCanvas"/> for
 		/// Gets or sets whether this View will use it's SuperView's <see cref="LineCanvas"/> for

+ 3 - 0
Terminal.Gui/Views/Toplevel.cs

@@ -966,6 +966,9 @@ namespace Terminal.Gui {
 		///<inheritdoc/>
 		///<inheritdoc/>
 		protected override void Dispose (bool disposing)
 		protected override void Dispose (bool disposing)
 		{
 		{
+			Application.GrabbingMouse -= Application_GrabbingMouse;
+			Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
+
 			_dragPosition = null;
 			_dragPosition = null;
 			base.Dispose (disposing);
 			base.Dispose (disposing);
 		}
 		}

+ 96 - 89
UICatalog/Scenarios/Dialogs.cs

@@ -156,105 +156,112 @@ namespace UICatalog.Scenarios {
 				IsDefault = true,
 				IsDefault = true,
 			};
 			};
 			showDialogButton.Clicked += (s, e) => {
 			showDialogButton.Clicked += (s, e) => {
-				try {
-					Dialog dialog = null;
+				var dlg = CreateDemoDialog (widthEdit, heightEdit, titleEdit, numButtonsEdit, glyphsNotWords, styleRadioGroup, buttonPressedLabel);
+				Application.Run (dlg);
+			};
 
 
-					int width = 0;
-					int.TryParse (widthEdit.Text, out width);
-					int height = 0;
-					int.TryParse (heightEdit.Text, out height);
-					int numButtons = 3;
-					int.TryParse (numButtonsEdit.Text, out numButtons);
+			Win.Add (showDialogButton);
 
 
-					var buttons = new List<Button> ();
-					var clicked = -1;
-					for (int i = 0; i < numButtons; i++) {
-						int buttonId = i;
-						Button button = null;
-						if (glyphsNotWords.Checked == true) {
-							buttonId = i;
-							button = new Button (NumberToWords.Convert (buttonId) + " " + Char.ConvertFromUtf32 (buttonId + CODE_POINT),
-								is_default: buttonId == 0);
-						} else {
-							button = new Button (NumberToWords.Convert (buttonId),
-							       is_default: buttonId == 0);
-						}
-						button.Clicked += (s, e) => {
-							clicked = buttonId;
-							Application.RequestStop ();
-						};
-						buttons.Add (button);
-					}
-					//if (buttons.Count > 1) {
-					//	buttons [1].Text = "Accept";
-					//	buttons [1].IsDefault = true;
-					//	buttons [0].Visible = false;
-					//	buttons [0].Text = "_Back";
-					//	buttons [0].IsDefault = false;
-					//}
+			Win.Add (buttonPressedLabel);
+		}
 
 
-					// This tests dynamically adding buttons; ensuring the dialog resizes if needed and 
-					// the buttons are laid out correctly
-					dialog = new Dialog (buttons.ToArray ()) {
-						Title = titleEdit.Text,
-						ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem
-					};
-					if (height != 0 || width != 0) {
-						dialog.Height = height;
-						dialog.Width = width;
-					}
+		Dialog CreateDemoDialog (TextField widthEdit, TextField heightEdit, TextField titleEdit, TextField numButtonsEdit, CheckBox glyphsNotWords, RadioGroup styleRadioGroup,  Label buttonPressedLabel)
+		{
+			Dialog dialog = null;
+			try {
 
 
-					var add = new Button ("Add a button") {
-						X = Pos.Center (),
-						Y = Pos.Center ()
-					};
-					add.Clicked += (s, e) => {
-						var buttonId = buttons.Count;
-						Button button;
-						if (glyphsNotWords.Checked == true) {
-							button = new Button (NumberToWords.Convert (buttonId) + " " + Char.ConvertFromUtf32 (buttonId + CODE_POINT),
-								is_default: buttonId == 0);
-						} else {
-							button = new Button (NumberToWords.Convert (buttonId),
-								is_default: buttonId == 0);
-						}
-						button.Clicked += (s, e) => {
-							clicked = buttonId;
-							Application.RequestStop ();
+				int width = 0;
+				int.TryParse (widthEdit.Text, out width);
+				int height = 0;
+				int.TryParse (heightEdit.Text, out height);
+				int numButtons = 3;
+				int.TryParse (numButtonsEdit.Text, out numButtons);
 
 
-						};
-						buttons.Add (button);
-						dialog.AddButton (button);
-						if (buttons.Count > 1) {
-							button.TabIndex = buttons [buttons.Count - 2].TabIndex + 1;
-						}
+				var buttons = new List<Button> ();
+				var clicked = -1;
+				for (int i = 0; i < numButtons; i++) {
+					int buttonId = i;
+					Button button = null;
+					if (glyphsNotWords.Checked == true) {
+						buttonId = i;
+						button = new Button (NumberToWords.Convert (buttonId) + " " + Char.ConvertFromUtf32 (buttonId + CODE_POINT),
+							is_default: buttonId == 0);
+					} else {
+						button = new Button (NumberToWords.Convert (buttonId),
+						       is_default: buttonId == 0);
+					}
+					button.Clicked += (s, e) => {
+						clicked = buttonId;
+						Application.RequestStop ();
 					};
 					};
-					dialog.Add (add);
+					buttons.Add (button);
+				}
+				//if (buttons.Count > 1) {
+				//	buttons [1].Text = "Accept";
+				//	buttons [1].IsDefault = true;
+				//	buttons [0].Visible = false;
+				//	buttons [0].Text = "_Back";
+				//	buttons [0].IsDefault = false;
+				//}
 
 
-					var addChar = new Button ($"Add a {Char.ConvertFromUtf32 (CODE_POINT)} to each button") {
-						X = Pos.Center (),
-						Y = Pos.Center () + 1
-					};
-					addChar.Clicked += (s, e) => {
-						foreach (var button in buttons) {
-							button.Text += Char.ConvertFromUtf32 (CODE_POINT);
-						}
-						dialog.LayoutSubviews ();
-					};
-					dialog.Closed += (s, e) => {
-						buttonPressedLabel.Text = $"{clicked}";
-					};
-					dialog.Add (addChar);
+				// This tests dynamically adding buttons; ensuring the dialog resizes if needed and 
+				// the buttons are laid out correctly
+				dialog = new Dialog (buttons.ToArray ()) {
+					Title = titleEdit.Text,
+					ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem
+				};
+				if (height != 0 || width != 0) {
+					dialog.Height = height;
+					dialog.Width = width;
+				}
 
 
-					Application.Run (dialog);
+				var add = new Button ("Add a button") {
+					X = Pos.Center (),
+					Y = Pos.Center ()
+				};
+				add.Clicked += (s, e) => {
+					var buttonId = buttons.Count;
+					Button button;
+					if (glyphsNotWords.Checked == true) {
+						button = new Button (NumberToWords.Convert (buttonId) + " " + Char.ConvertFromUtf32 (buttonId + CODE_POINT),
+							is_default: buttonId == 0);
+					} else {
+						button = new Button (NumberToWords.Convert (buttonId),
+							is_default: buttonId == 0);
+					}
+					button.Clicked += (s, e) => {
+						clicked = buttonId;
+						Application.RequestStop ();
 
 
-				} catch (FormatException) {
-					buttonPressedLabel.Text = "Invalid Options";
-				}
-			};
-			Win.Add (showDialogButton);
+					};
+					buttons.Add (button);
+					dialog.AddButton (button);
+					if (buttons.Count > 1) {
+						button.TabIndex = buttons [buttons.Count - 2].TabIndex + 1;
+					}
+				};
+				dialog.Add (add);
 
 
-			Win.Add (buttonPressedLabel);
+				var addChar = new Button ($"Add a {Char.ConvertFromUtf32 (CODE_POINT)} to each button") {
+					X = Pos.Center (),
+					Y = Pos.Center () + 1
+				};
+				addChar.Clicked += (s, e) => {
+					foreach (var button in buttons) {
+						button.Text += Char.ConvertFromUtf32 (CODE_POINT);
+					}
+					dialog.LayoutSubviews ();
+				};
+				dialog.Closed += (s, e) => {
+					buttonPressedLabel.Text = $"{clicked}";
+				};
+				dialog.Add (addChar);
+
+			} catch (FormatException) {
+				buttonPressedLabel.Text = "Invalid Options";
+			}
+			return dialog;
 		}
 		}
 	}
 	}
 }
 }
+

+ 0 - 14
UnitTests/Application/ApplicationTests.cs

@@ -83,20 +83,6 @@ namespace Terminal.Gui.ApplicationTests {
 #endif
 #endif
 		}
 		}
 
 
-		[Fact]
-		public void Init_Shutdown_Toplevel_Not_Disposed ()
-		{
-			Application.Init (new FakeDriver ());
-
-			Application.Shutdown ();
-
-#if DEBUG_IDISPOSABLE
-			// 4 for Application.Top and it's 3 Frames
-			Assert.Equal (4, Responder.Instances.Count);
-			Assert.True (Responder.Instances [0].WasDisposed);
-#endif
-		}
-
 		[Fact]
 		[Fact]
 		public void Init_Unbalanced_Throws ()
 		public void Init_Unbalanced_Throws ()
 		{
 		{

+ 1 - 1
UnitTests/ConsoleDrivers/AddRuneTests.cs

@@ -1,4 +1,4 @@
-using Microsoft.VisualStudio.TestPlatform.Utilities;
+//////using Microsoft.VisualStudio.TestPlatform.Utilities;
 using System.Buffers;
 using System.Buffers;
 using System.Text;
 using System.Text;
 using Xunit;
 using Xunit;

+ 34 - 7
UnitTests/Input/ResponderTests.cs

@@ -5,7 +5,7 @@ using Console = Terminal.Gui.FakeConsole;
 
 
 namespace Terminal.Gui.InputTests {
 namespace Terminal.Gui.InputTests {
 	public class ResponderTests {
 	public class ResponderTests {
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void New_Initializes ()
 		public void New_Initializes ()
 		{
 		{
 			var r = new Responder ();
 			var r = new Responder ();
@@ -15,9 +15,10 @@ namespace Terminal.Gui.InputTests {
 			Assert.False (r.HasFocus);
 			Assert.False (r.HasFocus);
 			Assert.True (r.Enabled);
 			Assert.True (r.Enabled);
 			Assert.True (r.Visible);
 			Assert.True (r.Visible);
+			r.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void New_Methods_Return_False ()
 		public void New_Methods_Return_False ()
 		{
 		{
 			var r = new Responder ();
 			var r = new Responder ();
@@ -30,14 +31,29 @@ namespace Terminal.Gui.InputTests {
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
-			Assert.False (r.OnEnter (new View ()));
-			Assert.False (r.OnLeave (new View ()));
+			
+			var v = new View ();
+			Assert.False (r.OnEnter (v));
+			v.Dispose ();
+			
+			v = new View ();
+			Assert.False (r.OnLeave (v));
+			v.Dispose ();
+
+			r.Dispose ();
 		}
 		}
 
 
 		// Generic lifetime (IDisposable) tests
 		// Generic lifetime (IDisposable) tests
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dispose_Works ()
 		public void Dispose_Works ()
 		{
 		{
+		
+			var r = new Responder ();
+#if DEBUG_IDISPOSABLE
+			Assert.Equal (1, Responder.Instances.Count);
+#endif
+
+			r.Dispose ();
 
 
 		}
 		}
 
 
@@ -52,7 +68,7 @@ namespace Terminal.Gui.InputTests {
 			}
 			}
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void IsOverridden_False_IfNotOverridden ()
 		public void IsOverridden_False_IfNotOverridden ()
 		{
 		{
 			// MouseEvent IS defined on Responder but NOT overridden
 			// MouseEvent IS defined on Responder but NOT overridden
@@ -67,9 +83,15 @@ namespace Terminal.Gui.InputTests {
 
 
 			// OnKeyDown is defined on View and NOT overrident on Button
 			// OnKeyDown is defined on View and NOT overrident on Button
 			Assert.False (Responder.IsOverridden (new Button () { Text = "Button does not override OnKeyDown" }, "OnKeyDown"));
 			Assert.False (Responder.IsOverridden (new Button () { Text = "Button does not override OnKeyDown" }, "OnKeyDown"));
+
+#if DEBUG_IDISPOSABLE
+			// HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
+			Responder.Instances.Clear ();
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void IsOverridden_True_IfOverridden ()
 		public void IsOverridden_True_IfOverridden ()
 		{
 		{
 			// MouseEvent is defined on Responder IS overriden on ScrollBarView (but not View)
 			// MouseEvent is defined on Responder IS overriden on ScrollBarView (but not View)
@@ -86,6 +108,11 @@ namespace Terminal.Gui.InputTests {
 			Assert.True (Responder.IsOverridden (new ScrollBarView () { Text = "ScrollBarView overrides OnDrawContent" }, "OnDrawContent"));
 			Assert.True (Responder.IsOverridden (new ScrollBarView () { Text = "ScrollBarView overrides OnDrawContent" }, "OnDrawContent"));
 
 
 			Assert.True (Responder.IsOverridden (new Button () { Text = "Button overrides MouseEvent" }, "MouseEvent"));
 			Assert.True (Responder.IsOverridden (new Button () { Text = "Button overrides MouseEvent" }, "MouseEvent"));
+#if DEBUG_IDISPOSABLE
+			// HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
+			Responder.Instances.Clear ();
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 	}
 	}
 }
 }

+ 47 - 12
UnitTests/TestHelpers.cs

@@ -62,19 +62,53 @@ public class AutoInitShutdownAttribute : Xunit.Sdk.BeforeAfterTestAttribute {
 	{
 	{
 		Debug.WriteLine ($"Before: {methodUnderTest.Name}");
 		Debug.WriteLine ($"Before: {methodUnderTest.Name}");
 		if (AutoInit) {
 		if (AutoInit) {
+#if DEBUG_IDISPOSABLE && FORCE_RESPONDER_DISPOSE
+			// Clear out any lingering Responder instances from previous tests
+			Responder.Instances.Clear ();
+			Assert.Equal (0, Responder.Instances.Count);
+#endif
 			Application.Init ((ConsoleDriver)Activator.CreateInstance (_driverType));
 			Application.Init ((ConsoleDriver)Activator.CreateInstance (_driverType));
 		}
 		}
 	}
 	}
-	
+
 	public override void After (MethodInfo methodUnderTest)
 	public override void After (MethodInfo methodUnderTest)
 	{
 	{
 		Debug.WriteLine ($"After: {methodUnderTest.Name}");
 		Debug.WriteLine ($"After: {methodUnderTest.Name}");
 		if (AutoInit) {
 		if (AutoInit) {
 			Application.Shutdown ();
 			Application.Shutdown ();
+#if DEBUG_IDISPOSABLE && FORCE_RESPONDER_DISPOSE
+			Assert.Equal (0, Responder.Instances.Count);
+#endif
 		}
 		}
 	}
 	}
 }
 }
 
 
+[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class TestRespondersDisposed : Xunit.Sdk.BeforeAfterTestAttribute {
+	public TestRespondersDisposed ()
+	{
+		CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US");
+	}
+
+	public override void Before (MethodInfo methodUnderTest)
+	{
+		Debug.WriteLine ($"Before: {methodUnderTest.Name}");
+#if DEBUG_IDISPOSABLE
+		// Clear out any lingering Responder instances from previous tests
+		Responder.Instances.Clear ();
+		Assert.Equal (0, Responder.Instances.Count);
+#endif
+	}
+
+	public override void After (MethodInfo methodUnderTest)
+	{
+		Debug.WriteLine ($"After: {methodUnderTest.Name}");
+#if DEBUG_IDISPOSABLE
+		Assert.Equal (0, Responder.Instances.Count);
+#endif
+	}
+}
+
 [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
 [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
 public class SetupFakeDriverAttribute : Xunit.Sdk.BeforeAfterTestAttribute {
 public class SetupFakeDriverAttribute : Xunit.Sdk.BeforeAfterTestAttribute {
 	/// <summary>
 	/// <summary>
@@ -118,7 +152,7 @@ partial class TestHelpers {
 		for (int r = 0; r < driver.Rows; r++) {
 		for (int r = 0; r < driver.Rows; r++) {
 			for (int c = 0; c < driver.Cols; c++) {
 			for (int c = 0; c < driver.Cols; c++) {
 				// TODO: Remove hard-coded [0] once combining pairs is supported
 				// TODO: Remove hard-coded [0] once combining pairs is supported
-				Rune rune = contents [r, c].Runes[0];
+				Rune rune = contents [r, c].Runes [0];
 				if (rune.DecodeSurrogatePair (out char [] spair)) {
 				if (rune.DecodeSurrogatePair (out char [] spair)) {
 					sb.Append (spair);
 					sb.Append (spair);
 				} else {
 				} else {
@@ -134,14 +168,14 @@ partial class TestHelpers {
 		var actualLook = sb.ToString ();
 		var actualLook = sb.ToString ();
 
 
 		if (string.Equals (expectedLook, actualLook)) return;
 		if (string.Equals (expectedLook, actualLook)) return;
-		
+
 		// get rid of trailing whitespace on each line (and leading/trailing whitespace of start/end of full string)
 		// get rid of trailing whitespace on each line (and leading/trailing whitespace of start/end of full string)
 		expectedLook = TrailingWhiteSpaceRegEx ().Replace (expectedLook, "").Trim ();
 		expectedLook = TrailingWhiteSpaceRegEx ().Replace (expectedLook, "").Trim ();
 		actualLook = TrailingWhiteSpaceRegEx ().Replace (actualLook, "").Trim ();
 		actualLook = TrailingWhiteSpaceRegEx ().Replace (actualLook, "").Trim ();
 
 
 		if (ignoreLeadingWhitespace) {
 		if (ignoreLeadingWhitespace) {
-			expectedLook = LeadingWhitespaceRegEx().Replace (expectedLook, "").Trim ();
-			actualLook = LeadingWhitespaceRegEx().Replace (actualLook, "").Trim ();
+			expectedLook = LeadingWhitespaceRegEx ().Replace (expectedLook, "").Trim ();
+			actualLook = LeadingWhitespaceRegEx ().Replace (actualLook, "").Trim ();
 		}
 		}
 
 
 		// standardize line endings for the comparison
 		// standardize line endings for the comparison
@@ -166,7 +200,7 @@ partial class TestHelpers {
 		var y = -1;
 		var y = -1;
 		var w = -1;
 		var w = -1;
 		var h = -1;
 		var h = -1;
-		
+
 		var contents = driver.Contents;
 		var contents = driver.Contents;
 
 
 		for (var r = 0; r < driver.Rows; r++) {
 		for (var r = 0; r < driver.Rows; r++) {
@@ -226,7 +260,7 @@ partial class TestHelpers {
 		if (string.Equals (expectedLook, actualLook)) {
 		if (string.Equals (expectedLook, actualLook)) {
 			return new Rect (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0);
 			return new Rect (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0);
 		}
 		}
-		
+
 		// standardize line endings for the comparison
 		// standardize line endings for the comparison
 		expectedLook = expectedLook.Replace ("\r\n", "\n");
 		expectedLook = expectedLook.Replace ("\r\n", "\n");
 		actualLook = actualLook.Replace ("\r\n", "\n");
 		actualLook = actualLook.Replace ("\r\n", "\n");
@@ -258,7 +292,7 @@ partial class TestHelpers {
 
 
 		expectedLook = expectedLook.Trim ();
 		expectedLook = expectedLook.Trim ();
 		var driver = (FakeDriver)Application.Driver;
 		var driver = (FakeDriver)Application.Driver;
-		
+
 		var contents = driver.Contents;
 		var contents = driver.Contents;
 
 
 		var r = 0;
 		var r = 0;
@@ -271,7 +305,7 @@ partial class TestHelpers {
 				var match = expectedColors.Where (e => e == val).ToList ();
 				var match = expectedColors.Where (e => e == val).ToList ();
 				switch (match.Count) {
 				switch (match.Count) {
 				case 0:
 				case 0:
-					throw new Exception ($"Unexpected color {val} was used at row {r} and col {c} (indexes start at 0).  Color value was {val} (expected colors were {string.Join (",", expectedColors.Select (c => c.Value.ToString()))})");
+					throw new Exception ($"Unexpected color {val} was used at row {r} and col {c} (indexes start at 0).  Color value was {val} (expected colors were {string.Join (",", expectedColors.Select (c => c.Value.ToString ()))})");
 				case > 1:
 				case > 1:
 					throw new ArgumentException ($"Bad value for expectedColors, {match.Count} Attributes had the same Value");
 					throw new ArgumentException ($"Bad value for expectedColors, {match.Count} Attributes had the same Value");
 				}
 				}
@@ -315,14 +349,15 @@ partial class TestHelpers {
 						toFind.Remove (match);
 						toFind.Remove (match);
 					}
 					}
 				}
 				}
-			}}
+			}
+		}
 
 
 		if (!toFind.Any ()) {
 		if (!toFind.Any ()) {
 			return;
 			return;
 		}
 		}
 		var sb = new StringBuilder ();
 		var sb = new StringBuilder ();
-		sb.AppendLine ("The following colors were not used:" + string.Join ("; ", toFind.Select (a => a.ToString())));
-		sb.AppendLine ("Colors used were:" + string.Join ("; ", colorsUsed.Select (a => a.ToString())));
+		sb.AppendLine ("The following colors were not used:" + string.Join ("; ", toFind.Select (a => a.ToString ())));
+		sb.AppendLine ("Colors used were:" + string.Join ("; ", colorsUsed.Select (a => a.ToString ())));
 		throw new Exception (sb.ToString ());
 		throw new Exception (sb.ToString ());
 	}
 	}
 
 

+ 2 - 0
UnitTests/View/BorderTests.cs

@@ -16,6 +16,7 @@ namespace Terminal.Gui.ViewTests {
 			var view = new View ();
 			var view = new View ();
 			Assert.Equal (LineStyle.None, view.BorderStyle);
 			Assert.Equal (LineStyle.None, view.BorderStyle);
 			Assert.Equal (Thickness.Empty, view.Border.Thickness);
 			Assert.Equal (Thickness.Empty, view.Border.Thickness);
+			view.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -33,6 +34,7 @@ namespace Terminal.Gui.ViewTests {
 			view.BorderStyle = LineStyle.None;
 			view.BorderStyle = LineStyle.None;
 			Assert.Equal (LineStyle.None, view.BorderStyle);
 			Assert.Equal (LineStyle.None, view.BorderStyle);
 			Assert.Equal (Thickness.Empty, view.Border.Thickness);
 			Assert.Equal (Thickness.Empty, view.Border.Thickness);
+			view.Dispose ();
 		}
 		}
 
 
 		//[Fact]
 		//[Fact]

+ 7 - 1
UnitTests/View/FrameTests.cs

@@ -41,6 +41,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			view.Margin.Thickness = new Thickness (1, 2, 3, 4);
 			view.Margin.Thickness = new Thickness (1, 2, 3, 4);
 			Assert.Equal (new Thickness (3, 5, 7, 9), view.GetFramesThickness ());
 			Assert.Equal (new Thickness (3, 5, 7, 9), view.GetFramesThickness ());
+			view.Dispose ();
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -91,7 +92,7 @@ namespace Terminal.Gui.ViewTests {
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-
+			Application.End (rs);
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -242,6 +243,7 @@ namespace Terminal.Gui.ViewTests {
 ╚═══╝";
 ╚═══╝";
 
 
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -268,6 +270,7 @@ namespace Terminal.Gui.ViewTests {
 ╚════════╝";
 ╚════════╝";
 
 
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -379,6 +382,7 @@ namespace Terminal.Gui.ViewTests {
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -490,6 +494,7 @@ namespace Terminal.Gui.ViewTests {
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -601,6 +606,7 @@ namespace Terminal.Gui.ViewTests {
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 	}
 	}
 }
 }

+ 37 - 12
UnitTests/View/Layout/AbsoluteLayoutTests.cs

@@ -18,7 +18,7 @@ namespace Terminal.Gui.ViewTests {
 			this.output = output;
 			this.output = output;
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Constructor ()
 		public void AbsoluteLayout_Constructor ()
 		{
 		{
 			var frame = new Rect (1, 2, 3, 4);
 			var frame = new Rect (1, 2, 3, 4);
@@ -30,6 +30,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 
 
 			v = new View (frame, "v");
 			v = new View (frame, "v");
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
@@ -39,6 +40,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 
 
 			v = new View (frame.X, frame.Y, "v");
 			v = new View (frame.X, frame.Y, "v");
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
@@ -49,9 +51,11 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
+			
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_Frame ()
 		public void AbsoluteLayout_Change_Frame ()
 		{
 		{
 			var frame = new Rect (1, 2, 3, 4);
 			var frame = new Rect (1, 2, 3, 4);
@@ -66,6 +70,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 
 
 			v = new View (frame.X, frame.Y, "v");
 			v = new View (frame.X, frame.Y, "v");
 			v.Frame = newFrame;
 			v.Frame = newFrame;
@@ -75,6 +80,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 
 
 			newFrame = new Rect (10, 20, 30, 40);
 			newFrame = new Rect (10, 20, 30, 40);
 			v = new View (frame);
 			v = new View (frame);
@@ -85,6 +91,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 
 
 			v = new View (frame.X, frame.Y, "v");
 			v = new View (frame.X, frame.Y, "v");
 			v.Frame = newFrame;
 			v.Frame = newFrame;
@@ -94,10 +101,10 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
-
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_Height_or_Width_Absolute ()
 		public void AbsoluteLayout_Change_Height_or_Width_Absolute ()
 		{
 		{
 			var frame = new Rect (1, 2, 3, 4);
 			var frame = new Rect (1, 2, 3, 4);
@@ -113,27 +120,30 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (v.Y);
 			Assert.Null (v.Y);
 			Assert.Equal ($"Absolute({newFrame.Height})", v.Height.ToString());
 			Assert.Equal ($"Absolute({newFrame.Height})", v.Height.ToString());
 			Assert.Equal ($"Absolute({newFrame.Width})", v.Width.ToString ());
 			Assert.Equal ($"Absolute({newFrame.Width})", v.Width.ToString ());
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_Height_or_Width_NotAbsolute ()
 		public void AbsoluteLayout_Change_Height_or_Width_NotAbsolute ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
 			v.Height = Dim.Fill ();
 			v.Height = Dim.Fill ();
 			v.Width = Dim.Fill ();
 			v.Width = Dim.Fill ();
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);  // BUGBUG: v2 - Changing the Height or Width should change the LayoutStyle
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);  // BUGBUG: v2 - Changing the Height or Width should change the LayoutStyle
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_Height_or_Width_Null ()
 		public void AbsoluteLayout_Change_Height_or_Width_Null ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
 			v.Height = null;
 			v.Height = null;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_X_or_Y_Absolute ()
 		public void AbsoluteLayout_Change_X_or_Y_Absolute ()
 		{
 		{
 			var frame = new Rect (1, 2, 3, 4);
 			var frame = new Rect (1, 2, 3, 4);
@@ -149,23 +159,26 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal ($"Absolute({newFrame.Y})", v.Y.ToString ());
 			Assert.Equal ($"Absolute({newFrame.Y})", v.Y.ToString ());
 			Assert.Null (v.Height);
 			Assert.Null (v.Height);
 			Assert.Null (v.Width);
 			Assert.Null (v.Width);
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_X_or_Y_NotAbsolute ()
 		public void AbsoluteLayout_Change_X_or_Y_NotAbsolute ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
 			v.Y = Pos.Center ();
 			v.Y = Pos.Center ();
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // BUGBUG: v2 - Changing the Height or Width should change the LayoutStyle
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // BUGBUG: v2 - Changing the Height or Width should change the LayoutStyle
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_X_or_Y_Null ()
 		public void AbsoluteLayout_Change_X_or_Y_Null ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
 			v.X = null;
 			v.X = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -173,10 +186,12 @@ namespace Terminal.Gui.ViewTests {
 
 
 			v.X = null;
 			v.X = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.Y = null;
 			v.Y = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.Y = Pos.Center ();
 			v.Y = Pos.Center ();
@@ -184,9 +199,10 @@ namespace Terminal.Gui.ViewTests {
 
 
 			v.Y = null;
 			v.Y = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_X_Y_Height_Width_Absolute ()
 		public void AbsoluteLayout_Change_X_Y_Height_Width_Absolute ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
@@ -195,6 +211,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = 3;
 			v.Height = 3;
 			v.Width = 4;
 			v.Width = 4;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -209,6 +226,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = null;
 			v.Height = null;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -223,6 +241,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = null;
 			v.Height = null;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -237,6 +256,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = null;
 			v.Height = null;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -251,6 +271,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = 3;
 			v.Height = 3;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 
 
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
@@ -265,9 +286,10 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = null;
 			v.Height = null;
 			v.Width = 4;
 			v.Width = 4;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Change_X_Y_Height_Width_Null ()
 		public void AbsoluteLayout_Change_X_Y_Height_Width_Null ()
 		{
 		{
 			var v = new View (Rect.Empty);
 			var v = new View (Rect.Empty);
@@ -277,6 +299,7 @@ namespace Terminal.Gui.ViewTests {
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
 
 
+			v.Dispose ();
 			v = new View (Rect.Empty);
 			v = new View (Rect.Empty);
 			v.X = Pos.Center ();
 			v.X = Pos.Center ();
 			v.Y = Pos.Center ();
 			v.Y = Pos.Center ();
@@ -290,9 +313,10 @@ namespace Terminal.Gui.ViewTests {
 			v.Height = null;
 			v.Height = null;
 			v.Width = null;
 			v.Width = null;
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
 			Assert.True (v.LayoutStyle == LayoutStyle.Absolute); // We never automatically change to Absolute from Computed??
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void AbsoluteLayout_Layout ()
 		public void AbsoluteLayout_Layout ()
 		{
 		{
 			var superRect = new Rect (0, 0, 100, 100);
 			var superRect = new Rect (0, 0, 100, 100);
@@ -320,6 +344,7 @@ namespace Terminal.Gui.ViewTests {
 			super.LayoutSubviews ();
 			super.LayoutSubviews ();
 			Assert.Equal (new Rect (0, 0, 10, 10), v1.Frame);
 			Assert.Equal (new Rect (0, 0, 10, 10), v1.Frame);
 			Assert.Equal (new Rect (10, 10, 10, 10), v2.Frame);
 			Assert.Equal (new Rect (10, 10, 10, 10), v2.Frame);
+			super.Dispose ();
 		}
 		}
 	}
 	}
 }
 }

+ 43 - 18
UnitTests/View/Layout/DimTests.cs

@@ -81,19 +81,24 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Throws<NullReferenceException> (() => dim.ToString ());
 			Assert.Throws<NullReferenceException> (() => dim.ToString ());
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void SetsValue ()
 		public void SetsValue ()
 		{
 		{
 			var testVal = Rect.Empty;
 			var testVal = Rect.Empty;
-			var dim = Dim.Width (new View (testVal));
+			var testValView = new View (testVal);
+			var dim = Dim.Width (testValView);
 			Assert.Equal ($"View(Width,View()({testVal}))", dim.ToString ());
 			Assert.Equal ($"View(Width,View()({testVal}))", dim.ToString ());
-
+			testValView.Dispose ();
+			
 			testVal = new Rect (1, 2, 3, 4);
 			testVal = new Rect (1, 2, 3, 4);
-			dim = Dim.Width (new View (testVal));
+			testValView = new View (testVal);
+			dim = Dim.Width (testValView);
 			Assert.Equal ($"View(Width,View()({testVal}))", dim.ToString ());
 			Assert.Equal ($"View(Width,View()({testVal}))", dim.ToString ());
+			testValView.Dispose ();
+
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Width_Equals ()
 		public void Width_Equals ()
 		{
 		{
 			var testRect1 = Rect.Empty;
 			var testRect1 = Rect.Empty;
@@ -132,6 +137,11 @@ namespace Terminal.Gui.ViewTests {
 			dim1 = Dim.Width (view1);
 			dim1 = Dim.Width (view1);
 			dim2 = Dim.Width (view2);
 			dim2 = Dim.Width (view2);
 			Assert.NotEqual (dim1, dim2);
 			Assert.NotEqual (dim1, dim2);
+#if DEBUG_IDISPOSABLE
+			// HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
+			Responder.Instances.Clear ();
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -141,16 +151,20 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Throws<NullReferenceException> (() => dim.ToString ());
 			Assert.Throws<NullReferenceException> (() => dim.ToString ());
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Height_SetsValue ()
 		public void Height_SetsValue ()
 		{
 		{
 			var testVal = Rect.Empty;
 			var testVal = Rect.Empty;
-			var dim = Dim.Height (new View (testVal));
+			var testValview = new View (testVal);
+			var dim = Dim.Height (testValview);
 			Assert.Equal ($"View(Height,View()({testVal}))", dim.ToString ());
 			Assert.Equal ($"View(Height,View()({testVal}))", dim.ToString ());
-
+			testValview.Dispose ();
+			
 			testVal = new Rect (1, 2, 3, 4);
 			testVal = new Rect (1, 2, 3, 4);
-			dim = Dim.Height (new View (testVal));
+			testValview = new View (testVal);
+			dim = Dim.Height (testValview);
 			Assert.Equal ($"View(Height,View()({testVal}))", dim.ToString ());
 			Assert.Equal ($"View(Height,View()({testVal}))", dim.ToString ());
+			testValview.Dispose ();
 		}
 		}
 
 
 		// TODO: Other Dim.Height tests (e.g. Equal?)
 		// TODO: Other Dim.Height tests (e.g. Equal?)
@@ -289,7 +303,7 @@ namespace Terminal.Gui.ViewTests {
 			Application.Run ();
 			Application.Run ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Null ()
 		public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Null ()
 		{
 		{
 			var t = new View ("top") { Width = 80, Height = 25 };
 			var t = new View ("top") { Width = 80, Height = 25 };
@@ -300,10 +314,10 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.Equal (3, w.Width = 3);
 			Assert.Equal (3, w.Width = 3);
 			Assert.Equal (4, w.Height = 4);
 			Assert.Equal (4, w.Height = 4);
-
+			t.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Another_Type_After_Sets_To_LayoutStyle_Absolute ()
 		public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Another_Type_After_Sets_To_LayoutStyle_Absolute ()
 		{
 		{
 			var t = new View ("top") { Width = 80, Height = 25 };
 			var t = new View ("top") { Width = 80, Height = 25 };
@@ -329,6 +343,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.Equal (2, v.Width = 2);
 			Assert.Equal (2, v.Width = 2);
 			Assert.Equal (2, v.Height = 2);
 			Assert.Equal (2, v.Height = 2);
+			t.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -545,7 +560,7 @@ namespace Terminal.Gui.ViewTests {
 		/// <summary>
 		/// <summary>
 		/// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461
 		/// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461
 		/// </summary>
 		/// </summary>
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void DimCombine_ObtuseScenario_Throw_If_SuperView_Refs_SubView ()
 		public void DimCombine_ObtuseScenario_Throw_If_SuperView_Refs_SubView ()
 		{
 		{
 			var t = new View () { Width = 80, Height = 25 };
 			var t = new View () { Width = 80, Height = 25 };
@@ -585,9 +600,10 @@ namespace Terminal.Gui.ViewTests {
 			//Assert.Equal (21, v1.Frame.Height);
 			//Assert.Equal (21, v1.Frame.Height);
 			//Assert.Equal (74, v2.Frame.Width);
 			//Assert.Equal (74, v2.Frame.Width);
 			//Assert.Equal (19, v2.Frame.Height);
 			//Assert.Equal (19, v2.Frame.Height);
+			t.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void DimCombine_ObtuseScenario_Does_Not_Throw_If_Two_SubViews_Refs_The_Same_SuperView ()
 		public void DimCombine_ObtuseScenario_Does_Not_Throw_If_Two_SubViews_Refs_The_Same_SuperView ()
 		{
 		{
 			var t = new View ("top") { Width = 80, Height = 25 };
 			var t = new View ("top") { Width = 80, Height = 25 };
@@ -626,9 +642,10 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (21, v1.Frame.Height);
 			Assert.Equal (21, v1.Frame.Height);
 			Assert.Equal (74, v2.Frame.Width);
 			Assert.Equal (74, v2.Frame.Width);
 			Assert.Equal (19, v2.Frame.Height);
 			Assert.Equal (19, v2.Frame.Height);
+			t.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void PosCombine_View_Not_Added_Throws ()
 		public void PosCombine_View_Not_Added_Throws ()
 		{
 		{
 			var t = new View () { Width = 80, Height = 50 };
 			var t = new View () { Width = 80, Height = 50 };
@@ -657,6 +674,8 @@ namespace Terminal.Gui.ViewTests {
 			sub.Height = Dim.Fill () - Dim.Height (v2);
 			sub.Height = Dim.Fill () - Dim.Height (v2);
 
 
 			Assert.Throws<InvalidOperationException> (() => t.LayoutSubviews ());
 			Assert.Throws<InvalidOperationException> (() => t.LayoutSubviews ());
+			t.Dispose ();
+			v2.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1109,6 +1128,7 @@ namespace Terminal.Gui.ViewTests {
 				if (k.KeyEvent.Key == Key.Enter) {
 				if (k.KeyEvent.Key == Key.Enter) {
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					view.Remove (listLabels [count - 1]);
 					view.Remove (listLabels [count - 1]);
+					listLabels [count - 1].Dispose ();
 
 
 					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 					view.Height -= 1;
 					view.Height -= 1;
@@ -1180,6 +1200,7 @@ namespace Terminal.Gui.ViewTests {
 					if (count > 0) {
 					if (count > 0) {
 						Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 						Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 						view.Remove (listLabels [count - 1]);
 						view.Remove (listLabels [count - 1]);
+						listLabels [count - 1].Dispose ();
 						listLabels.RemoveAt (count - 1);
 						listLabels.RemoveAt (count - 1);
 						Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 						Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 						view.Height -= 1;
 						view.Height -= 1;
@@ -1217,7 +1238,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (count, listLabels.Count);
 			Assert.Equal (count, listLabels.Count);
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Internal_Tests ()
 		public void Internal_Tests ()
 		{
 		{
 			var dimFactor = new Dim.DimFactor (0.10F);
 			var dimFactor = new Dim.DimFactor (0.10F);
@@ -1239,6 +1260,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (1, dimViewHeight.Anchor (0));
 			Assert.Equal (1, dimViewHeight.Anchor (0));
 			var dimViewWidth = new Dim.DimView (view, 1);
 			var dimViewWidth = new Dim.DimView (view, 1);
 			Assert.Equal (20, dimViewWidth.Anchor (0));
 			Assert.Equal (20, dimViewWidth.Anchor (0));
+
+			view.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -1305,7 +1328,7 @@ namespace Terminal.Gui.ViewTests {
 			}
 			}
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dim_Referencing_SuperView_Does_Not_Throw ()
 		public void Dim_Referencing_SuperView_Does_Not_Throw ()
 		{
 		{
 			var super = new View ("super") {
 			var super = new View ("super") {
@@ -1323,9 +1346,10 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var exception = Record.Exception (super.LayoutSubviews);
 			var exception = Record.Exception (super.LayoutSubviews);
 			Assert.Null (exception);
 			Assert.Null (exception);
+			super.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dim_SyperView_Referencing_SubView_Throws ()
 		public void Dim_SyperView_Referencing_SubView_Throws ()
 		{
 		{
 			var super = new View ("super") {
 			var super = new View ("super") {
@@ -1347,6 +1371,7 @@ namespace Terminal.Gui.ViewTests {
 			super.EndInit ();
 			super.EndInit ();
 
 
 			Assert.Throws<InvalidOperationException> (super.LayoutSubviews);
 			Assert.Throws<InvalidOperationException> (super.LayoutSubviews);
+			super.Dispose ();
 		}
 		}
 	}
 	}
 }
 }

+ 67 - 17
UnitTests/View/Layout/LayoutTests.cs

@@ -29,6 +29,9 @@ namespace Terminal.Gui.ViewTests {
 			sub2.Width = Dim.Width (sub1);
 			sub2.Width = Dim.Width (sub1);
 
 
 			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
 			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+			root.Dispose ();
+			sub1.Dispose ();
+			sub2.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -43,6 +46,9 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var exception = Record.Exception (root.LayoutSubviews);
 			var exception = Record.Exception (root.LayoutSubviews);
 			Assert.Null (exception);
 			Assert.Null (exception);
+			root.Dispose ();
+			sub1.Dispose ();
+			sub2.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -60,6 +66,9 @@ namespace Terminal.Gui.ViewTests {
 			root.LayoutSubviews ();
 			root.LayoutSubviews ();
 
 
 			Assert.Equal (6, second.Frame.X);
 			Assert.Equal (6, second.Frame.X);
+			root.Dispose ();
+			first.Dispose ();
+			second.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -74,12 +83,16 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var second = new View () { Id = "second" };
 			var second = new View () { Id = "second" };
 			root.Add (second);
 			root.Add (second);
-
+			
 			second.X = Pos.Right (first) + 1;
 			second.X = Pos.Right (first) + 1;
 
 
 			root.LayoutSubviews ();
 			root.LayoutSubviews ();
 
 
 			Assert.Equal (6, second.Frame.X);
 			Assert.Equal (6, second.Frame.X);
+			root.Dispose ();
+			top.Dispose ();
+			first.Dispose ();
+			second.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -92,6 +105,8 @@ namespace Terminal.Gui.ViewTests {
 			super.Add (sub);
 			super.Add (sub);
 			super.Width = Dim.Width (sub);
 			super.Width = Dim.Width (sub);
 			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
 			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+			root.Dispose ();
+			super.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -173,7 +188,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (5, rHeight);
 			Assert.Equal (5, rHeight);
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void GetCurrentWidth_TrySetWidth ()
 		public void GetCurrentWidth_TrySetWidth ()
 		{
 		{
 			var top = new View () {
 			var top = new View () {
@@ -204,6 +219,7 @@ namespace Terminal.Gui.ViewTests {
 			top.LayoutSubviews ();
 			top.LayoutSubviews ();
 
 
 			Assert.True (v.TrySetWidth (0, out _));
 			Assert.True (v.TrySetWidth (0, out _));
+			top.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -237,6 +253,7 @@ namespace Terminal.Gui.ViewTests {
 			top.LayoutSubviews ();
 			top.LayoutSubviews ();
 
 
 			Assert.True (v.TrySetHeight (0, out _));
 			Assert.True (v.TrySetHeight (0, out _));
+			top.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -249,6 +266,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (view1.AutoSize);
 			Assert.False (view1.AutoSize);
 			Assert.False (view2.AutoSize);
 			Assert.False (view2.AutoSize);
 			Assert.False (view3.AutoSize);
 			Assert.False (view3.AutoSize);
+			view1.Dispose ();
+			view2.Dispose ();
+			view3.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -262,6 +282,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (view1.AutoSize);
 			Assert.False (view1.AutoSize);
 			Assert.False (view2.AutoSize);
 			Assert.False (view2.AutoSize);
 			Assert.False (view3.AutoSize);
 			Assert.False (view3.AutoSize);
+			view1.Dispose ();
+			view2.Dispose ();
+			view3.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -274,6 +297,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (label1.AutoSize);
 			Assert.True (label1.AutoSize);
 			Assert.True (label2.AutoSize);
 			Assert.True (label2.AutoSize);
 			Assert.True (label3.AutoSize);
 			Assert.True (label3.AutoSize);
+			label1.Dispose ();
+			label2.Dispose ();
+			label3.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -287,6 +313,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (label1.AutoSize);
 			Assert.True (label1.AutoSize);
 			Assert.True (label2.AutoSize);
 			Assert.True (label2.AutoSize);
 			Assert.True (label3.AutoSize);
 			Assert.True (label3.AutoSize);
+			label1.Dispose ();
+			label2.Dispose ();
+			label3.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -301,6 +330,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.False (label.AutoSize);
 			Assert.False (label.AutoSize);
 			Assert.Equal ("(0,0,0,1)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,0,1)", label.Bounds.ToString ());
+			super.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -316,6 +346,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal ("(0,0,8,1)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,8,1)", label.Bounds.ToString ());
+			super.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -337,10 +368,11 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal ("(0,0,28,78)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,28,78)", label.Bounds.ToString ());
 			Assert.False (label.IsInitialized);
 			Assert.False (label.IsInitialized);
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 			Assert.True (label.IsInitialized);
 			Assert.True (label.IsInitialized);
 			Assert.False (label.AutoSize);
 			Assert.False (label.AutoSize);
 			Assert.Equal ("(0,0,28,78)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,28,78)", label.Bounds.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -366,7 +398,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal ("(0,0,28,2)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,28,2)", label.Bounds.ToString ());
 			Assert.False (label.IsInitialized);
 			Assert.False (label.IsInitialized);
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal ("(0,0,28,2)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,28,2)", label.Bounds.ToString ());
@@ -377,6 +409,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.False (label.AutoSize);
 			Assert.False (label.AutoSize);
 			Assert.Equal ("(0,0,28,1)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,28,1)", label.Bounds.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -391,7 +424,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal ("(0,0,0,0)", label.Bounds.ToString ());
 			Assert.Equal ("(0,0,0,0)", label.Bounds.ToString ());
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			// Here the AutoSize ensuring the right size with width 28 (Dim.Fill)
 			// Here the AutoSize ensuring the right size with width 28 (Dim.Fill)
@@ -430,6 +463,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			// BUGBUG: v2 - AutoSize is broken - temporarily disabling test See #2432
 			// BUGBUG: v2 - AutoSize is broken - temporarily disabling test See #2432
 			//Assert.Equal ("(0,0,28,3)", label.Bounds.ToString ());
 			//Assert.Equal ("(0,0,28,3)", label.Bounds.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -440,7 +474,7 @@ namespace Terminal.Gui.ViewTests {
 			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
 			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
 
 
 			Application.Top.Add (label, viewX, viewY);
 			Application.Top.Add (label, viewX, viewY);
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal (new Rect (0, 0, 10, 2), label.Frame);
 			Assert.Equal (new Rect (0, 0, 10, 2), label.Frame);
@@ -468,6 +502,7 @@ Y
 
 
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			Assert.Equal (new Rect (0, 0, 11, 3), pos);
 			Assert.Equal (new Rect (0, 0, 11, 3), pos);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -478,7 +513,7 @@ Y
 			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
 			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
 
 
 			Application.Top.Add (label, viewX, viewY);
 			Application.Top.Add (label, viewX, viewY);
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal (new Rect (0, 0, 2, 10), label.Frame);
 			Assert.Equal (new Rect (0, 0, 2, 10), label.Frame);
@@ -522,6 +557,7 @@ Y
 
 
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			Assert.Equal (new Rect (0, 0, 3, 11), pos);
 			Assert.Equal (new Rect (0, 0, 3, 11), pos);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -530,7 +566,7 @@ Y
 		{
 		{
 			var lbl = new Label ("123");
 			var lbl = new Label ("123");
 			Application.Top.Add (lbl);
 			Application.Top.Add (lbl);
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (lbl.AutoSize);
 			Assert.True (lbl.AutoSize);
 			Assert.Equal ("123 ", GetContents ());
 			Assert.Equal ("123 ", GetContents ());
@@ -554,6 +590,7 @@ Y
 				}
 				}
 				return text;
 				return text;
 			}
 			}
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -579,7 +616,7 @@ Y
 			};
 			};
 			win.Add (horizontalView, verticalView);
 			win.Add (horizontalView, verticalView);
 			Application.Top.Add (win);
 			Application.Top.Add (win);
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 			((FakeDriver)Application.Driver).SetBufferSize (32, 32);
 			((FakeDriver)Application.Driver).SetBufferSize (32, 32);
 
 
 			Assert.False (horizontalView.AutoSize);
 			Assert.False (horizontalView.AutoSize);
@@ -664,6 +701,7 @@ Y
 
 
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			Assert.Equal (new Rect (0, 0, 32, 32), pos);
 			Assert.Equal (new Rect (0, 0, 32, 32), pos);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -674,7 +712,7 @@ Y
 			win.Add (view);
 			win.Add (view);
 			Application.Top.Add (win);
 			Application.Top.Add (win);
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
 			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
 
 
 			Assert.Equal (new Rect (0, 0, 22, 22), win.Frame);
 			Assert.Equal (new Rect (0, 0, 22, 22), win.Frame);
@@ -976,6 +1014,7 @@ Y
 
 
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			Assert.Equal (new Rect (0, 0, 22, 22), pos);
 			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1004,7 +1043,7 @@ Y
 			};
 			};
 			win.Add (horizontalView, verticalView);
 			win.Add (horizontalView, verticalView);
 			Application.Top.Add (win);
 			Application.Top.Add (win);
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
 			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
 
 
 			Assert.True (horizontalView.AutoSize);
 			Assert.True (horizontalView.AutoSize);
@@ -1088,6 +1127,7 @@ Y
 
 
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			Assert.Equal (new Rect (0, 0, 22, 22), pos);
 			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1109,7 +1149,7 @@ Y
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 			((FakeDriver)Application.Driver).SetBufferSize (30, 5);
 			((FakeDriver)Application.Driver).SetBufferSize (30, 5);
 			var expected = @$"
 			var expected = @$"
 ┌┤Test Demo 你├──────────────┐
 ┌┤Test Demo 你├──────────────┐
@@ -1134,6 +1174,7 @@ Y
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1195,7 +1236,7 @@ Y
 			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (view1.IsInitialized);
 			Assert.True (view1.IsInitialized);
 			Assert.True (view2.IsInitialized);
 			Assert.True (view2.IsInitialized);
@@ -1226,6 +1267,7 @@ Y
 			Assert.Equal (new Rect (0, 0, 10, 5), view6.Frame);
 			Assert.Equal (new Rect (0, 0, 10, 5), view6.Frame);
 			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1288,7 +1330,7 @@ Y
 			//Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			//Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			//Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 			//Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 
 
-			Application.Begin (Application.Top);
+			var rs = Application.Begin (Application.Top);
 
 
 			Assert.True (view1.IsInitialized);
 			Assert.True (view1.IsInitialized);
 			Assert.True (view2.IsInitialized);
 			Assert.True (view2.IsInitialized);
@@ -1320,6 +1362,7 @@ Y
 			//Assert.Equal (new Rect (0, 0, 10, 17), view6.Frame);
 			//Assert.Equal (new Rect (0, 0, 10, 17), view6.Frame);
 			//Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			//Assert.Equal ("Absolute(10)", view6.Width.ToString ());
 			//Assert.Equal ("Absolute(5)", view6.Height.ToString ());
 			//Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1374,6 +1417,7 @@ Y
 			// BUGBUG: v2 - Autosize is broken when setting Width/Height AutoSize. Disabling test for now.
 			// BUGBUG: v2 - Autosize is broken when setting Width/Height AutoSize. Disabling test for now.
 			//Assert.Equal ("Absolute(2)", view2.Width.ToString ());
 			//Assert.Equal ("Absolute(2)", view2.Width.ToString ());
 			//Assert.Equal ("Absolute(17)", view2.Height.ToString ());
 			//Assert.Equal ("Absolute(17)", view2.Height.ToString ());
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1410,9 +1454,10 @@ Y
 			Assert.Equal ("Center", view2.Y.ToString ());
 			Assert.Equal ("Center", view2.Y.ToString ());
 			Assert.Equal ("Fill(0)", view2.Width.ToString ());
 			Assert.Equal ("Fill(0)", view2.Width.ToString ());
 			Assert.Equal ("Fill(0)", view2.Height.ToString ());
 			Assert.Equal ("Fill(0)", view2.Height.ToString ());
+		
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void SetRelativeLayout_PosCombine_Center_Plus_Absolute ()
 		public void SetRelativeLayout_PosCombine_Center_Plus_Absolute ()
 		{
 		{
 			var superView = new View () {
 			var superView = new View () {
@@ -1516,6 +1561,9 @@ Y
 			testView.SetRelativeLayout (superView.Frame);
 			testView.SetRelativeLayout (superView.Frame);
 			Assert.Equal (6, testView.Frame.X);
 			Assert.Equal (6, testView.Frame.X);
 			Assert.Equal (6, testView.Frame.Y);
 			Assert.Equal (6, testView.Frame.Y);
+
+			superView.Dispose ();
+
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -1653,6 +1701,7 @@ Y
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -1803,6 +1852,7 @@ Y
 				break;
 				break;
 			}
 			}
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1856,7 +1906,7 @@ Y
 			Application.End (rs);
 			Application.End (rs);
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
 		public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
@@ -1887,7 +1937,7 @@ Y
 			Application.Shutdown ();
 			Application.Shutdown ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
 		public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());

+ 37 - 9
UnitTests/View/Layout/PosTests.cs

@@ -74,11 +74,12 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win);
 			top.Add (win);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 
 
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), win.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), win.Frame);
 			Assert.Equal (new Rect (68, 22, 10, 1), tv.Frame);
 			Assert.Equal (new Rect (68, 22, 10, 1), tv.Frame);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -102,13 +103,15 @@ namespace Terminal.Gui.ViewTests {
 			var status = new StatusBar ();
 			var status = new StatusBar ();
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win, menu, status);
 			top.Add (win, menu, status);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 
 
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 1), menu.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 1), menu.Frame);
 			Assert.Equal (new Rect (0, 24, 80, 1), status.Frame);
 			Assert.Equal (new Rect (0, 24, 80, 1), status.Frame);
 			Assert.Equal (new Rect (0, 1, 80, 23), win.Frame);
 			Assert.Equal (new Rect (0, 1, 80, 23), win.Frame);
 			Assert.Equal (new Rect (68, 20, 10, 1), tv.Frame);
 			Assert.Equal (new Rect (68, 20, 10, 1), tv.Frame);
+
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -129,7 +132,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win);
 			top.Add (win);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 			((FakeDriver)Application.Driver).SetBufferSize (40, 10);
 			((FakeDriver)Application.Driver).SetBufferSize (40, 10);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
@@ -150,6 +153,7 @@ namespace Terminal.Gui.ViewTests {
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -170,7 +174,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win);
 			top.Add (win);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 			((FakeDriver)Application.Driver).SetBufferSize (40, 10);
 			((FakeDriver)Application.Driver).SetBufferSize (40, 10);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
@@ -192,6 +196,7 @@ namespace Terminal.Gui.ViewTests {
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -214,7 +219,7 @@ namespace Terminal.Gui.ViewTests {
 			var status = new StatusBar (new StatusItem [] { new (Key.F1, "~F1~ Help", null) });
 			var status = new StatusBar (new StatusItem [] { new (Key.F1, "~F1~ Help", null) });
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win, menu, status);
 			top.Add (win, menu, status);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
@@ -251,6 +256,7 @@ namespace Terminal.Gui.ViewTests {
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -273,7 +279,7 @@ namespace Terminal.Gui.ViewTests {
 			var status = new StatusBar (new StatusItem [] { new (Key.F1, "~F1~ Help", null) });
 			var status = new StatusBar (new StatusItem [] { new (Key.F1, "~F1~ Help", null) });
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (win, menu, status);
 			top.Add (win, menu, status);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 
 
 			Assert.True (label.AutoSize);
 			Assert.True (label.AutoSize);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
 			Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
@@ -310,6 +316,7 @@ namespace Terminal.Gui.ViewTests {
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -518,6 +525,11 @@ namespace Terminal.Gui.ViewTests {
 			// Pos.Bottom(win) -1
 			// Pos.Bottom(win) -1
 			pos = Pos.Bottom (new View (testRect)) - testInt;
 			pos = Pos.Bottom (new View (testRect)) - testInt;
 			Assert.Equal ($"Combine(Combine(View({side},View()({testRect}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 			Assert.Equal ($"Combine(Combine(View({side},View()({testRect}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
+
+#if DEBUG_IDISPOSABLE
+			// HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
+			Responder.Instances.Clear ();
+#endif
 		}
 		}
 
 
 		// See: https://github.com/gui-cs/Terminal.Gui/issues/504
 		// See: https://github.com/gui-cs/Terminal.Gui/issues/504
@@ -599,6 +611,9 @@ namespace Terminal.Gui.ViewTests {
 			// If Application.RunState is used then we must use Application.RunLoop with the rs parameter
 			// If Application.RunState is used then we must use Application.RunLoop with the rs parameter
 			Application.RunLoop (rs);
 			Application.RunLoop (rs);
 			cleanup (rs);
 			cleanup (rs);
+#if DEBUG_IDISPOSABLE
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -833,12 +848,16 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.Throws<InvalidOperationException> (() => Application.Run ());
 			Assert.Throws<InvalidOperationException> (() => Application.Run ());
 			Application.Shutdown ();
 			Application.Shutdown ();
+
+			v2.Dispose ();
+#if DEBUG_IDISPOSABLE
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
 		[Fact]
 		[Fact]
 		public void Pos_Add_Operator ()
 		public void Pos_Add_Operator ()
 		{
 		{
-
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
 
 
 			var top = Application.Top;
 			var top = Application.Top;
@@ -880,12 +899,14 @@ namespace Terminal.Gui.ViewTests {
 
 
 			// Shutdown must be called to safely clean up Application if Init has been called
 			// Shutdown must be called to safely clean up Application if Init has been called
 			Application.Shutdown ();
 			Application.Shutdown ();
+#if DEBUG_IDISPOSABLE
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
 		[Fact]
 		[Fact]
 		public void Pos_Subtract_Operator ()
 		public void Pos_Subtract_Operator ()
 		{
 		{
-
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
 
 
 			var top = Application.Top;
 			var top = Application.Top;
@@ -912,6 +933,7 @@ namespace Terminal.Gui.ViewTests {
 				if (k.KeyEvent.Key == Key.Enter) {
 				if (k.KeyEvent.Key == Key.Enter) {
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					view.Remove (listLabels [count - 1]);
 					view.Remove (listLabels [count - 1]);
+					listLabels [count - 1].Dispose ();
 
 
 					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 					field.Y -= 1;
 					field.Y -= 1;
@@ -938,6 +960,9 @@ namespace Terminal.Gui.ViewTests {
 
 
 			// Shutdown must be called to safely clean up Application if Init has been called
 			// Shutdown must be called to safely clean up Application if Init has been called
 			Application.Shutdown ();
 			Application.Shutdown ();
+#if DEBUG_IDISPOSABLE
+			Assert.Empty (Responder.Instances);
+#endif
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -974,6 +999,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (40, posRight.Anchor (0));
 			Assert.Equal (40, posRight.Anchor (0));
 			var posViewBottom = new Pos.PosView (view, 3);
 			var posViewBottom = new Pos.PosView (view, 3);
 			Assert.Equal (11, posViewBottom.Anchor (0));
 			Assert.Equal (11, posViewBottom.Anchor (0));
+			
+			view.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -1008,7 +1035,6 @@ namespace Terminal.Gui.ViewTests {
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
 		[InlineData (true)]
 		[InlineData (true)]
 		[InlineData (false)]
 		[InlineData (false)]
-
 		public void PosPercentPlusOne (bool testHorizontal)
 		public void PosPercentPlusOne (bool testHorizontal)
 		{
 		{
 			var container = new View {
 			var container = new View {
@@ -1065,6 +1091,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (new Rect (0, 0, 10, 10), super.Frame);
 			Assert.Equal (new Rect (0, 0, 10, 10), super.Frame);
 			Assert.Equal (new Rect (0, 0, 2, 2), view1.Frame);
 			Assert.Equal (new Rect (0, 0, 2, 2), view1.Frame);
 			Assert.Equal (new Rect (8, 0, 2, 2), view2.Frame);
 			Assert.Equal (new Rect (8, 0, 2, 2), view2.Frame);
+
+			super.Dispose ();
 		}
 		}
 	}
 	}
 }
 }

+ 26 - 4
UnitTests/View/NavigationTests.cs

@@ -45,6 +45,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal ("FrameSubview", top.MostFocused.Text);
 			Assert.Equal ("FrameSubview", top.MostFocused.Text);
 			top.ProcessKey (new KeyEvent (Key.BackTab | Key.ShiftMask, new KeyModifiers ()));
 			top.ProcessKey (new KeyEvent (Key.BackTab | Key.ShiftMask, new KeyModifiers ()));
 			Assert.Equal ($"WindowSubview", top.MostFocused.Text);
 			Assert.Equal ($"WindowSubview", top.MostFocused.Text);
+			top.Dispose ();
 		}
 		}
 
 
 
 
@@ -69,6 +70,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (r.Subviews.IndexOf (v1), r.TabIndexes.IndexOf (v1));
 			Assert.Equal (r.Subviews.IndexOf (v1), r.TabIndexes.IndexOf (v1));
 			Assert.Equal (r.Subviews.IndexOf (v2), r.TabIndexes.IndexOf (v2));
 			Assert.Equal (r.Subviews.IndexOf (v2), r.TabIndexes.IndexOf (v2));
 			Assert.Equal (r.Subviews.IndexOf (v3), r.TabIndexes.IndexOf (v3));
 			Assert.Equal (r.Subviews.IndexOf (v3), r.TabIndexes.IndexOf (v3));
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -89,6 +91,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -109,6 +112,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -129,8 +133,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
-		}
-
+			r.Dispose ();
+		} 
+		
 		[Fact]
 		[Fact]
 		public void SendSubviewBackwards_Subviews_vs_TabIndexes ()
 		public void SendSubviewBackwards_Subviews_vs_TabIndexes ()
 		{
 		{
@@ -149,6 +154,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v3) == 2);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -168,6 +174,7 @@ namespace Terminal.Gui.ViewTests {
 			v1.TabIndex = 2;
 			v1.TabIndex = 2;
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 2);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -183,6 +190,7 @@ namespace Terminal.Gui.ViewTests {
 			v1.TabIndex = 3;
 			v1.TabIndex = 3;
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 2);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 2);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -198,6 +206,7 @@ namespace Terminal.Gui.ViewTests {
 			v1.TabIndex = -1;
 			v1.TabIndex = -1;
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -215,6 +224,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 0);
 			Assert.Equal (-1, v1.TabIndex);
 			Assert.Equal (-1, v1.TabIndex);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -231,6 +241,7 @@ namespace Terminal.Gui.ViewTests {
 			v1.TabIndex = 1;
 			v1.TabIndex = 1;
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.Subviews.IndexOf (v1) == 0);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 1);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -255,6 +266,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.True (v3.HasFocus);
 			Assert.True (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -279,6 +291,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v3.HasFocus);
 			Assert.False (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -303,6 +316,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v3.HasFocus);
 			Assert.False (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -327,6 +341,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v3.HasFocus);
 			Assert.False (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -359,6 +374,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.True (v3.HasFocus);
 			Assert.True (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -391,6 +407,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (v1.HasFocus);
 			Assert.False (v1.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.False (v2.HasFocus);
 			Assert.True (v3.HasFocus);
 			Assert.True (v3.HasFocus);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -433,6 +450,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
 			Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
 			Assert.Equal (2, v3.TabIndex);
 			Assert.Equal (2, v3.TabIndex);
 			Assert.True (v3.TabStop);
 			Assert.True (v3.TabStop);
+			r.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -463,6 +481,7 @@ namespace Terminal.Gui.ViewTests {
 			v.CanFocus = true;
 			v.CanFocus = true;
 			Assert.False (f.CanFocus);
 			Assert.False (f.CanFocus);
 			Assert.True (v.CanFocus);
 			Assert.True (v.CanFocus);
+			t.Dispose ();
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -986,7 +1005,8 @@ namespace Terminal.Gui.ViewTests {
 			window.Add (view);
 			window.Add (view);
 
 
 			// Act
 			// Act
-			Application.Begin (top);
+			var rs = Application.Begin (top);
+			Application.End (rs);
 			Application.Shutdown ();
 			Application.Shutdown ();
 
 
 			// Assert does Not throw NullReferenceException
 			// Assert does Not throw NullReferenceException
@@ -1018,12 +1038,14 @@ namespace Terminal.Gui.ViewTests {
 			subView1.Add (subView1subView1);
 			subView1.Add (subView1subView1);
 			var view2 = new View { CanFocus = true };
 			var view2 = new View { CanFocus = true };
 			top.Add (view1, view2);
 			top.Add (view1, view2);
-			Application.Begin (top);
+			var rs = Application.Begin (top);
 
 
 			view2.SetFocus ();
 			view2.SetFocus ();
 			Assert.True (view1Leave);
 			Assert.True (view1Leave);
 			Assert.True (subView1Leave);
 			Assert.True (subView1Leave);
 			Assert.False (subView1subView1Leave);
 			Assert.False (subView1subView1Leave);
+			Application.End (rs);
+			subView1subView1.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]

+ 1 - 0
UnitTests/View/TitleTests.cs

@@ -68,6 +68,7 @@ namespace Terminal.Gui.ViewTests {
 			expectedOld = r.Title;
 			expectedOld = r.Title;
 			r.Title = expected;
 			r.Title = expected;
 			Assert.Equal (expected, r.Title);
 			Assert.Equal (expected, r.Title);
+			r.Dispose ();
 		}
 		}
 
 
 	}
 	}

+ 91 - 128
UnitTests/View/ViewTests.cs

@@ -15,7 +15,7 @@ namespace Terminal.Gui.ViewTests {
 			this.output = output;
 			this.output = output;
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void New_Initializes ()
 		public void New_Initializes ()
 		{
 		{
 			// Parameterless
 			// Parameterless
@@ -41,7 +41,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (r.SuperView);
 			Assert.Null (r.SuperView);
 			Assert.Null (r.MostFocused);
 			Assert.Null (r.MostFocused);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
-
+			r.Dispose ();
+			
 			// Empty Rect
 			// Empty Rect
 			r = new View (Rect.Empty);
 			r = new View (Rect.Empty);
 			Assert.NotNull (r);
 			Assert.NotNull (r);
@@ -65,6 +66,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (r.SuperView);
 			Assert.Null (r.SuperView);
 			Assert.Null (r.MostFocused);
 			Assert.Null (r.MostFocused);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
+			r.Dispose ();
 
 
 			// Rect with values
 			// Rect with values
 			r = new View (new Rect (1, 2, 3, 4));
 			r = new View (new Rect (1, 2, 3, 4));
@@ -89,6 +91,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (r.SuperView);
 			Assert.Null (r.SuperView);
 			Assert.Null (r.MostFocused);
 			Assert.Null (r.MostFocused);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
 			Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
+			r.Dispose ();
 
 
 			// Initializes a view with a vertical direction
 			// Initializes a view with a vertical direction
 			r = new View ("Vertical View", TextDirection.TopBottom_LeftRight);
 			r = new View ("Vertical View", TextDirection.TopBottom_LeftRight);
@@ -113,10 +116,11 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (r.SuperView);
 			Assert.Null (r.SuperView);
 			Assert.Null (r.MostFocused);
 			Assert.Null (r.MostFocused);
 			Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection);
 			Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection);
-
+			r.Dispose ();
+		
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void New_Methods_Return_False ()
 		public void New_Methods_Return_False ()
 		{
 		{
 			var r = new View ();
 			var r = new View ();
@@ -129,13 +133,22 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
-			Assert.False (r.OnEnter (new View ()));
-			Assert.False (r.OnLeave (new View ()));
+
+			var v1 = new View ();
+			Assert.False (r.OnEnter (v1));
+			v1.Dispose ();
+
+			var v2 = new View ();
+			Assert.False (r.OnLeave (v2));
+			v2.Dispose ();
+
+			r.Dispose ();
+
 
 
 			// TODO: Add more
 			// TODO: Add more
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void View_With_No_Difference_Between_An_Object_Initializer_And_A_Constructor ()
 		public void View_With_No_Difference_Between_An_Object_Initializer_And_A_Constructor ()
 		{
 		{
 			// Object Initializer
 			// Object Initializer
@@ -168,7 +181,12 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (4, view.Height);
 			Assert.Equal (4, view.Height);
 			Assert.False (view.Frame.IsEmpty);
 			Assert.False (view.Frame.IsEmpty);
 			Assert.False (view.Bounds.IsEmpty);
 			Assert.False (view.Bounds.IsEmpty);
+			super.Dispose ();
 
 
+#if DEBUG_IDISPOSABLE
+			Assert.Empty (Responder.Instances);
+#endif
+			
 			// Default Constructor
 			// Default Constructor
 			view = new View ();
 			view = new View ();
 			Assert.Null (view.X);
 			Assert.Null (view.X);
@@ -177,6 +195,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (view.Height);
 			Assert.Null (view.Height);
 			Assert.True (view.Frame.IsEmpty);
 			Assert.True (view.Frame.IsEmpty);
 			Assert.True (view.Bounds.IsEmpty);
 			Assert.True (view.Bounds.IsEmpty);
+			view.Dispose ();
 
 
 			// Constructor
 			// Constructor
 			view = new View (1, 2, "");
 			view = new View (1, 2, "");
@@ -186,6 +205,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Null (view.Height);
 			Assert.Null (view.Height);
 			Assert.False (view.Frame.IsEmpty);
 			Assert.False (view.Frame.IsEmpty);
 			Assert.True (view.Bounds.IsEmpty);
 			Assert.True (view.Bounds.IsEmpty);
+			view.Dispose ();
 
 
 			// Default Constructor and post assignment equivalent to Object Initializer
 			// Default Constructor and post assignment equivalent to Object Initializer
 			view = new View ();
 			view = new View ();
@@ -206,9 +226,10 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (new Rect (1, 2, 3, 4), view.Frame);
 			Assert.Equal (new Rect (1, 2, 3, 4), view.Frame);
 			Assert.False (view.Bounds.IsEmpty);
 			Assert.False (view.Bounds.IsEmpty);
 			Assert.Equal (new Rect (0, 0, 3, 4), view.Bounds);
 			Assert.Equal (new Rect (0, 0, 3, 4), view.Bounds);
+			super.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Added_Removed ()
 		public void Added_Removed ()
 		{
 		{
 			var v = new View (new Rect (0, 0, 10, 24));
 			var v = new View (new Rect (0, 0, 10, 24));
@@ -231,9 +252,12 @@ namespace Terminal.Gui.ViewTests {
 
 
 			t.Remove (v);
 			t.Remove (v);
 			Assert.True (t.Subviews.Count == 0);
 			Assert.True (t.Subviews.Count == 0);
+
+			t.Dispose ();
+			v.Dispose ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Initialized_Event_Comparing_With_Added_Event ()
 		public void Initialized_Event_Comparing_With_Added_Event ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
@@ -330,9 +354,10 @@ namespace Terminal.Gui.ViewTests {
 
 
 			v1.CanFocus = true;
 			v1.CanFocus = true;
 			Assert.False (sv1.CanFocus); // False because sv1 was disposed and it isn't a subview of v1.
 			Assert.False (sv1.CanFocus); // False because sv1 was disposed and it isn't a subview of v1.
+
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically ()
 		public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
@@ -409,104 +434,11 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (w.CanFocus);
 			Assert.True (w.CanFocus);
 			Assert.False (v1.CanFocus);
 			Assert.False (v1.CanFocus);
 			Assert.False (v2.CanFocus);
 			Assert.False (v2.CanFocus);
-		}
-
-		[Fact]
-		public void Multi_Thread_Toplevels ()
-		{
-			Application.Init (new FakeDriver ());
-
-			var t = Application.Top;
-			var w = new Window ();
-			t.Add (w);
-
-			int count = 0, count1 = 0, count2 = 0;
-			bool log = false, log1 = false, log2 = false;
-			bool fromTopStillKnowFirstIsRunning = false;
-			bool fromTopStillKnowSecondIsRunning = false;
-			bool fromFirstStillKnowSecondIsRunning = false;
-
-			Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
-				count++;
-				if (count1 == 5) {
-					log1 = true;
-				}
-				if (count1 == 14 && count2 == 10 && count == 15) { // count2 is already stopped
-					fromTopStillKnowFirstIsRunning = true;
-				}
-				if (count1 == 7 && count2 == 7 && count == 8) {
-					fromTopStillKnowSecondIsRunning = true;
-				}
-				if (count == 30) {
-					Assert.Equal (30, count);
-					Assert.Equal (20, count1);
-					Assert.Equal (10, count2);
-
-					Assert.True (log);
-					Assert.True (log1);
-					Assert.True (log2);
-
-					Assert.True (fromTopStillKnowFirstIsRunning);
-					Assert.True (fromTopStillKnowSecondIsRunning);
-					Assert.True (fromFirstStillKnowSecondIsRunning);
-
-					Application.RequestStop ();
-					return false;
-				}
-				return true;
-			});
-
-			t.Ready += FirstDialogToplevel;
-
-			void FirstDialogToplevel (object sender, EventArgs args)
-			{
-				var od = new OpenDialog ();
-				od.Ready += SecondDialogToplevel;
-
-				Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
-					count1++;
-					if (count2 == 5) {
-						log2 = true;
-					}
-					if (count2 == 4 && count1 == 5 && count == 5) {
-						fromFirstStillKnowSecondIsRunning = true;
-					}
-					if (count1 == 20) {
-						Assert.Equal (20, count1);
-						Application.RequestStop ();
-						return false;
-					}
-					return true;
-				});
-
-				Application.Run (od);
-			}
 
 
-			void SecondDialogToplevel (object sender, EventArgs args)
-			{
-				var d = new Dialog ();
-
-				Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
-					count2++;
-					if (count < 30) {
-						log = true;
-					}
-					if (count2 == 10) {
-						Assert.Equal (10, count2);
-						Application.RequestStop ();
-						return false;
-					}
-					return true;
-				});
-
-				Application.Run (d);
-			}
-
-			Application.Run ();
-			Application.Shutdown ();
 		}
 		}
 
 
-		[Theory]
+
+		[Theory, TestRespondersDisposed]
 		[InlineData (1)]
 		[InlineData (1)]
 		[InlineData (2)]
 		[InlineData (2)]
 		[InlineData (3)]
 		[InlineData (3)]
@@ -544,8 +476,7 @@ namespace Terminal.Gui.ViewTests {
 			}
 			}
 		}
 		}
 
 
-		[Fact]
-		[AutoInitShutdown]
+		[Fact, AutoInitShutdown]
 		public void Internal_Tests ()
 		public void Internal_Tests ()
 		{
 		{
 			Assert.Equal (new [] { View.Direction.Forward, View.Direction.Backward },
 			Assert.Equal (new [] { View.Direction.Forward, View.Direction.Backward },
@@ -574,7 +505,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal (top.Bounds, view.ScreenClip (top.Bounds));
 			Assert.Equal (top.Bounds, view.ScreenClip (top.Bounds));
 			Assert.True (view.LayoutStyle == LayoutStyle.Absolute);
 			Assert.True (view.LayoutStyle == LayoutStyle.Absolute);
 
 
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			view.Width = Dim.Fill ();
 			view.Width = Dim.Fill ();
 			view.Height = Dim.Fill ();
 			view.Height = Dim.Fill ();
@@ -618,10 +549,11 @@ namespace Terminal.Gui.ViewTests {
 			view.ViewToScreen (0, 0, out rcol, out rrow);
 			view.ViewToScreen (0, 0, out rcol, out rrow);
 			Assert.Equal (-41, rcol);
 			Assert.Equal (-41, rcol);
 			Assert.Equal (-13, rrow);
 			Assert.Equal (-13, rrow);
+			
+			Application.End (runState);
 		}
 		}
 
 
-		[Fact]
-		[AutoInitShutdown]
+		[Fact, AutoInitShutdown]
 		public void Visible_Sets_Also_Sets_Subviews ()
 		public void Visible_Sets_Also_Sets_Subviews ()
 		{
 		{
 			var button = new Button ("Click Me");
 			var button = new Button ("Click Me");
@@ -689,8 +621,7 @@ namespace Terminal.Gui.ViewTests {
 			}
 			}
 		}
 		}
 
 
-		[Fact]
-		[AutoInitShutdown]
+		[Fact, AutoInitShutdown]
 		public void GetTopSuperView_Test ()
 		public void GetTopSuperView_Test ()
 		{
 		{
 			var v1 = new View ();
 			var v1 = new View ();
@@ -713,9 +644,18 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Assert.Equal (top1, v1.GetTopSuperView ());
 			Assert.Equal (top1, v1.GetTopSuperView ());
 			Assert.Equal (top2, v2.GetTopSuperView ());
 			Assert.Equal (top2, v2.GetTopSuperView ());
-		}
-
 
 
+			v1.Dispose ();
+			fv1.Dispose ();
+			tf1.Dispose ();
+			w1.Dispose ();
+			top1.Dispose ();
+			v2.Dispose ();
+			fv2.Dispose ();
+			tf2.Dispose ();
+			w2.Dispose ();
+			top2.Dispose ();
+		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
 		public void Clear_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
 		public void Clear_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
@@ -868,7 +808,7 @@ namespace Terminal.Gui.ViewTests {
 			//Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
 			//Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void IsAdded_Added_Removed ()
 		public void IsAdded_Added_Removed ()
 		{
 		{
 			var top = new Toplevel ();
 			var top = new Toplevel ();
@@ -878,6 +818,9 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (view.IsAdded);
 			Assert.True (view.IsAdded);
 			top.Remove (view);
 			top.Remove (view);
 			Assert.False (view.IsAdded);
 			Assert.False (view.IsAdded);
+			
+			top.Dispose ();
+			view.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -911,6 +854,7 @@ namespace Terminal.Gui.ViewTests {
 │                            │
 │                            │
 └────────────────────────────┘
 └────────────────────────────┘
 ", output);
 ", output);
+			Application.End (rs);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -940,6 +884,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			view.Enabled = false;
 			view.Enabled = false;
 			Assert.Equal (view.ColorScheme.Disabled, view.GetNormalColor ());
 			Assert.Equal (view.ColorScheme.Disabled, view.GetNormalColor ());
+			view.Dispose ();
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -951,6 +896,7 @@ namespace Terminal.Gui.ViewTests {
 
 
 			view.Enabled = false;
 			view.Enabled = false;
 			Assert.Equal (view.ColorScheme.Disabled, view.GetHotNormalColor ());
 			Assert.Equal (view.ColorScheme.Disabled, view.GetHotNormalColor ());
+			view.Dispose ();
 		}
 		}
 
 
 		[Theory, AutoInitShutdown]
 		[Theory, AutoInitShutdown]
@@ -973,7 +919,7 @@ namespace Terminal.Gui.ViewTests {
 			root.Add (v);
 			root.Add (v);
 
 
 			Application.Top.Add (root);
 			Application.Top.Add (root);
-			Application.Begin (Application.Top);
+			var runState = Application.Begin (Application.Top);
 
 
 			if (label) {
 			if (label) {
 				Assert.True (v.AutoSize);
 				Assert.True (v.AutoSize);
@@ -1014,6 +960,7 @@ cccccccccccccccccccc", output);
 222222222222222222220
 222222222222222222220
 111111111111111111110", attributes);
 111111111111111111110", attributes);
 			}
 			}
+			Application.End (runState);
 		}
 		}
 
 
 		public class DerivedView : View {
 		public class DerivedView : View {
@@ -1081,7 +1028,7 @@ cccccccccccccccccccc", output);
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			top.Draw ();
 			top.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1100,6 +1047,7 @@ At 0,0
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 At 0,0     
 At 0,0     
  A text wit", output);
  A text wit", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1115,7 +1063,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			top.Draw ();
 			top.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1135,6 +1083,7 @@ At 0,0
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 At 0,0     
 At 0,0     
  A text wit", output);
  A text wit", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1150,7 +1099,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			view.Draw ();
 			view.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1171,6 +1120,7 @@ At 0,0
  A text wit                  
  A text wit                  
   A text with some long width
   A text with some long width
    and also with two lines.  ", output);
    and also with two lines.  ", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1186,7 +1136,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			view.Draw ();
 			view.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1208,6 +1158,7 @@ At 0,0
  A text wit                  
  A text wit                  
   A text with some long width
   A text with some long width
    and also with two lines.  ", output);
    and also with two lines.  ", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1223,7 +1174,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 At 0,0                       
 At 0,0                       
@@ -1243,6 +1194,7 @@ At 0,0
              
              
              
              
    A text wit", output);
    A text wit", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1258,7 +1210,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			top.Draw ();
 			top.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1280,6 +1232,7 @@ At 0,0
              
              
              
              
    A text wit", output);
    A text wit", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1295,7 +1248,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			view.Draw ();
 			view.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1313,6 +1266,7 @@ At 0,0
                              
                              
   A text with some long width
   A text with some long width
    A text witith two lines.  ", output);
    A text witith two lines.  ", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1328,7 +1282,7 @@ At 0,0
 			};
 			};
 			var top = Application.Top;
 			var top = Application.Top;
 			top.Add (label, view);
 			top.Add (label, view);
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			view.Draw ();
 			view.Draw ();
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1350,6 +1304,7 @@ At 0,0
                              
                              
   A text with some long width
   A text with some long width
    A text witith two lines.  ", output);
    A text witith two lines.  ", output);
+			Application.End (runState);
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]
@@ -1377,10 +1332,12 @@ At 0,0
 ───────────
 ───────────
 222";
 222";
 			TestHelpers.AssertDriverContentsAre (looksLike, output);
 			TestHelpers.AssertDriverContentsAre (looksLike, output);
+			v.Dispose ();
+			top.Dispose ();
+			bottom.Dispose ();
 		}
 		}
 
 
-		[Fact]
-		[AutoInitShutdown]
+		[Fact, AutoInitShutdown]
 		public void Frame_Set_After_Initialize_Update_NeededDisplay ()
 		public void Frame_Set_After_Initialize_Update_NeededDisplay ()
 		{
 		{
 			var frame = new FrameView ();
 			var frame = new FrameView ();
@@ -1409,7 +1366,7 @@ At 0,0
 
 
 			top.Add (frame);
 			top.Add (frame);
 
 
-			Application.Begin (top);
+			var runState = Application.Begin (top);
 
 
 			top.LayoutComplete += (s, e) => {
 			top.LayoutComplete += (s, e) => {
 				Assert.Equal (new Rect (0, 0, 80, 25), top._needsDisplayRect);
 				Assert.Equal (new Rect (0, 0, 80, 25), top._needsDisplayRect);
@@ -1447,9 +1404,10 @@ At 0,0
 ";
 ";
 
 
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Application.End (runState);
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dispose_View ()
 		public void Dispose_View ()
 		{
 		{
 			var view = new View ();
 			var view = new View ();
@@ -1457,10 +1415,15 @@ At 0,0
 			Assert.NotNull (view.Border);
 			Assert.NotNull (view.Border);
 			Assert.NotNull (view.Padding);
 			Assert.NotNull (view.Padding);
 
 
+#if DEBUG_IDISPOSABLE
+			Assert.Equal (4, Responder.Instances.Count);
+#endif
+
 			view.Dispose ();
 			view.Dispose ();
 			Assert.Null (view.Margin);
 			Assert.Null (view.Margin);
 			Assert.Null (view.Border);
 			Assert.Null (view.Border);
 			Assert.Null (view.Padding);
 			Assert.Null (view.Padding);
+
 		}
 		}
 	}
 	}
 }
 }

+ 6 - 14
UnitTests/Views/OverlappedTests.cs

@@ -19,25 +19,22 @@ namespace Terminal.Gui.ViewsTests {
 #endif
 #endif
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
 		public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
 
 
 			var top = new Toplevel ();
 			var top = new Toplevel ();
 			var rs = Application.Begin (top);
 			var rs = Application.Begin (top);
-			Application.End (rs);
-
-			Application.Shutdown ();
-
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-			Assert.Equal (8, Responder.Instances.Count);
-			Assert.True (Responder.Instances [0].WasDisposed);
-			Assert.True (Responder.Instances [1].WasDisposed);
+			Assert.Equal (4, Responder.Instances.Count);
 #endif
 #endif
+
+			Application.End (rs);
+			Application.Shutdown ();
 		}
 		}
 
 
-		[Fact]
+		[Fact, TestRespondersDisposed]
 		public void Dispose_Toplevel_IsOverlappedContainer_True_With_Begin ()
 		public void Dispose_Toplevel_IsOverlappedContainer_True_With_Begin ()
 		{
 		{
 			Application.Init (new FakeDriver ());
 			Application.Init (new FakeDriver ());
@@ -47,11 +44,6 @@ namespace Terminal.Gui.ViewsTests {
 			Application.End (rs);
 			Application.End (rs);
 
 
 			Application.Shutdown ();
 			Application.Shutdown ();
-#if DEBUG_IDISPOSABLE
-			Assert.Equal (8, Responder.Instances.Count);
-			Assert.True (Responder.Instances [0].WasDisposed);
-			Assert.True (Responder.Instances [1].WasDisposed);
-#endif
 		}
 		}
 
 
 		[Fact, AutoInitShutdown]
 		[Fact, AutoInitShutdown]

+ 96 - 0
UnitTests/Views/ToplevelTests.cs

@@ -1602,5 +1602,101 @@ namespace Terminal.Gui.ViewsTests {
 			var exception = Record.Exception (() => topChild.ProcessHotKey (new KeyEvent (Key.AltMask, new KeyModifiers { Alt = true })));
 			var exception = Record.Exception (() => topChild.ProcessHotKey (new KeyEvent (Key.AltMask, new KeyModifiers { Alt = true })));
 			Assert.Null (exception);
 			Assert.Null (exception);
 		}
 		}
+
+
+		[Fact, TestRespondersDisposed]
+		public void Multi_Thread_Toplevels ()
+		{
+			Application.Init (new FakeDriver ());
+
+			var t = Application.Top;
+			var w = new Window ();
+			t.Add (w);
+
+			int count = 0, count1 = 0, count2 = 0;
+			bool log = false, log1 = false, log2 = false;
+			bool fromTopStillKnowFirstIsRunning = false;
+			bool fromTopStillKnowSecondIsRunning = false;
+			bool fromFirstStillKnowSecondIsRunning = false;
+
+			Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
+				count++;
+				if (count1 == 5) {
+					log1 = true;
+				}
+				if (count1 == 14 && count2 == 10 && count == 15) { // count2 is already stopped
+					fromTopStillKnowFirstIsRunning = true;
+				}
+				if (count1 == 7 && count2 == 7 && count == 8) {
+					fromTopStillKnowSecondIsRunning = true;
+				}
+				if (count == 30) {
+					Assert.Equal (30, count);
+					Assert.Equal (20, count1);
+					Assert.Equal (10, count2);
+
+					Assert.True (log);
+					Assert.True (log1);
+					Assert.True (log2);
+
+					Assert.True (fromTopStillKnowFirstIsRunning);
+					Assert.True (fromTopStillKnowSecondIsRunning);
+					Assert.True (fromFirstStillKnowSecondIsRunning);
+
+					Application.RequestStop ();
+					return false;
+				}
+				return true;
+			});
+
+			t.Ready += FirstDialogToplevel;
+
+			void FirstDialogToplevel (object sender, EventArgs args)
+			{
+				var od = new OpenDialog ();
+				od.Ready += SecondDialogToplevel;
+
+				Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
+					count1++;
+					if (count2 == 5) {
+						log2 = true;
+					}
+					if (count2 == 4 && count1 == 5 && count == 5) {
+						fromFirstStillKnowSecondIsRunning = true;
+					}
+					if (count1 == 20) {
+						Assert.Equal (20, count1);
+						Application.RequestStop ();
+						return false;
+					}
+					return true;
+				});
+
+				Application.Run (od);
+			}
+
+			void SecondDialogToplevel (object sender, EventArgs args)
+			{
+				var d = new Dialog ();
+
+				Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => {
+					count2++;
+					if (count < 30) {
+						log = true;
+					}
+					if (count2 == 10) {
+						Assert.Equal (10, count2);
+						Application.RequestStop ();
+						return false;
+					}
+					return true;
+				});
+
+				Application.Run (d);
+			}
+
+			Application.Run ();
+			Application.Shutdown ();
+		}
 	}
 	}
 }
 }

+ 1 - 1
UnitTests/xunit.runner.json

@@ -2,5 +2,5 @@
   "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
   "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
   "parallelizeTestCollections": false,
   "parallelizeTestCollections": false,
   "parallelizeAssembly": false,
   "parallelizeAssembly": false,
-  "stopOnFail": false
+  "stopOnFail": true
 }
 }