Skip to content

Commit f676f12

Browse files
tigBDisp
authored andcommitted
Fixes gui-cs#3071 & gui-cs#3079. Key cast and static props are not correct (gui-cs#3089)
* Removed char->Key cast. Added Key(char) * Re-added char->key cast. Added unit tests * Fixed standard keys to always return new instead of being readonly * Re-fixed WindowsDriver to report shift/alt/ctrl as key/down/up * Re-fixed WindowsDriver to report shift/alt/ctrl as key/down/up * Adds string constructor to Key + tests. * Simplified Key json * Added string/Key cast operators.
1 parent 393836e commit f676f12

File tree

13 files changed

+911
-747
lines changed

13 files changed

+911
-747
lines changed

Terminal.Gui/Configuration/ConfigurationManager.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Linq;
1010
using System.Reflection;
1111
using System.Text;
12+
using System.Text.Encodings.Web;
1213
using System.Text.Json;
1314
using System.Text.Json.Serialization;
1415
using static Terminal.Gui.SpinnerStyle;
@@ -70,8 +71,13 @@ public static partial class ConfigurationManager {
7071
// We override the standard Rune converter to support specifying Glyphs in
7172
// a flexible way
7273
new RuneJsonConverter(),
74+
// Override Key to support "Ctrl+Q" format.
75+
new KeyJsonConverter()
7376
},
74-
};
77+
// Enables Key to be "Ctrl+Q" vs "Ctrl\u002BQ"
78+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
79+
80+
};
7581

7682
/// <summary>
7783
/// A dictionary of all properties in the Terminal.Gui project that are decorated with the <see cref="SerializableConfigurationProperty"/> attribute.

Terminal.Gui/Configuration/KeyJsonConverter.cs

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,12 @@
33
using System.Text.Json.Serialization;
44

