diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 21b7a6094..e9383b9a4 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1244,6 +1244,9 @@ namespace Terminal.Gui { keyModifiers.Scrolllock = scrolllock; var ConsoleKeyInfo = new ConsoleKeyInfo (keyEvent.UnicodeChar, (ConsoleKey)keyEvent.wVirtualKeyCode, shift, alt, control); + + ConsoleKeyInfo = RemapPacketKey(ConsoleKeyInfo); + return new WindowsConsole.ConsoleKeyInfoEx (ConsoleKeyInfo, capslock, numlock); } @@ -1757,6 +1760,40 @@ namespace Terminal.Gui { public override void CookMouse () { } + + + /// + /// Handles case when the 'key' providied is ConsoleKey.Packet by + /// returning a new where key is remapped + /// by parsing the Unicode char data of the + /// + internal static ConsoleKeyInfo RemapPacketKey (ConsoleKeyInfo original) + { + // If the key struck was virtual + if(original.Key == ConsoleKey.Packet) + { + // Try to parse the unicode key e.g. 'A' into a value in ConsoleKey + // so that other parts of the program consider it as a regular button + // press + ConsoleKey remappedkey; + if(Enum.TryParse( + // have to turn e.g. 'a' to something parseable as + // an enum value (i.e. Upper it) + original.KeyChar.ToString().ToUpper(), + out remappedkey)) + { + return new ConsoleKeyInfo( + original.KeyChar, + remappedkey, + original.Modifiers.HasFlag(ConsoleModifiers.Shift), + original.Modifiers.HasFlag(ConsoleModifiers.Alt), + original.Modifiers.HasFlag(ConsoleModifiers.Control) + ); + } + } + + return original; + } #endregion } diff --git a/UnitTests/ConsoleDriverTests.cs b/UnitTests/ConsoleDriverTests.cs index cb4bc1dcf..4981f30b6 100644 --- a/UnitTests/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDriverTests.cs @@ -608,5 +608,29 @@ namespace Terminal.Gui.ConsoleDrivers { Application.Run (win); Application.Shutdown (); } + + /// + /// Sometimes when using remoting tools EventKeyRecord sends 'virtual keystrokes'. + /// These are indicated with the wVirtualKeyCode of 231. When we see this code + /// then we need to look to the unicode character (UnicodeChar) instead of the key + /// when telling the rest of the framework what button was pressed. For full details + /// see: https://github.com/gui-cs/Terminal.Gui/issues/2008 + /// + [Theory] + [InlineData('A',true,false,false,ConsoleKey.A)] + [InlineData('z',false,false,false,ConsoleKey.Z)] + public void TestVKPacket(char unicodeCharacter,bool shift, bool alt, bool control, ConsoleKey expectedRemapping) + { + var before = new ConsoleKeyInfo(unicodeCharacter,ConsoleKey.Packet,shift,alt,control); + var after = WindowsDriver.RemapPacketKey(before); + + Assert.Equal(before.KeyChar, after.KeyChar); + + // The thing we are really interested in, did we correctly convert + // the input ConsoleKey.Packet to the correct physical key + Assert.Equal(expectedRemapping,after.Key); + + Assert.Equal(after.Modifiers,before.Modifiers); + } } }