diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 9742d2591..e0f854dcf 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -838,6 +838,29 @@ internal class WindowsConsole [DllImport ("kernel32.dll", SetLastError = true)] private static extern bool GetNumberOfConsoleInputEvents (nint handle, out uint lpcNumberOfEvents); + internal uint GetNumberOfConsoleInputEvents () + { + if (!GetNumberOfConsoleInputEvents (_inputHandle, out uint numOfEvents)) + { + Console.WriteLine ($"Error: {Marshal.GetLastWin32Error ()}"); + + return 0; + } + + return numOfEvents; + } + + [DllImport ("kernel32.dll", SetLastError = true)] + private static extern bool FlushConsoleInputBuffer (nint handle); + + internal void FlushConsoleInputBuffer () + { + if (!FlushConsoleInputBuffer (_inputHandle)) + { + Console.WriteLine ($"Error: {Marshal.GetLastWin32Error ()}"); + } + } + public InputRecord [] ReadConsoleInput () { const int bufferSize = 1; @@ -1281,7 +1304,7 @@ internal class WindowsDriver : ConsoleDriver { #if HACK_CHECK_WINCHANGED - //_mainLoop.WinChanged -= ChangeWin; + _mainLoopDriver.WinChanged -= ChangeWin; #endif } @@ -1698,7 +1721,7 @@ internal class WindowsDriver : ConsoleDriver private async Task ProcessButtonDoubleClickedAsync () { - await Task.Delay (300); + await Task.Delay (200); _isButtonDoubleClicked = false; _isOneFingerDoubleClicked = false; @@ -2130,34 +2153,32 @@ internal class WindowsMainLoop : IMainLoopDriver void IMainLoopDriver.TearDown () { - // Eat any outstanding events. See # - //var records = - _winConsole.ReadConsoleInput (); - - //if (records != null) - //{ - // foreach (var rec in records) - // { - // Debug.WriteLine ($"Teardown: {rec.ToString ()}"); - // //Debug.Assert (rec is not { EventType: WindowsConsole.EventType.Mouse, MouseEvent.ButtonState: WindowsConsole.ButtonState.Button1Pressed }); - // } - //} - _inputHandlerTokenSource?.Cancel (); _inputHandlerTokenSource?.Dispose (); + if (_winConsole is { }) + { + var numOfEvents = _winConsole.GetNumberOfConsoleInputEvents (); + + if (numOfEvents > 0) + { + _winConsole.FlushConsoleInputBuffer (); + //Debug.WriteLine ($"Flushed {numOfEvents} events."); + } + } + + _waitForProbe?.Dispose (); + + _resultQueue?.Clear (); + _eventReadyTokenSource?.Cancel (); _eventReadyTokenSource?.Dispose (); _eventReady?.Dispose (); - _resultQueue?.Clear (); - #if HACK_CHECK_WINCHANGED _winChange?.Dispose (); #endif - //_waitForProbe?.Dispose (); - _mainLoop = null; } @@ -2174,11 +2195,18 @@ internal class WindowsMainLoop : IMainLoopDriver } catch (OperationCanceledException) { + // Wakes the _waitForProbe if it's waiting + _waitForProbe.Set (); return; } finally { - _waitForProbe.Reset (); + // If IsCancellationRequested is true the code after + // the `finally` block will not be executed. + if (!_inputHandlerTokenSource.IsCancellationRequested) + { + _waitForProbe.Reset (); + } } if (_resultQueue?.Count == 0)