55
namespace Terminal.Gui;
6-
class KeyJsonConverter : JsonConverter<Key> {
7-
8-
public override Key Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
9-
{
10-
if (reader.TokenType == JsonTokenType.StartObject) {
11-
Key key = Key.Empty;
12-
while (reader.Read ()) {
13-
if (reader.TokenType == JsonTokenType.EndObject) {
14-
break;
15-
}
166

17-
if (reader.TokenType == JsonTokenType.PropertyName) {
18-
string propertyName = reader.GetString ();
19-
reader.Read ();
7+
/// <summary>
8+
/// Support for <see cref="Key"/> in JSON in the form of "Ctrl-X" or "Alt-Shift-F1".
9+
/// </summary>
10+
public class KeyJsonConverter : JsonConverter<Key> {
11+
public override Key Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Key.TryParse (reader.GetString (), out var key) ? key : Key.Empty;
2012

21-
switch (propertyName?.ToLowerInvariant ()) {
22-
case "key":
23-
if (reader.TokenType == JsonTokenType.String) {
24-
string keyValue = reader.GetString ();
25-
if (Key.TryParse (keyValue, out key)) {
26-
break;
27-
}
28-
throw new JsonException ($"Error parsing Key: {keyValue}.");
29-
30-
}
31-
break;
32-
default:
33-
throw new JsonException ($"Unexpected Key property \"{propertyName}\".");
34-
}
35-
}
36-
}
37-
return key;
38-
}
39-
throw new JsonException ($"Unexpected StartObject token when parsing Key: {reader.TokenType}.");
40-
}
41-
42-
public override void Write (Utf8JsonWriter writer, Key value, JsonSerializerOptions options)
43-
{
44-
writer.WriteStartObject ();
45-
writer.WriteString ("Key", value.ToString ());
46-
writer.WriteEndObject ();
47-
}
48-
}
13+
public override void Write (Utf8JsonWriter writer, Key value, JsonSerializerOptions options) => writer.WriteStringValue (value.ToString ());
14+
}

Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,6 @@ public enum CursorVisibility {
649649
/// Lowercase alpha keys are encoded as values between 65 and 90 corresponding to the un-shifted A to Z keys on a keyboard. Enum values
650650
/// are provided for these (e.g. <see cref="KeyCode.A"/>, <see cref="KeyCode.B"/>, etc.). Even though the values are the same as the ASCII
651651
/// values for uppercase characters, these enum values represent *lowercase*, un-shifted characters.
652-
/// TODO: Strongly consider renaming these from .A to .Z to .A_Lowercase to .Z_Lowercase (or .a to .z).
653652
/// </para>
654653
/// <para>
655654
/// Numeric keys are the values between 48 and 57 corresponding to 0 to 9 (e.g. <see cref="KeyCode.D0"/>, <see cref="KeyCode.D1"/>, etc.).
@@ -680,7 +679,7 @@ public enum KeyCode : uint {
680679

681680
/// <summary>
682681
/// If the <see cref="SpecialMask"/> is set, then the value is that of the special mask,
683-
/// otherwise, the value is the one of the lower bits (as extracted by <see cref="CharMask"/>).
682+
/// otherwise, the value is in the the lower bits (as extracted by <see cref="CharMask"/>).
684683
/// </summary>
685684
SpecialMask = 0xfff00000,
686685

@@ -791,111 +790,111 @@ public enum KeyCode : uint {
791790
D9,
792791

793792
/// <summary>
794-
/// The key code for the user pressing Shift-A
793+
/// The key code for the A key
795794
/// </summary>
796795
A = 65,
797796
/// <summary>
798-
/// The key code for the user pressing Shift-B
797+
/// The key code for the B key
799798
/// </summary>
800799
B,
801800
/// <summary>
802-
/// The key code for the user pressing Shift-C
801+
/// The key code for the C key
803802
/// </summary>
804803
C,
805804
/// <summary>
806-
/// The key code for the user pressing Shift-D
805+
/// The key code for the D key
807806
/// </summary>
808807
D,
809808
/// <summary>
810-
/// The key code for the user pressing Shift-E
809+
/// The key code for the E key
811810
/// </summary>
812811
E,
813812
/// <summary>
814-
/// The key code for the user pressing Shift-F
813+
/// The key code for the F key
815814
/// </summary>
816815
F,
817816
/// <summary>
818-
/// The key code for the user pressing Shift-G
817+
/// The key code for the G key
819818
/// </summary>
820819
G,
821820
/// <summary>
822-
/// The key code for the user pressing Shift-H
821+
/// The key code for the H key
823822
/// </summary>
824823
H,
825824
/// <summary>
826-
/// The key code for the user pressing Shift-I
825+
/// The key code for the I key
827826
/// </summary>
828827
I,
829828
/// <summary>
830-
/// The key code for the user pressing Shift-J
829+
/// The key code for the J key
831830
/// </summary>
832831
J,
833832
/// <summary>
834-
/// The key code for the user pressing Shift-K
833+
/// The key code for the K key
835834
/// </summary>
836835
K,
837836
/// <summary>
838-
/// The key code for the user pressing Shift-L
837+
/// The key code for the L key
839838
/// </summary>
840839
L,
841840
/// <summary>
842-
/// The key code for the user pressing Shift-M
841+
/// The key code for the M key
843842
/// </summary>
844843
M,
845844
/// <summary>
846-
/// The key code for the user pressing Shift-N
845+
/// The key code for the N key
847846
/// </summary>
848847
N,
849848
/// <summary>
850-
/// The key code for the user pressing Shift-O
849+
/// The key code for the O key
851850
/// </summary>
852851
O,
853852
/// <summary>
854-
/// The key code for the user pressing Shift-P
853+
/// The key code for the P key
855854
/// </summary>
856855
P,
857856
/// <summary>
858-
/// The key code for the user pressing Shift-Q
857+
/// The key code for the Q key
859858
/// </summary>
860859
Q,
861860
/// <summary>
862-
/// The key code for the user pressing Shift-R
861+
/// The key code for the R key
863862
/// </summary>
864863
R,
865864
/// <summary>
866-
/// The key code for the user pressing Shift-S
865+
/// The key code for the S key
867866
/// </summary>
868867
S,
869868
/// <summary>
870-
/// The key code for the user pressing Shift-T
869+
/// The key code for the T key
871870
/// </summary>
872871
T,
873872
/// <summary>
874-
/// The key code for the user pressing Shift-U
873+
/// The key code for the U key
875874
/// </summary>
876875
U,
877876
/// <summary>
878-
/// The key code for the user pressing Shift-V
877+
/// The key code for the V key
879878
/// </summary>
880879
V,
881880
/// <summary>
882-
/// The key code for the user pressing Shift-W
881+
/// The key code for the W key
883882
/// </summary>
884883
W,
885884
/// <summary>
886-
/// The key code for the user pressing Shift-X
885+
/// The key code for the X key
887886
/// </summary>
888887
X,
889888
/// <summary>
890-
/// The key code for the user pressing Shift-Y
889+
/// The key code for the Y key
891890
/// </summary>
892891
Y,
893892
/// <summary>
894-
/// The key code for the user pressing Shift-Z
893+
/// The key code for the Z key
895894
/// </summary>
896895
Z,
897896
/// <summary>
898-
/// The key code for the user pressing A
897+
/// The key code for the Delete key.
899898
/// </summary>
900899
Delete = 127,
901900

Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,16 +1051,17 @@ KeyCode MapKey (WindowsConsole.ConsoleKeyInfoEx keyInfoEx)
10511051
return (KeyCode)((uint)KeyCode.F1 + delta);
10521052
}
10531053

1054+
// If the key is JUST a modifier, return it as that key
10541055
if (key == (ConsoleKey)16) { // Shift
1055-
return KeyCode.Null | KeyCode.ShiftMask;
1056+
return KeyCode.ShiftKey;
10561057
}
10571058

10581059
if (key == (ConsoleKey)17) { // Ctrl
1059-
return KeyCode.Null | KeyCode.CtrlMask;
1060+
return KeyCode.CtrlKey;
10601061
}
10611062

10621063
if (key == (ConsoleKey)18) { // Alt
1063-
return KeyCode.Null | KeyCode.AltMask;
1064+
return KeyCode.AltKey;
10641065
}
10651066

10661067
return ConsoleKeyMapping.MapKeyModifiers (keyInfo, (KeyCode)((uint)keyInfo.KeyChar));

0 commit comments

Comments
 (0)