Bläddra i källkod

Refactored CheckTimers into MainLoop and renamed/simplified

Tigger Kindel 1 år sedan
förälder
incheckning
1c133ba364

+ 16 - 24
Terminal.Gui/Application.cs

@@ -470,14 +470,14 @@ namespace Terminal.Gui {
 		///  <para>
 		///   Alternatively, to have a program control the main loop and 
 		///   process events manually, call <see cref="Begin(Toplevel)"/> to set things up manually and then
-		///   repeatedly call <see cref="RunLoop(RunState, bool)"/> with the wait parameter set to false. By doing this
-		///   the <see cref="RunLoop(RunState, bool)"/> method will only process any pending events, timers, idle handlers and
+		///   repeatedly call <see cref="RunLoop(RunState)"/> with the wait parameter set to false. By doing this
+		///   the <see cref="RunLoop(RunState)"/> method will only process any pending events, timers, idle handlers and
 		///   then return control immediately.
 		///  </para>
 		///  <para>
-		///   RELEASE builds only: When <paramref name="errorHandler"/> is <see langword="null"/> any exeptions will be rethrown. 
+		///   RELEASE builds only: When <paramref name="errorHandler"/> is <see langword="null"/> any exceptions will be rethrown. 
 		///   Otherwise, if <paramref name="errorHandler"/> will be called. If <paramref name="errorHandler"/> 
-		///   returns <see langword="true"/> the <see cref="RunLoop(RunState, bool)"/> will resume; otherwise 
+		///   returns <see langword="true"/> the <see cref="RunLoop(RunState)"/> will resume; otherwise 
 		///   this method will exit.
 		///  </para>
 		/// </remarks>
@@ -598,13 +598,8 @@ namespace Terminal.Gui {
 		/// <summary>
 		///  Building block API: Runs the <see cref="MainLoop"/> for the created <see cref="Toplevel"/>.
 		/// </summary>
-		/// <remarks>
-		///  Use the <paramref name="wait"/> parameter to control whether this is a blocking or non-blocking call.
-		/// </remarks>
 		/// <param name="state">The state returned by the <see cref="Begin(Toplevel)"/> method.</param>
-		/// <param name="wait">By default this is <see langword="true"/> which will execute the loop waiting for events, 
-		/// if set to <see langword="false"/>, a single iteration will execute.</param>
-		public static void RunLoop (RunState state, bool wait = true)
+		public static void RunLoop (RunState state)
 		{
 			if (state == null)
 				throw new ArgumentNullException (nameof (state));
@@ -616,7 +611,7 @@ namespace Terminal.Gui {
 				if (ExitRunLoopAfterFirstIteration && !firstIteration) {
 					return;
 				}
-				RunMainLoopIteration (ref state, wait, ref firstIteration);
+				RunMainLoopIteration (ref state, ref firstIteration);
 			}
 		}
 
@@ -624,13 +619,11 @@ namespace Terminal.Gui {
 		/// Run one iteration of the <see cref="MainLoop"/>.
 		/// </summary>
 		/// <param name="state">The state returned by <see cref="Begin(Toplevel)"/>.</param>
-		/// <param name="wait">If <see langword="true"/> will execute the <see cref="MainLoop"/> waiting for events. If <see langword="false"/>
-		/// the method will return after a single iteration.</param>
 		/// <param name="firstIteration">Set to <see langword="true"/> if this is the first run loop iteration. Upon return,
 		/// it will be set to <see langword="false"/> if at least one iteration happened.</param>
-		public static void RunMainLoopIteration (ref RunState state, bool wait, ref bool firstIteration)
+		public static void RunMainLoopIteration (ref RunState state, ref bool firstIteration)
 		{
-			if (MainLoop.EventsPending (wait)) {
+			if (MainLoop.EventsPending ()) {
 				// Notify Toplevel it's ready
 				if (firstIteration) {
 					state.Toplevel.OnReady ();
@@ -652,9 +645,8 @@ namespace Terminal.Gui {
 				if (Driver.EnsureCursorVisibility ()) {
 					state.Toplevel.SetNeedsDisplay ();
 				}
-			} else if (!wait) {
-				return;
 			}
+
 			firstIteration = false;
 
 			if (state.Toplevel != Top &&
@@ -696,13 +688,13 @@ namespace Terminal.Gui {
 			}
 		}
 
-		/// <summary>
-		/// Wakes up the <see cref="MainLoop"/> that might be waiting on input; must be thread safe.
-		/// </summary>
-		public static void DoEvents ()
-		{
-			MainLoop.MainLoopDriver.Wakeup ();
-		}
+		///// <summary>
+		///// Wakes up the <see cref="MainLoop"/> that might be waiting on input; must be thread safe.
+		///// </summary>
+		//public static void DoEvents ()
+		//{
+		//	MainLoop.MainLoopDriver.Wakeup ();
+		//}
 
 		/// <summary>
 		/// Stops running the most recent <see cref="Toplevel"/> or the <paramref name="top"/> if provided.

+ 36 - 33
Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs

@@ -1,5 +1,5 @@
 //
-// mainloop.cs: Simple managed mainloop implementation.
+// mainloop.cs: Linux/Curses MainLoop implementation.
 //
 using System;
 using System.Collections.Generic;
@@ -10,7 +10,7 @@ namespace Terminal.Gui {
 	/// Unix main loop, suitable for using on Posix systems
 	/// </summary>
 	/// <remarks>
-	/// In addition to the general functions of the mainloop, the Unix version
+	/// In addition to the general functions of the MainLoop, the Unix version
 	/// can watch file descriptors using the AddWatch methods.
 	/// </remarks>
 	internal class UnixMainLoop : IMainLoopDriver {
@@ -78,19 +78,19 @@ namespace Terminal.Gui {
 		[DllImport ("libc")]
 		extern static int write (int fd, IntPtr buf, IntPtr n);
 
-		Pollfd [] _pollmap;
-		bool _poll_dirty = true;
-		int [] _wakeupPipes = new int [2];
-		static IntPtr _ignore = Marshal.AllocHGlobal (1);
+		Pollfd [] _pollMap;
+		bool _pollDirty = true;
+		readonly int [] _wakeUpPipes = new int [2];
+		static readonly IntPtr _ignore = Marshal.AllocHGlobal (1);
 		MainLoop _mainLoop;
 		bool _winChanged;
 
-		public Action WinChanged;
+		internal Action WinChanged;
 
 		void IMainLoopDriver.Wakeup ()
 		{
 			if (!ConsoleDriver.RunningUnitTests) {
-				write (_wakeupPipes [1], _ignore, (IntPtr)1);
+				write (_wakeUpPipes [1], _ignore, (IntPtr)1);
 			}
 		}
 
@@ -102,13 +102,13 @@ namespace Terminal.Gui {
 			}
 
 			try {
-				pipe (_wakeupPipes);
-				AddWatch (_wakeupPipes [0], Condition.PollIn, ml => {
-					read (_wakeupPipes [0], _ignore, (IntPtr)1);
+				pipe (_wakeUpPipes);
+				AddWatch (_wakeUpPipes [0], Condition.PollIn, ml => {
+					read (_wakeUpPipes [0], _ignore, (IntPtr)1);
 					return true;
 				});
 			} catch (DllNotFoundException e) {
-				throw new NotSupportedException ("liblibc not found", e);
+				throw new NotSupportedException ("libc not found", e);
 			}
 		}
 
@@ -121,9 +121,9 @@ namespace Terminal.Gui {
 		public void RemoveWatch (object token)
 		{
 			if (!ConsoleDriver.RunningUnitTests) {
-				var watch = token as Watch;
-				if (watch == null)
+				if (token is not Watch watch) {
 					return;
+				}
 				_descriptorWatchers.Remove (watch.File);
 			}
 		}
@@ -147,33 +147,33 @@ namespace Terminal.Gui {
 
 			var watch = new Watch () { Condition = condition, Callback = callback, File = fileDescriptor };
 			_descriptorWatchers [fileDescriptor] = watch;
-			_poll_dirty = true;
+			_pollDirty = true;
 			return watch;
 		}
 
 		void UpdatePollMap ()
 		{
-			if (!_poll_dirty) {
+			if (!_pollDirty) {
 				return;
 			}
-			_poll_dirty = false;
+			_pollDirty = false;
 
-			_pollmap = new Pollfd [_descriptorWatchers.Count];
-			int i = 0;
+			_pollMap = new Pollfd [_descriptorWatchers.Count];
+			var i = 0;
 			foreach (var fd in _descriptorWatchers.Keys) {
-				_pollmap [i].fd = fd;
-				_pollmap [i].events = (short)_descriptorWatchers [fd].Condition;
+				_pollMap [i].fd = fd;
+				_pollMap [i].events = (short)_descriptorWatchers [fd].Condition;
 				i++;
 			}
 		}
 
-		bool IMainLoopDriver.EventsPending (bool wait)
+		bool IMainLoopDriver.EventsPending ()
 		{
 			UpdatePollMap ();
 
-			bool checkTimersResult = _mainLoop.CheckTimers (wait, out var pollTimeout);
+			var checkTimersResult = _mainLoop.CheckTimersAndIdleHandlers (out var pollTimeout);
 
-			var n = poll (_pollmap, (uint)_pollmap.Length, pollTimeout);
+			var n = poll (_pollMap, (uint)_pollMap.Length, pollTimeout);
 
 			if (n == KEY_RESIZE) {
 				_winChanged = true;
@@ -188,17 +188,20 @@ namespace Terminal.Gui {
 				_winChanged = false;
 				WinChanged?.Invoke ();
 			}
-			if (_pollmap != null) {
-				foreach (var p in _pollmap) {
-					Watch watch;
+			if (_pollMap == null) return;
+			foreach (var p in _pollMap) {
+				Watch watch;
+
+				if (p.revents == 0) {
+					continue;
+				}
 
-					if (p.revents == 0)
-						continue;
+				if (!_descriptorWatchers.TryGetValue (p.fd, out watch)) {
+					continue;
+				}
 
-					if (!_descriptorWatchers.TryGetValue (p.fd, out watch))
-						continue;
-					if (!watch.Callback (this._mainLoop))
-						_descriptorWatchers.Remove (p.fd);
+				if (!watch.Callback (this._mainLoop)) {
+					_descriptorWatchers.Remove (p.fd);
 				}
 			}
 		}

+ 1 - 1
Terminal.Gui/ConsoleDrivers/FakeDriver/FakeMainLoop.cs

@@ -21,7 +21,7 @@ internal class FakeMainLoop : IMainLoopDriver {
 		// No implementation needed for FakeMainLoop
 	}
 
-	public bool EventsPending (bool wait)
+	public bool EventsPending ()
 	{
 		// Always return true for FakeMainLoop
 		return true;

+ 3 - 3
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -1359,11 +1359,11 @@ internal class NetMainLoop : IMainLoopDriver {
 		_keyReady.Set ();
 	}
 
-	bool IMainLoopDriver.EventsPending (bool wait)
+	bool IMainLoopDriver.EventsPending ()
 	{
 		_waitForProbe.Set ();
 
-		if (_mainLoop.CheckTimers (wait, out var waitTimeout)) {
+		if (_mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout)) {
 			return true;
 		}
 
@@ -1378,7 +1378,7 @@ internal class NetMainLoop : IMainLoopDriver {
 		}
 
 		if (!_tokenSource.IsCancellationRequested) {
-			return _inputResult.Count > 0 || _mainLoop.CheckTimers (wait, out _);
+			return _inputResult.Count > 0 || _mainLoop.CheckTimersAndIdleHandlers (out _);
 		}
 
 		_tokenSource.Dispose ();

+ 3 - 3
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1841,11 +1841,11 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		_eventReady.Set ();
 	}
 	
-	bool IMainLoopDriver.EventsPending (bool wait)
+	bool IMainLoopDriver.EventsPending ()
 	{
 		_waitForProbe.Set ();
 		_winChange.Set ();
-		if (_mainLoop.CheckTimers (wait, out var waitTimeout)) {
+		if (_mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout)) {
 			return true;
 		}
 
@@ -1860,7 +1860,7 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		}
 
 		if (!_eventReadyTokenSource.IsCancellationRequested) {
-			return _resultQueue.Count > 0 || _mainLoop.CheckTimers (wait, out _) || _winChanged;
+			return _resultQueue.Count > 0 || _mainLoop.CheckTimersAndIdleHandlers (out _) || _winChanged;
 		}
 
 		_eventReadyTokenSource.Dispose ();

+ 42 - 51
Terminal.Gui/MainLoop.cs

@@ -28,8 +28,7 @@ namespace Terminal.Gui {
 		/// Must report whether there are any events pending, or even block waiting for events.
 		/// </summary>
 		/// <returns><c>true</c>, if there were pending events, <c>false</c> otherwise.</returns>
-		/// <param name="wait">If set to <c>true</c> wait until an event is available, otherwise return immediately.</param>
-		bool EventsPending (bool wait);
+		bool EventsPending ();
 
 		/// <summary>
 		/// The iteration function.
@@ -38,8 +37,7 @@ namespace Terminal.Gui {
 	}
 
 	/// <summary>
-	///   Simple main loop implementation that can be used to monitor
-	///   file descriptor, run timers and idle handlers.
+	///   The MainLoop monitors timers and idle handlers.
 	/// </summary>
 	/// <remarks>
 	///   Monitoring of file descriptors is only available on Unix, there
@@ -48,16 +46,16 @@ namespace Terminal.Gui {
 	public class MainLoop {
 
 		internal SortedList<long, Timeout> _timeouts = new SortedList<long, Timeout> ();
-		object _timeoutsLockToken = new object ();
+		readonly object _timeoutsLockToken = new object ();
 
 		/// <summary>
 		/// The idle handlers and lock that must be held while manipulating them
 		/// </summary>
-		object _idleHandlersLock = new object ();
+		readonly object _idleHandlersLock = new object ();
 		internal List<Func<bool>> _idleHandlers = new List<Func<bool>> ();
 
 		/// <summary>
-		/// Gets the list of all timeouts sorted by the <see cref="TimeSpan"/> time ticks./>.
+		/// Gets the list of all timeouts sorted by the <see cref="TimeSpan"/> time ticks.
 		/// A shorter limit time can be added at the end, but it will be called before an
 		///  earlier addition that has a longer limit time.
 		/// </summary>
@@ -87,9 +85,9 @@ namespace Terminal.Gui {
 		public event EventHandler<TimeoutEventArgs> TimeoutAdded;
 
 		/// <summary>
-		///  Creates a new Mainloop. 
+		///  Creates a new MainLoop. 
 		/// </summary>
-		/// <param name="driver">Should match the <see cref="ConsoleDriver"/> 
+		/// <param name="driver">The <see cref="ConsoleDriver"/> instance
 		/// (one of the implementations FakeMainLoop, UnixMainLoop, NetMainLoop or WindowsMainLoop).</param>
 		public MainLoop (IMainLoopDriver driver)
 		{
@@ -98,7 +96,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Runs <c>action</c> on the thread that is processing events
+		///   Runs <paramref name="action"/> on the thread that is processing events
 		/// </summary>
 		/// <param name="action">the action to be invoked on the main processing thread.</param>
 		public void Invoke (Action action)
@@ -115,10 +113,10 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// <remarks>
 		/// <para>
-		///   Remove an idle hander by calling <see cref="RemoveIdle(Func{bool})"/> with the token this method returns.
+		///   Remove an idle handler by calling <see cref="RemoveIdle(Func{bool})"/> with the token this method returns.
 		/// </para>
 		/// <para>
-		///   If the <c>idleHandler</c> returns <c>false</c> it will be removed and not called subsequently.
+		///   If the <paramref name="idleHandler"/> returns  <see langword="false"/> it will be removed and not called subsequently.
 		/// </para>
 		/// </remarks>
 		/// <param name="idleHandler">Token that can be used to remove the idle handler with <see cref="RemoveIdle(Func{bool})"/> .</param>
@@ -200,7 +198,7 @@ namespace Terminal.Gui {
 
 		void RunTimers ()
 		{
-			long now = DateTime.UtcNow.Ticks;
+			var now = DateTime.UtcNow.Ticks;
 			SortedList<long, Timeout> copy;
 
 			// lock prevents new timeouts being added
@@ -212,9 +210,7 @@ namespace Terminal.Gui {
 				_timeouts = new SortedList<long, Timeout> ();
 			}
 
-			foreach (var t in copy) {
-				var k = t.Key;
-				var timeout = t.Value;
+			foreach ((var k, var timeout) in copy) {
 				if (k < now) {
 					if (timeout.Callback (this)) {
 						AddTimeout (timeout.Span, timeout);
@@ -228,43 +224,36 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Checks if there are any outstanding timers that need to be processed. Called from the driver's <see cref="IMainLoopDriver"/>.
+		/// Called from <see cref="IMainLoopDriver.EventsPending"/> to check if there are any outstanding timers or idle handlers.
 		/// </summary>
-		/// <param name="wait">If <see langword="false"/> <paramref name="waitTimeout"/> will be set to 0.</param>
-		/// <param name="waitTimeout">Returns the number of milliseconds remaining in the current timer.</param>
-		/// <returns></returns>
-		public bool CheckTimers (bool wait, out int waitTimeout)
+		/// <param name="waitTimeout">Returns the number of milliseconds remaining in the current timer (if any).</param>
+		/// <returns><see langword="true"/> if there is a timer or idle handler active.</returns>
+		public bool CheckTimersAndIdleHandlers (out int waitTimeout)
 		{
-			if (wait == false) {
-				throw new InvalidOperationException ("CheckTimers should not be called with wait == false");
-			}
-			
-			long now = DateTime.UtcNow.Ticks;
-
-			if (_timeouts.Count > 0) {
-				waitTimeout = (int)((_timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
-				if (waitTimeout < 0)
-					// This avoids 'poll' waiting infinitely if 'waitTimeout < 0' until some action is detected
-					// This can occur after IMainLoopDriver.Wakeup is executed where the pollTimeout is less than 0
-					// and no event occurred in elapsed time when the 'poll' is start running again.
-					waitTimeout = 0; 
+			var now = DateTime.UtcNow.Ticks;
+
+			waitTimeout = 0;
+
+			lock (_timeouts) {
+				if (_timeouts.Count > 0) {
+					waitTimeout = (int)((_timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
+					if (waitTimeout < 0) {
+						// This avoids 'poll' waiting infinitely if 'waitTimeout < 0' until some action is detected
+						// This can occur after IMainLoopDriver.Wakeup is executed where the pollTimeout is less than 0
+						// and no event occurred in elapsed time when the 'poll' is start running again.
+						waitTimeout = 0;
+					}
 					return true;
-			} else {
-				waitTimeout = -1;
+				}
 			}
 
-			if (!wait) {
-				waitTimeout = 0;
-			}
+			// There are no timers set, check if there are any idle handlers
 
-			int ic;
 			lock (_idleHandlers) {
-				ic = _idleHandlers.Count;
+				return _idleHandlers.Count > 0;
 			}
-
-			return ic > 0;
 		}
-		
+
 		/// <summary>
 		/// Finds the closest number to <paramref name="k"/> that is not
 		/// present in <see cref="_timeouts"/> (incrementally).
@@ -320,9 +309,9 @@ namespace Terminal.Gui {
 		///   Typically used if you need to flush the input queue while still
 		///   running some of your own code in your main thread.
 		/// </remarks>
-		public bool EventsPending (bool wait = false)
+		public bool EventsPending ()
 		{
-			return MainLoopDriver.EventsPending (wait);
+			return MainLoopDriver.EventsPending ();
 		}
 
 		/// <summary>
@@ -337,8 +326,10 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public void RunIteration ()
 		{
-			if (_timeouts.Count > 0) {
-				RunTimers ();
+			lock (_timeouts) {
+				if (_timeouts.Count > 0) {
+					RunTimers ();
+				}
 			}
 
 			MainLoopDriver.Iteration ();
@@ -347,7 +338,7 @@ namespace Terminal.Gui {
 			lock (_idleHandlersLock) {
 				runIdle = _idleHandlers.Count > 0;
 			}
-			
+
 			if (runIdle) {
 				RunIdle ();
 			}
@@ -358,10 +349,10 @@ namespace Terminal.Gui {
 		/// </summary>
 		public void Run ()
 		{
-			bool prev = _running;
+			var prev = _running;
 			_running = true;
 			while (_running) {
-				EventsPending (true);
+				EventsPending ();
 				RunIteration ();
 			}
 			_running = prev;

+ 1 - 1
Terminal.Gui/Views/Toplevel.cs

@@ -33,7 +33,7 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Invoked when the <see cref="Toplevel"/> <see cref="RunState"/> has begun to be loaded.
 		/// A Loaded event handler is a good place to finalize initialization before calling 
-		/// <see cref="Application.RunLoop(RunState, bool)"/>.
+		/// <see cref="Application.RunLoop(RunState)"/>.
 		/// </summary>
 		public event EventHandler Loaded;
 

+ 2 - 1
Terminal.sln.DotSettings

@@ -126,4 +126,5 @@
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/UserDictionary/Words/=Toplevel/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 5 - 33
UnitTests/Application/MainLoopTests.cs

@@ -506,39 +506,11 @@ namespace Terminal.Gui.ApplicationTests {
 		public void CheckTimer_NoTimers_Wait_True_Returns_False ()
 		{
 			var ml = new MainLoop (new FakeMainLoop ());
-			var retVal = ml.CheckTimers (true, out var waitTimeOut);
+			var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut);
 			Assert.False (retVal);
-			Assert.Equal (-1, waitTimeOut);
+			Assert.Equal (0, waitTimeOut);
 		}
 
-		//[Fact]
-		//public void CheckTimer_NoTimers_Wait_False_Returns_False ()
-		//{
-		//	var ml = new MainLoop (new FakeMainLoop ());
-		//	var retVal = ml.CheckTimers (true, out var waitTimeOut);
-		//	Assert.False (retVal);
-		//	Assert.Equal (-1, waitTimeOut);
-		//}
-
-		//[Fact]
-		//public void CheckTimer_WithTimer_Wait_False_Returns_0 ()
-		//{
-		//	var ml = new MainLoop (new FakeMainLoop ());
-		//	var ms = TimeSpan.FromMilliseconds (50);
-
-		//	var callbackCount = 0;
-		//	Func<MainLoop, bool> callback = (loop) => {
-		//		callbackCount++;
-		//		return false;
-		//	};
-
-		//	var token = ml.AddTimeout (ms, callback);
-		//	var retVal = ml.CheckTimers (false, out var waitTimeOut);
-
-		//	Assert.True (retVal);
-		//	Assert.Equal (0, waitTimeOut);
-		//}
-
 		[Fact]
 		public void CheckTimer_With1Timer_Wait_True_Returns_Timer ()
 		{
@@ -552,7 +524,7 @@ namespace Terminal.Gui.ApplicationTests {
 			};
 
 			var token = ml.AddTimeout (ms, callback);
-			var retVal = ml.CheckTimers (true, out var waitTimeOut);
+			var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut);
 
 			Assert.True (retVal);
 			// It should take < 10ms to execute to here
@@ -573,7 +545,7 @@ namespace Terminal.Gui.ApplicationTests {
 
 			var token1 = ml.AddTimeout (ms, callback);
 			var token2 = ml.AddTimeout (ms, callback);
-			var retVal = ml.CheckTimers (true, out var waitTimeOut);
+			var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut);
 
 			Assert.True (retVal);
 			// It should take < 10ms to execute to here
@@ -596,7 +568,7 @@ namespace Terminal.Gui.ApplicationTests {
 		private class TestMainloop : IMainLoopDriver {
 			private MainLoop mainLoop;
 
-			public bool EventsPending (bool wait)
+			public bool EventsPending ()
 			{
 				throw new NotImplementedException ();
 			}

+ 8 - 8
UnitTests/Dialogs/DialogTests.cs

@@ -352,7 +352,7 @@ namespace Terminal.Gui.DialogTests {
 			button2 = new Button (btn2Text);
 			(runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, button1, button2);
 			button1.Visible = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 			buttonRow = $@"{CM.Glyphs.VLine}         {btn2} {CM.Glyphs.VLine}";
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
@@ -363,7 +363,7 @@ namespace Terminal.Gui.DialogTests {
 			button2 = new Button (btn2Text);
 			(runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Justify, button1, button2);
 			button1.Visible = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 			buttonRow = $@"{CM.Glyphs.VLine}          {btn2}{CM.Glyphs.VLine}";
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
@@ -374,7 +374,7 @@ namespace Terminal.Gui.DialogTests {
 			button2 = new Button (btn2Text);
 			(runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Right, button1, button2);
 			button1.Visible = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
 
@@ -384,7 +384,7 @@ namespace Terminal.Gui.DialogTests {
 			button2 = new Button (btn2Text);
 			(runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Left, button1, button2);
 			button1.Visible = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 			buttonRow = $@"{CM.Glyphs.VLine}        {btn2}  {CM.Glyphs.VLine}";
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
@@ -713,7 +713,7 @@ namespace Terminal.Gui.DialogTests {
 			buttonRow = $"{CM.Glyphs.VLine} {btn1} {btn2} {CM.Glyphs.VLine}";
 			dlg.AddButton (new Button (btn2Text));
 			bool first = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref first);
+			Application.RunMainLoopIteration (ref runstate, ref first);
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
 
@@ -729,7 +729,7 @@ namespace Terminal.Gui.DialogTests {
 			buttonRow = $"{CM.Glyphs.VLine}{btn1}   {btn2}{CM.Glyphs.VLine}";
 			dlg.AddButton (new Button (btn2Text));
 			first = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref first);
+			Application.RunMainLoopIteration (ref runstate, ref first);
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
 
@@ -745,7 +745,7 @@ namespace Terminal.Gui.DialogTests {
 			buttonRow = $"{CM.Glyphs.VLine}  {btn1} {btn2}{CM.Glyphs.VLine}";
 			dlg.AddButton (new Button (btn2Text));
 			first = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref first);
+			Application.RunMainLoopIteration (ref runstate, ref first);
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
 
@@ -761,7 +761,7 @@ namespace Terminal.Gui.DialogTests {
 			buttonRow = $"{CM.Glyphs.VLine}{btn1} {btn2}  {CM.Glyphs.VLine}";
 			dlg.AddButton (new Button (btn2Text));
 			first = false;
-			Application.RunMainLoopIteration (ref runstate, true, ref first);
+			Application.RunMainLoopIteration (ref runstate, ref first);
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
 			Application.End (runstate);
 		}

+ 5 - 5
UnitTests/Dialogs/WizardTests.cs

@@ -163,7 +163,7 @@ namespace Terminal.Gui.DialogTests {
 			//wizard.LayoutSubviews ();
 			var firstIteration = false;
 			var runstate = Application.Begin (wizard);
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{topRow}\n{row2}\n{row3}\n{row4}\n{separatorRow}\n{buttonRow}\n{bottomRow}", output);
 			Application.End (runstate);
@@ -530,10 +530,10 @@ namespace Terminal.Gui.DialogTests {
 
 			var runstate = Application.Begin (wizard);
 			var firstIteration = true;
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 
 			wizard.NextFinishButton.OnClicked ();
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 			Application.End (runstate);
 			Assert.True (finishedFired);
 			Assert.True (closedFired);
@@ -559,7 +559,7 @@ namespace Terminal.Gui.DialogTests {
 			};
 
 			runstate = Application.Begin (wizard);
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 
 			Assert.Equal (step1.Title, wizard.CurrentStep.Title);
 			wizard.NextFinishButton.OnClicked ();
@@ -597,7 +597,7 @@ namespace Terminal.Gui.DialogTests {
 			};
 
 			runstate = Application.Begin (wizard);
-			Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref runstate, ref firstIteration);
 
 			Assert.Equal (step2.Title, wizard.CurrentStep.Title);
 			Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);

+ 8 - 8
UnitTests/View/FrameTests.cs

@@ -61,7 +61,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (20, height);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (height) {
@@ -119,7 +119,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (width, 3);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (width) {
@@ -210,7 +210,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (3, 3);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = @"
 ┌─┐
 │ │
@@ -234,7 +234,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (5, 5);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = @"
 ╔═══╗
 ║┌─┐║
@@ -262,7 +262,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (10, 4);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = @"
 ╔════════╗
 ║┌┤1234├┐║
@@ -299,7 +299,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (width, 4);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (width) {
@@ -411,7 +411,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (width, 4);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (width) {
@@ -523,7 +523,7 @@ namespace Terminal.Gui.ViewTests {
 			bool firstIteration = false;
 
 			((FakeDriver)Application.Driver).SetBufferSize (width, 5);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (width) {

+ 4 - 4
UnitTests/View/Layout/LayoutTests.cs

@@ -1396,7 +1396,7 @@ Y
 
 			view1.Frame = new Rect (0, 0, 25, 4);
 			bool firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 
 			Assert.True (view1.AutoSize);
 			Assert.Equal (LayoutStyle.Absolute, view1.LayoutStyle);
@@ -1407,7 +1407,7 @@ Y
 			Assert.Equal ("Absolute(1)", view1.Height.ToString ());
 
 			view2.Frame = new Rect (0, 0, 1, 25);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 
 			Assert.True (view2.AutoSize);
 			Assert.Equal (LayoutStyle.Absolute, view2.LayoutStyle);
@@ -1598,7 +1598,7 @@ Y
 
 
 			((FakeDriver)Application.Driver).SetBufferSize (20, height);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (height) {
@@ -1736,7 +1736,7 @@ Y
 
 
 			((FakeDriver)Application.Driver).SetBufferSize (width, 7);
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			var expected = string.Empty;
 
 			switch (width) {

+ 1 - 1
UnitTests/View/ViewTests.cs

@@ -846,7 +846,7 @@ namespace Terminal.Gui.ViewTests {
 			label.Visible = false;
 
 			bool firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌────────────────────────────┐
 │                            │

+ 3 - 3
UnitTests/Views/CheckBoxTests.cs

@@ -125,7 +125,7 @@ namespace Terminal.Gui.ViewsTests {
 			//checkBox.AutoSize = false;
 			// It isn't auto-size so the height is guaranteed by the SetMinWidthHeight
 			//checkBox.Text = "Check this out 你 changed";
-			//Application.RunMainLoopIteration (ref runstate, true, ref first);
+			//Application.RunMainLoopIteration (ref runstate, ref first);
 			// BUGBUG - v2 - Autosize is busted; disabling tests for now
 //			Assert.Equal (new Rect (1, 1, 19, 1), checkBox.Frame);
 //			expected = @"
@@ -142,7 +142,7 @@ namespace Terminal.Gui.ViewsTests {
 //			checkBox.Width = 19;
 //			// It isn't auto-size so the height is guaranteed by the SetMinWidthHeight
 //			checkBox.Text = "Check this out 你 changed";
-//			Application.RunMainLoopIteration (ref runstate, true, ref first);
+//			Application.RunMainLoopIteration (ref runstate, ref first);
 //			Assert.False (checkBox.AutoSize);
 //			Assert.Equal (new Rect (1, 1, 19, 1), checkBox.Frame);
 //			expected = @"
@@ -157,7 +157,7 @@ namespace Terminal.Gui.ViewsTests {
 //			Assert.Equal (new Rect (0, 0, 30, 5), pos);
 
 //			checkBox.AutoSize = true;
-//			Application.RunMainLoopIteration (ref runstate, true, ref first);
+//			Application.RunMainLoopIteration (ref runstate, ref first);
 //			Assert.Equal (new Rect (1, 1, 27, 1), checkBox.Frame);
 //			expected = @"
 //┌┤Test Demo 你├──────────────┐

+ 5 - 5
UnitTests/Views/ContextMenuTests.cs

@@ -967,7 +967,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 │                  │
@@ -1018,7 +1018,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
   ┌─────────────┐   
   │ Test        │   
@@ -1062,7 +1062,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
     Test            
 ┌───────────────────
@@ -1113,7 +1113,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (new Rect (5, 11, 10, 5), Application.Top.Subviews [0].Frame);
 			Assert.Equal (new Rect (5, 11, 15, 6), Application.Top.Subviews [1].Frame);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1134,7 +1134,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (new Rect (5, 11, 10, 5), Application.Top.Subviews [0].Frame);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
      ┌────────┐

+ 10 - 10
UnitTests/Views/MenuTests.cs

@@ -2376,7 +2376,7 @@ wo
 			Assert.Equal ("File", menu.Menus [0].Title);
 			menu.OpenMenu ();
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────────────────────────┐
 │                                      │
@@ -2404,7 +2404,7 @@ wo
 				});
 
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (items [0], menu.Menus [0].Title);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────────────────────────┐
@@ -2436,14 +2436,14 @@ wo
 					});
 
 				firstIteration = false;
-				Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+				Application.RunMainLoopIteration (ref rs, ref firstIteration);
 				Assert.Equal (items [i], menu.Menus [0].Title);
 			}
 
 			((FakeDriver)Application.Driver).SetBufferSize (20, 15);
 			menu.OpenMenu ();
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
 ┌──────────────────┐
 │                  │
@@ -2505,7 +2505,7 @@ wo
 			Assert.Equal ("File", menu.Menus [0].Title);
 			menu.OpenMenu ();
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
   ┌─────────────┐                       
   │  File       │                       
@@ -2528,7 +2528,7 @@ wo
 				});
 
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (items [0], menu.Menus [0].Title);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
   ┌─────────────┐
@@ -2549,14 +2549,14 @@ wo
 					});
 
 				firstIteration = false;
-				Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+				Application.RunMainLoopIteration (ref rs, ref firstIteration);
 				Assert.Equal (items [i], menu.Menus [0].Title);
 			}
 
 			((FakeDriver)Application.Driver).SetBufferSize (20, 15);
 			menu.OpenMenu ();
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
   ┌─────────────┐   
   │  Delete     │   
@@ -2585,7 +2585,7 @@ wo
 
 			menu.OpenMenu ();
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
  File                         
 ┌────────────────────────────┐
@@ -2594,7 +2594,7 @@ wo
 
 			((FakeDriver)Application.Driver).SetBufferSize (20, 15);
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
  File", output);
 

+ 3 - 3
UnitTests/Views/ToplevelTests.cs

@@ -1416,7 +1416,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (dialog, Application.MouseGrabView);
 
 			Assert.Equal (new Rect (25, 7, 30, 10), dialog.Frame);
@@ -1442,7 +1442,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			Assert.Equal (dialog, Application.MouseGrabView);
 			Assert.Equal (new Rect (20, 10, 30, 10), dialog.Frame);
 			TestHelpers.AssertDriverContentsWithFrameAre (@"
@@ -1560,7 +1560,7 @@ namespace Terminal.Gui.ViewsTests {
 				});
 
 			var firstIteration = false;
-			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+			Application.RunMainLoopIteration (ref rs, ref firstIteration);
 			TestHelpers.AssertDriverContentsWithFrameAre (@$"
 ┌──────────────────┐
 │                  │