Skip to content

Commit

Permalink
Fixes #3071 & #3079. Key cast and static props are not correct (#3089)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
tig authored Dec 27, 2023
1 parent a7209bc commit 80ef4b5
Show file tree
Hide file tree
Showing 13 changed files with 911 additions and 747 deletions.
8 changes: 7 additions & 1 deletion Terminal.Gui/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using static Terminal.Gui.SpinnerStyle;
Expand Down Expand Up @@ -70,8 +71,13 @@ public static partial class ConfigurationManager {
// We override the standard Rune converter to support specifying Glyphs in
// a flexible way
new RuneJsonConverter(),
// Override Key to support "Ctrl+Q" format.
new KeyJsonConverter()
},
};
// Enables Key to be "Ctrl+Q" vs "Ctrl\u002BQ"
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping

};

/// <summary>
/// A dictionary of all properties in the Terminal.Gui project that are decorated with the <see cref="SerializableConfigurationProperty"/> attribute.
Expand Down
48 changes: 7 additions & 41 deletions Terminal.Gui/Configuration/KeyJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,12 @@
using System.Text.Json.Serialization;

namespace Terminal.Gui;
class KeyJsonConverter : JsonConverter<Key> {

public override Key Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject) {
Key key = Key.Empty;
while (reader.Read ()) {
if (reader.TokenType == JsonTokenType.EndObject) {
break;
}

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

Check warning on line 11 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Read(ref Utf8JsonReader, Type, JsonSerializerOptions)'

Check warning on line 11 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Read(ref Utf8JsonReader, Type, JsonSerializerOptions)'

Check warning on line 11 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / Build and Publish to Nuget.org

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Read(ref Utf8JsonReader, Type, JsonSerializerOptions)'

Check warning on line 11 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / Build and Publish to Nuget.org

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Read(ref Utf8JsonReader, Type, JsonSerializerOptions)'

switch (propertyName?.ToLowerInvariant ()) {
case "key":
if (reader.TokenType == JsonTokenType.String) {
string keyValue = reader.GetString ();
if (Key.TryParse (keyValue, out key)) {
break;
}
throw new JsonException ($"Error parsing Key: {keyValue}.");

}
break;
default:
throw new JsonException ($"Unexpected Key property \"{propertyName}\".");
}
}
}
return key;
}
throw new JsonException ($"Unexpected StartObject token when parsing Key: {reader.TokenType}.");
}

public override void Write (Utf8JsonWriter writer, Key value, JsonSerializerOptions options)
{
writer.WriteStartObject ();
writer.WriteString ("Key", value.ToString ());
writer.WriteEndObject ();
}
}
public override void Write (Utf8JsonWriter writer, Key value, JsonSerializerOptions options) => writer.WriteStringValue (value.ToString ());

Check warning on line 13 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Write(Utf8JsonWriter, Key, JsonSerializerOptions)'

Check warning on line 13 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Write(Utf8JsonWriter, Key, JsonSerializerOptions)'

Check warning on line 13 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / Build and Publish to Nuget.org

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Write(Utf8JsonWriter, Key, JsonSerializerOptions)'

Check warning on line 13 in Terminal.Gui/Configuration/KeyJsonConverter.cs

View workflow job for this annotation

GitHub Actions / Build and Publish to Nuget.org

