From 67b28925ccab546abe8905f27a84b29da56e8821 Mon Sep 17 00:00:00 2001 From: tznind Date: Sun, 13 Oct 2024 10:42:34 +0100 Subject: [PATCH] Change WindowsDriver to send down/up on key down and ignore key up events from win 32 api --- .../ConsoleDrivers/AnsiResponseParser.cs | 2 +- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 47 ++++-------- .../ConsoleDrivers/WindowsDriverKeyPairer.cs | 74 ------------------- 3 files changed, 14 insertions(+), 109 deletions(-) delete mode 100644 Terminal.Gui/ConsoleDrivers/WindowsDriverKeyPairer.cs diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs index e16374c74..5625f4a5a 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs @@ -246,7 +246,7 @@ namespace Terminal.Gui; public IEnumerable> Release () { - foreach (var h in held) + foreach (var h in held.ToArray ()) { yield return h; } diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 3bffdf9b2..6850749ce 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/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 /// private TimeSpan _escTimeout = TimeSpan.FromMilliseconds (50); - public AnsiResponseParser Parser { get; set; } = new (); + public AnsiResponseParser Parser { get; set; } = new (); internal void ProcessInput (WindowsConsole.InputRecord inputEvent) { @@ -1493,15 +1493,9 @@ internal class WindowsDriver : ConsoleDriver 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; @@ -1543,7 +1537,6 @@ internal class WindowsDriver : ConsoleDriver } } - private WindowsDriverKeyPairer pairer = new WindowsDriverKeyPairer (); private IEnumerable Parse (WindowsConsole.InputRecord inputEvent) { if (inputEvent.EventType != WindowsConsole.EventType.Key) @@ -1552,36 +1545,22 @@ internal class WindowsDriver : ConsoleDriver 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 ()) { yield return i; } - foreach (var p in pair) + foreach (Tuple 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 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 ShouldRelease () @@ -1590,7 +1569,7 @@ internal class WindowsDriver : ConsoleDriver if (Parser.State == ParserState.ExpectingBracket && DateTime.Now - Parser.StateChangedAt > _escTimeout) { - return Parser.Release ().SelectMany (o => o.Item2); + return Parser.Release ().Select (o => o.Item2); } return []; diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriverKeyPairer.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriverKeyPairer.cs deleted file mode 100644 index b86feaba0..000000000 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriverKeyPairer.cs +++ /dev/null @@ -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 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 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 (); - } - - private IEnumerable 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; - } -}