Browse Source

Fix NetDriver read key issue.

BDisp 10 months ago
parent
commit
8d52fe731f

+ 29 - 9
Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequest.cs

@@ -18,19 +18,31 @@ public class AnsiEscapeSequenceRequest
         var response = new StringBuilder ();
         var error = new StringBuilder ();
         var savedIsReportingMouseMoves = false;
+        NetDriver? netDriver = null;
 
         try
         {
             switch (Application.Driver)
             {
-                case NetDriver netDriver:
-                    savedIsReportingMouseMoves = netDriver.IsReportingMouseMoves;
+                case NetDriver:
+                    netDriver = Application.Driver as NetDriver;
+                    savedIsReportingMouseMoves = netDriver!.IsReportingMouseMoves;
 
                     if (savedIsReportingMouseMoves)
                     {
                         netDriver.StopReportingMouseMoves ();
                     }
 
+                    while (Console.KeyAvailable)
+                    {
+                        netDriver._mainLoopDriver._netEvents._waitForStart.Set ();
+                        netDriver._mainLoopDriver._netEvents._waitForStart.Reset ();
+
+                        netDriver._mainLoopDriver._netEvents._forceRead = true;
+                    }
+
+                    netDriver._mainLoopDriver._netEvents._forceRead = false;
+
                     break;
                 case CursesDriver cursesDriver:
                     savedIsReportingMouseMoves = cursesDriver.IsReportingMouseMoves;
@@ -43,12 +55,19 @@ public class AnsiEscapeSequenceRequest
                     break;
             }
 
-            Thread.Sleep (100); // Allow time for mouse stopping and to flush the input buffer
-
-            // Flush the input buffer to avoid reading stale input
-            while (Console.KeyAvailable)
+            if (netDriver is { })
+            {
+                NetEvents._suspendRead = true;
+            }
+            else
             {
-                Console.ReadKey (true);
+                Thread.Sleep (100); // Allow time for mouse stopping and to flush the input buffer
+
+                // Flush the input buffer to avoid reading stale input
+                while (Console.KeyAvailable)
+                {
+                    Console.ReadKey (true);
+                }
             }
 
             // Send the ANSI escape sequence
@@ -89,8 +108,9 @@ public class AnsiEscapeSequenceRequest
             {
                 switch (Application.Driver)
                 {
-                    case NetDriver netDriver:
-                        netDriver.StartReportingMouseMoves ();
+                    case NetDriver:
+                        NetEvents._suspendRead = false;
+                        netDriver!.StartReportingMouseMoves ();
 
                         break;
                     case CursesDriver cursesDriver:

+ 8 - 5
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -136,7 +136,7 @@ internal class NetEvents : IDisposable
 {
     private readonly ManualResetEventSlim _inputReady = new (false);
     private CancellationTokenSource _inputReadyCancellationTokenSource;
-    private readonly ManualResetEventSlim _waitForStart = new (false);
+    internal readonly ManualResetEventSlim _waitForStart = new (false);
 
     //CancellationTokenSource _waitForStartCancellationTokenSource;
     private readonly ManualResetEventSlim _winChange = new (false);
@@ -202,7 +202,7 @@ internal class NetEvents : IDisposable
     {
         // if there is a key available, return it without waiting
         //  (or dispatching work to the thread queue)
-        if (Console.KeyAvailable)
+        if (Console.KeyAvailable && !_suspendRead)
         {
             return Console.ReadKey (intercept);
         }
@@ -211,7 +211,7 @@ internal class NetEvents : IDisposable
         {
             Task.Delay (100, cancellationToken).Wait (cancellationToken);
 
-            if (Console.KeyAvailable)
+            if (Console.KeyAvailable && !_suspendRead)
             {
                 return Console.ReadKey (intercept);
             }
@@ -222,6 +222,9 @@ internal class NetEvents : IDisposable
         return default (ConsoleKeyInfo);
     }
 
+    internal bool _forceRead;
+    internal static bool _suspendRead;
+
     private void ProcessInputQueue ()
     {
         while (_inputReadyCancellationTokenSource is { IsCancellationRequested: false })
@@ -237,7 +240,7 @@ internal class NetEvents : IDisposable
 
             _waitForStart.Reset ();
 
-            if (_inputQueue.Count == 0)
+            if (_inputQueue.Count == 0 || _forceRead)
             {
                 ConsoleKey key = 0;
                 ConsoleModifiers mod = 0;
@@ -812,7 +815,7 @@ internal class NetDriver : ConsoleDriver
     private const int COLOR_RED = 31;
     private const int COLOR_WHITE = 37;
     private const int COLOR_YELLOW = 33;
-    private NetMainLoop _mainLoopDriver;
+    internal NetMainLoop _mainLoopDriver;
     public bool IsWinPlatform { get; private set; }
     public NetWinVTConsole NetWinConsole { get; private set; }