Missing XML comment for publicly visible type or member 'KeyJsonConverter.Write(Utf8JsonWriter, Key, JsonSerializerOptions)'
}
57 changes: 28 additions & 29 deletions Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,6 @@ public enum CursorVisibility {
/// 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
/// 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
/// values for uppercase characters, these enum values represent *lowercase*, un-shifted characters.
/// TODO: Strongly consider renaming these from .A to .Z to .A_Lowercase to .Z_Lowercase (or .a to .z).
/// </para>
/// <para>
/// 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.).
Expand Down Expand Up @@ -680,7 +679,7 @@ public enum KeyCode : uint {

/// <summary>
/// If the <see cref="SpecialMask"/> is set, then the value is that of the special mask,
/// otherwise, the value is the one of the lower bits (as extracted by <see cref="CharMask"/>).
/// otherwise, the value is in the the lower bits (as extracted by <see cref="CharMask"/>).
/// </summary>
SpecialMask = 0xfff00000,

Expand Down Expand Up @@ -791,111 +790,111 @@ public enum KeyCode : uint {
D9,

/// <summary>
/// The key code for the user pressing Shift-A
/// The key code for the A key
/// </summary>
A = 65,
/// <summary>
/// The key code for the user pressing Shift-B
/// The key code for the B key
/// </summary>
B,
/// <summary>
/// The key code for the user pressing Shift-C
/// The key code for the C key
/// </summary>
C,
/// <summary>
/// The key code for the user pressing Shift-D
/// The key code for the D key
/// </summary>
D,
/// <summary>
/// The key code for the user pressing Shift-E
/// The key code for the E key
/// </summary>
E,
/// <summary>
/// The key code for the user pressing Shift-F
/// The key code for the F key
/// </summary>
F,
/// <summary>
/// The key code for the user pressing Shift-G
/// The key code for the G key
/// </summary>
G,
/// <summary>
/// The key code for the user pressing Shift-H
/// The key code for the H key
/// </summary>
H,
/// <summary>
/// The key code for the user pressing Shift-I
/// The key code for the I key
/// </summary>
I,
/// <summary>
/// The key code for the user pressing Shift-J
/// The key code for the J key
/// </summary>
J,
/// <summary>
/// The key code for the user pressing Shift-K
/// The key code for the K key
/// </summary>
K,
/// <summary>
/// The key code for the user pressing Shift-L
/// The key code for the L key
/// </summary>
L,
/// <summary>
/// The key code for the user pressing Shift-M
/// The key code for the M key
/// </summary>
M,
/// <summary>
/// The key code for the user pressing Shift-N
/// The key code for the N key
/// </summary>
N,
/// <summary>
/// The key code for the user pressing Shift-O
/// The key code for the O key
/// </summary>
O,
/// <summary>
/// The key code for the user pressing Shift-P
/// The key code for the P key
/// </summary>
P,
/// <summary>
/// The key code for the user pressing Shift-Q
/// The key code for the Q key
/// </summary>
Q,
/// <summary>
/// The key code for the user pressing Shift-R
/// The key code for the R key
/// </summary>
R,
/// <summary>
/// The key code for the user pressing Shift-S
/// The key code for the S key
/// </summary>
S,
/// <summary>
/// The key code for the user pressing Shift-T
/// The key code for the T key
/// </summary>
T,
/// <summary>
/// The key code for the user pressing Shift-U
/// The key code for the U key
/// </summary>
U,
/// <summary>
/// The key code for the user pressing Shift-V
/// The key code for the V key
/// </summary>
V,
/// <summary>
/// The key code for the user pressing Shift-W
/// The key code for the W key
/// </summary>
W,
/// <summary>
/// The key code for the user pressing Shift-X
/// The key code for the X key
/// </summary>
X,
/// <summary>
/// The key code for the user pressing Shift-Y
/// The key code for the Y key
/// </summary>
Y,
/// <summary>
/// The key code for the user pressing Shift-Z
/// The key code for the Z key
/// </summary>
Z,
/// <summary>
/// The key code for the user pressing A
/// The key code for the Delete key.
/// </summary>
Delete = 127,

Expand Down
7 changes: 4 additions & 3 deletions Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1051,16 +1051,17 @@ KeyCode MapKey (WindowsConsole.ConsoleKeyInfoEx keyInfoEx)
return (KeyCode)((uint)KeyCode.F1 + delta);
}

// If the key is JUST a modifier, return it as that key
if (key == (ConsoleKey)16) { // Shift
return KeyCode.Null | KeyCode.ShiftMask;
return KeyCode.ShiftKey;
}

if (key == (ConsoleKey)17) { // Ctrl
return KeyCode.Null | KeyCode.CtrlMask;
return KeyCode.CtrlKey;
}

if (key == (ConsoleKey)18) { // Alt
return KeyCode.Null | KeyCode.AltMask;
return KeyCode.AltKey;
}

return ConsoleKeyMapping.MapKeyModifiers (keyInfo, (KeyCode)((uint)keyInfo.KeyChar));
Expand Down
Loading

0 comments on commit 80ef4b5

Please sign in to comment.