Browse Source

Fixes #3807. WindowsDriver doesn't process characters with accents.

BDisp 9 months ago
parent
commit
2e0bc0162d

+ 3 - 2
Terminal.Gui/ConsoleDrivers/ConsoleKeyMapping.cs

@@ -249,7 +249,7 @@ public static class ConsoleKeyMapping
     {
         var modifiers = new ConsoleModifiers ();
 
-        if (key.HasFlag (KeyCode.ShiftMask))
+        if (key.HasFlag (KeyCode.ShiftMask) || char.IsUpper ((char)key))
         {
             modifiers |= ConsoleModifiers.Shift;
         }
@@ -590,7 +590,8 @@ public static class ConsoleKeyMapping
 
                 if (uc != UnicodeCategory.NonSpacingMark && uc != UnicodeCategory.OtherLetter)
                 {
-                    consoleKey = char.ToUpper (stFormD [i]);
+                    char ck = char.ToUpper (stFormD [i]);
+                    consoleKey = (uint)(ck > 0 && ck <= 255 ? char.ToUpper (stFormD [i]) : 0);
                     scode = GetScanCode ("VirtualKey", char.ToUpper (stFormD [i]), 0);
 
                     if (scode is { })

+ 4 - 3
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1891,12 +1891,13 @@ internal class WindowsDriver : ConsoleDriver
                 // If (ShiftMask is on and CapsLock is off) or (ShiftMask is off and CapsLock is on) add the ShiftMask
                 if (char.IsUpper (keyInfo.KeyChar))
                 {
-                    return (KeyCode)(uint)keyInfo.Key | KeyCode.ShiftMask;
+                    // Always return the KeyChar because it may be an À, À with Oem1, etc
+                    return (KeyCode)keyInfo.KeyChar | KeyCode.ShiftMask;
                 }
             }
 
-            // Return the Key (not KeyChar!)
-            return (KeyCode)keyInfo.Key;
+            // Always return the KeyChar because it may be an á, à with Oem1, etc
+            return (KeyCode)keyInfo.KeyChar;
         }
 
         // Handle control keys whose VK codes match the related ASCII value (those below ASCII 33) like ESC

+ 11 - 4
Terminal.Gui/Input/Key.cs

@@ -1,5 +1,6 @@
 using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
+using Terminal.Gui.ConsoleDrivers;
 
 namespace Terminal.Gui;
 
@@ -288,7 +289,10 @@ public class Key : EventArgs, IEquatable<Key>
             return false;
         }
 
-        if ((keyCode & ~KeyCode.Space & ~KeyCode.ShiftMask) is >= KeyCode.A and <= KeyCode.Z)
+        // A to Z may have á, à, ã, â, with Oem1, etc
+        ConsoleKeyInfo cki = ConsoleKeyMapping.GetConsoleKeyInfoFromKeyCode (keyCode);
+
+        if (cki.Key is >= ConsoleKey.A and <= ConsoleKey.Z)
         {
             return true;
         }
@@ -521,9 +525,12 @@ public class Key : EventArgs, IEquatable<Key>
         // Handle special cases and modifiers on their own
         if (key != KeyCode.SpecialMask && (baseKey != KeyCode.Null || hasModifiers))
         {
-            if ((key & KeyCode.SpecialMask) != 0 && (baseKey & ~KeyCode.Space) is >= KeyCode.A and <= KeyCode.Z)
+            // A to Z may have á, à, ã, â, with Oem1, etc
+            ConsoleKeyInfo cki = ConsoleKeyMapping.GetConsoleKeyInfoFromKeyCode (baseKey);
+
+            if ((key & KeyCode.SpecialMask) != 0 && cki.Key is >= ConsoleKey.A and <= ConsoleKey.Z)
             {
-                sb.Append (baseKey & ~KeyCode.Space);
+                sb.Append (((char)(baseKey & ~KeyCode.Space)).ToString ());
             }
             else
             {
@@ -706,7 +713,7 @@ public class Key : EventArgs, IEquatable<Key>
 
             if (GetIsKeyCodeAtoZ (keyCode) && (keyCode & KeyCode.Space) != 0)
             {
-                keyCode = keyCode & ~KeyCode.Space;
+                keyCode &= ~KeyCode.Space;
             }
 
             key = new (keyCode | modifiers);

+ 5 - 7
UnitTests/Input/KeyTests.cs

@@ -17,7 +17,7 @@ public class KeyTests
             { "Alt+A", Key.A.WithAlt },
             { "Shift+A", Key.A.WithShift },
             { "A", Key.A.WithShift },
-            { "â", new ((KeyCode)'â') },
+            { "â", new ((KeyCode)'Â') },
             { "Shift+â", new ((KeyCode)'â' | KeyCode.ShiftMask) },
             { "Shift+Â", new ((KeyCode)'Â' | KeyCode.ShiftMask) },
             { "Ctrl+Shift+CursorUp", Key.CursorUp.WithShift.WithCtrl },
@@ -342,12 +342,10 @@ public class KeyTests
     [InlineData ((KeyCode)'{', "{")]
     [InlineData ((KeyCode)'\'', "\'")]
     [InlineData ((KeyCode)'ó', "ó")]
-    [InlineData (
-                    (KeyCode)'Ó' | KeyCode.ShiftMask,
-                    "Shift+Ó"
-                )] // TODO: This is not correct, it should be Shift+ó or just Ó
+    [InlineData ((KeyCode)'Ó' | KeyCode.ShiftMask, "Ó")]
+    [InlineData ((KeyCode)'ó' | KeyCode.ShiftMask, "Ó")]
     [InlineData ((KeyCode)'Ó', "Ó")]
-    [InlineData ((KeyCode)'ç' | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+Shift+ç")]
+    [InlineData ((KeyCode)'ç' | KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+Shift+Ç")]
     [InlineData ((KeyCode)'a', "a")] // 97 or Key.Space | Key.A
     [InlineData ((KeyCode)'A', "a")] // 65 or equivalent to Key.A, but A-Z are mapped to lower case by drivers
     [InlineData (KeyCode.ShiftMask | KeyCode.A, "A")]
@@ -470,7 +468,7 @@ public class KeyTests
     [InlineData ("Alt+A", KeyCode.A | KeyCode.AltMask)]
     [InlineData ("Shift+A", KeyCode.A | KeyCode.ShiftMask)]
     [InlineData ("A", KeyCode.A | KeyCode.ShiftMask)]
-    [InlineData ("â", (KeyCode)'â')]
+    [InlineData ("â", (KeyCode)'Â')]
     [InlineData ("Shift+â", (KeyCode)'â' | KeyCode.ShiftMask)]
     [InlineData ("Shift+Â", (KeyCode)'Â' | KeyCode.ShiftMask)]
     [InlineData ("Ctrl+Shift+CursorUp", KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.CursorUp)]