瀏覽代碼

Merge pull request #3386 from BDisp/v2_WindowsDriver-input-fix_3380

Fixes #3380. WindowsDriver is sending mouse button pressed only on moving.
Tig 1 年之前
父節點
當前提交
ef6e22c7a2
共有 1 個文件被更改,包括 48 次插入20 次删除
  1. 48 20
      Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

+ 48 - 20
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)