Browse Source

Change WindowsDriver to send down/up on key down and ignore key up events from win 32 api

tznind 9 months ago
parent
commit
67b28925cc

+ 1 - 1
Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs

@@ -246,7 +246,7 @@ namespace Terminal.Gui;
 
 
         public IEnumerable<Tuple<char, T>> Release ()
         public IEnumerable<Tuple<char, T>> Release ()
         {
         {
-            foreach (var h in held)
+            foreach (var h in held.ToArray ())
             {
             {
                 yield return h;
                 yield return h;
             }
             }

+ 13 - 34
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1458,7 +1458,7 @@ internal class WindowsDriver : ConsoleDriver
     /// How long after Esc has been pressed before we give up on getting an Ansi escape sequence
     /// How long after Esc has been pressed before we give up on getting an Ansi escape sequence
     /// </summary>
     /// </summary>
     private TimeSpan _escTimeout = TimeSpan.FromMilliseconds (50);
     private TimeSpan _escTimeout = TimeSpan.FromMilliseconds (50);
-    public AnsiResponseParser<WindowsConsole.InputRecord []> Parser { get; set; } = new ();
+    public AnsiResponseParser<WindowsConsole.InputRecord> Parser { get; set; } = new ();
 
 
     internal void ProcessInput (WindowsConsole.InputRecord inputEvent)
     internal void ProcessInput (WindowsConsole.InputRecord inputEvent)
     {
     {
@@ -1493,15 +1493,9 @@ internal class WindowsDriver : ConsoleDriver
                     break;
                     break;
                 }
                 }
 
 
-                if (inputEvent.KeyEvent.bKeyDown)
-                {
-                    // Avoid sending repeat key down events
-                    OnKeyDown (new Key (map));
-                }
-                else
-                {
-                    OnKeyUp (new Key (map));
-                }
+                // This follows convention in NetDriver
+                OnKeyDown (new Key (map));
+                OnKeyUp (new Key (map));
 
 
                 break;
                 break;
 
 
@@ -1543,7 +1537,6 @@ internal class WindowsDriver : ConsoleDriver
         }
         }
     }
     }
 
 
-    private WindowsDriverKeyPairer pairer = new WindowsDriverKeyPairer ();
     private IEnumerable<WindowsConsole.InputRecord> Parse (WindowsConsole.InputRecord inputEvent)
     private IEnumerable<WindowsConsole.InputRecord> Parse (WindowsConsole.InputRecord inputEvent)
     {
     {
         if (inputEvent.EventType != WindowsConsole.EventType.Key)
         if (inputEvent.EventType != WindowsConsole.EventType.Key)
@@ -1552,36 +1545,22 @@ internal class WindowsDriver : ConsoleDriver
             yield break;
             yield break;
         }
         }
 
 
-        var pair = pairer.ProcessInput (inputEvent).ToArray ();
+        // Swallow key up events - they are unreliable
+        if (!inputEvent.KeyEvent.bKeyDown)
+        {
+            yield break;
+        }
 
 
         foreach (var i in ShouldRelease ())
         foreach (var i in ShouldRelease ())
         {
         {
             yield return i;
             yield return i;
         }
         }
 
 
-        foreach (var p in pair)
+        foreach (Tuple<char, WindowsConsole.InputRecord> output in
+                 Parser.ProcessInput (Tuple.Create (inputEvent.KeyEvent.UnicodeChar, inputEvent)))
         {
         {
-            // may be down/up
-            if (p.Length == 2)
-            {
-                var c = p [0].KeyEvent.UnicodeChar;
-                foreach (Tuple<char, WindowsConsole.InputRecord []> output in
-                         Parser.ProcessInput (Tuple.Create(c,p)))
-                {
-                    foreach (var r in output.Item2)
-                    {
-                        yield return r;
-                    }
-                }
-            }
-            else
-            {
-                // environment doesn't support down/up
-
-                // TODO: what we do in this situation?
-            }
+                yield return output.Item2;
         }
         }
-
     }
     }
 
 
     public IEnumerable<WindowsConsole.InputRecord> ShouldRelease ()
     public IEnumerable<WindowsConsole.InputRecord> ShouldRelease ()
@@ -1590,7 +1569,7 @@ internal class WindowsDriver : ConsoleDriver
         if (Parser.State == ParserState.ExpectingBracket &&
         if (Parser.State == ParserState.ExpectingBracket &&
             DateTime.Now - Parser.StateChangedAt > _escTimeout)
             DateTime.Now - Parser.StateChangedAt > _escTimeout)
         {
         {
-            return Parser.Release ().SelectMany (o => o.Item2);
+            return Parser.Release ().Select (o => o.Item2);
         }
         }
 
 
         return [];
         return [];

+ 0 - 74
Terminal.Gui/ConsoleDrivers/WindowsDriverKeyPairer.cs

@@ -1,74 +0,0 @@
-using static Terminal.Gui.WindowsConsole;
-
-namespace Terminal.Gui.ConsoleDrivers;
-class WindowsDriverKeyPairer
-{
-    private InputRecord? _heldDownEvent = null; // To hold the "down" event
-
-    // Process a single input record at a time
-    public IEnumerable<InputRecord []> ProcessInput (InputRecord record)
-    {
-        // If it's a "down" event, store it as a held event
-        if (IsKeyDown (record))
-        {
-            return HandleKeyDown (record);
-        }
-        // If it's an "up" event, try to match it with the held "down" event
-        else if (IsKeyUp (record))
-        {
-            return HandleKeyUp (record);
-        }
-        else
-        {
-            // If it's not a key event, just pass it through
-            return new [] { new [] { record } };
-        }
-    }
-
-    private IEnumerable<InputRecord []> HandleKeyDown (InputRecord record)
-    {
-        // If we already have a held "down" event, release it (unmatched)
-        if (_heldDownEvent != null)
-        {
-            // Release the previous "down" event since there's a new "down"
-            var previousDown = _heldDownEvent.Value;
-            _heldDownEvent = record; // Hold the new "down" event
-            return new [] { new [] { previousDown } };
-        }
-
-        // Hold the new "down" event
-        _heldDownEvent = record;
-        return Enumerable.Empty<InputRecord []> ();
-    }
-
-    private IEnumerable<InputRecord []> HandleKeyUp (InputRecord record)
-    {
-        // If we have a held "down" event that matches this "up" event, release both
-        if (_heldDownEvent != null && IsMatchingKey (record, _heldDownEvent.Value))
-        {
-            var downEvent = _heldDownEvent.Value;
-            _heldDownEvent = null; // Clear the held event
-            return new [] { new [] { downEvent, record } };
-        }
-        else
-        {
-            // No match, release the "up" event by itself
-            return new [] { new [] { record } };
-        }
-    }
-
-    private bool IsKeyDown (InputRecord record)
-    {
-        return record.KeyEvent.bKeyDown;
-    }
-
-    private bool IsKeyUp (InputRecord record)
-    {
-        return !record.KeyEvent.bKeyDown;
-    }
-
-    private bool IsMatchingKey (InputRecord upEvent, InputRecord downEvent)
-    {
-        return upEvent.KeyEvent.UnicodeChar == downEvent.KeyEvent.UnicodeChar;
-    }
-}