Support for remapping basic unicode keychars that come from OS with ConsoleKey.Packet. Affects only WindowsDriver

This commit is contained in:
Thomas
2022-09-17 13:26:47 +01:00
parent 0321b25b0e
commit 9897bb903e
2 changed files with 61 additions and 0 deletions

View File

@@ -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 ()
{
}
/// <summary>
/// Handles case when the 'key' providied is ConsoleKey.Packet by
/// returning a new <see cref="ConsoleKeyInfo"/> where key is remapped
/// by parsing the Unicode char data of the <see cref="ConsoleKeyInfo"/>
/// </summary>
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<ConsoleKey>(
// 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
}

View File

@@ -608,5 +608,29 @@ namespace Terminal.Gui.ConsoleDrivers {
Application.Run (win);
Application.Shutdown ();
}
/// <summary>
/// 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
/// </summary>
[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);
}
}
}