From a0880bcfed67f6ae5b5e6689fadf9e16e02d73c8 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 13 Dec 2023 06:53:33 -0600 Subject: [PATCH] key: add additional keypad keys Add additional keypad keys to the encoding scheme. This allows Ghostty to report KP_HOME and it's relatives. We also always check for a keyval first, so we can report KP_7, etc as opposed to ASCII '7'. --- src/apprt/gtk/Surface.zig | 13 +++++++------ src/apprt/gtk/key.zig | 22 ++++++++++++---------- src/input/function_keys.zig | 10 ++++++++++ src/input/key.zig | 26 ++++++++++++++++++++++++++ src/input/kitty.zig | 12 ++++++++++++ 5 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 6eb4e73d1..4dd2e1245 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1391,6 +1391,13 @@ fn keyEvent( // If we're not in a dead key state, we want to translate our text // to some input.Key. const key = if (!self.im_composing) key: { + // First, try to convert the keyval directly to a key. This allows the + // use of key remapping and identification of keypad numerics (as + // opposed to their ASCII counterparts) + if (gtk_key.keyFromKeyval(keyval)) |key| { + break :key key; + } + // A completed key. If the length of the key is one then we can // attempt to translate it to a key enum and call the key // callback. First try plain ASCII. @@ -1416,12 +1423,6 @@ fn keyEvent( } } - // Before using the physical key, try to convert the keyval - // directly to a key. This allows the use of key remapping. - if (gtk_key.keyFromKeyval(keyval)) |key| { - break :key key; - } - // If we have im text then this is invalid. This means that // the keypress generated some character that we don't know about // in our key enum. We don't want to use the physical key because diff --git a/src/apprt/gtk/key.zig b/src/apprt/gtk/key.zig index 2cd71eb1c..1d575ab39 100644 --- a/src/apprt/gtk/key.zig +++ b/src/apprt/gtk/key.zig @@ -190,16 +190,18 @@ const keymap: []const RawEntry = &.{ .{ c.GDK_KEY_KP_Enter, .kp_enter }, .{ c.GDK_KEY_KP_Equal, .kp_equal }, - // These are all just aliases to the non-kp variants because Ghostty - // core doesn't distinguish between them currently. - .{ c.GDK_KEY_KP_Home, .home }, - .{ c.GDK_KEY_KP_End, .end }, - .{ c.GDK_KEY_KP_Page_Up, .page_up }, - .{ c.GDK_KEY_KP_Page_Down, .page_down }, - .{ c.GDK_KEY_KP_Up, .up }, - .{ c.GDK_KEY_KP_Down, .down }, - .{ c.GDK_KEY_KP_Right, .right }, - .{ c.GDK_KEY_KP_Left, .left }, + .{ c.GDK_KEY_KP_Separator, .kp_separator }, + .{ c.GDK_KEY_KP_Left, .kp_left }, + .{ c.GDK_KEY_KP_Right, .kp_right }, + .{ c.GDK_KEY_KP_Up, .kp_up }, + .{ c.GDK_KEY_KP_Down, .kp_down }, + .{ c.GDK_KEY_KP_Page_Up, .kp_page_up }, + .{ c.GDK_KEY_KP_Page_Down, .kp_page_down }, + .{ c.GDK_KEY_KP_Home, .kp_home }, + .{ c.GDK_KEY_KP_End, .kp_end }, + .{ c.GDK_KEY_KP_Insert, .kp_insert }, + .{ c.GDK_KEY_KP_Delete, .kp_delete }, + .{ c.GDK_KEY_KP_Begin, .kp_begin }, .{ c.GDK_KEY_Shift_L, .left_shift }, .{ c.GDK_KEY_Control_L, .left_control }, diff --git a/src/input/function_keys.zig b/src/input/function_keys.zig index 9721130d1..ea98c386c 100644 --- a/src/input/function_keys.zig +++ b/src/input/function_keys.zig @@ -117,6 +117,16 @@ pub const keys = keys: { result.set(.kp_subtract, kpDefault("m") ++ pcStyle("\x1bO{}m")); result.set(.kp_add, kpDefault("k") ++ pcStyle("\x1bO{}k")); result.set(.kp_enter, kpDefault("M") ++ pcStyle("\x1bO{}M") ++ .{.{ .sequence = "\r" }}); + result.set(.kp_up, pcStyle("\x1b[1;{}A") ++ cursorKey("\x1b[A", "\x1bOA")); + result.set(.kp_down, pcStyle("\x1b[1;{}B") ++ cursorKey("\x1b[B", "\x1bOB")); + result.set(.kp_right, pcStyle("\x1b[1;{}C") ++ cursorKey("\x1b[C", "\x1bOC")); + result.set(.kp_left, pcStyle("\x1b[1;{}D") ++ cursorKey("\x1b[D", "\x1bOD")); + result.set(.kp_home, pcStyle("\x1b[1;{}H") ++ cursorKey("\x1b[H", "\x1bOH")); + result.set(.kp_end, pcStyle("\x1b[1;{}F") ++ cursorKey("\x1b[F", "\x1bOF")); + result.set(.kp_insert, pcStyle("\x1b[2;{}~") ++ .{.{ .sequence = "\x1B[2~" }}); + result.set(.kp_delete, pcStyle("\x1b[3;{}~") ++ .{.{ .sequence = "\x1B[3~" }}); + result.set(.kp_page_up, pcStyle("\x1b[5;{}~") ++ .{.{ .sequence = "\x1B[5~" }}); + result.set(.kp_page_down, pcStyle("\x1b[6;{}~") ++ .{.{ .sequence = "\x1B[6~" }}); result.set(.backspace, &.{ // Modify Keys Normal diff --git a/src/input/key.zig b/src/input/key.zig index 2a7795cbd..ce8390091 100644 --- a/src/input/key.zig +++ b/src/input/key.zig @@ -344,6 +344,18 @@ pub const Key = enum(c_int) { kp_add, kp_enter, kp_equal, + kp_separator, + kp_left, + kp_right, + kp_up, + kp_down, + kp_page_up, + kp_page_down, + kp_home, + kp_end, + kp_insert, + kp_delete, + kp_begin, // modifiers left_shift, @@ -552,6 +564,20 @@ pub const Key = enum(c_int) { .kp_add => cimgui.c.ImGuiKey_KeypadAdd, .kp_enter => cimgui.c.ImGuiKey_KeypadEnter, .kp_equal => cimgui.c.ImGuiKey_KeypadEqual, + // We map KP_SEPARATOR to Comma because traditionally a numpad would + // have a numeric separator key. Most modern numpads do not + .kp_separator => cimgui.c.ImGuiKey_Comma, + .kp_left => cimgui.c.ImGuiKey_LeftArrow, + .kp_right => cimgui.c.ImGuiKey_RightArrow, + .kp_up => cimgui.c.ImGuiKey_UpArrow, + .kp_down => cimgui.c.ImGuiKey_DownArrow, + .kp_page_up => cimgui.c.ImGuiKey_PageUp, + .kp_page_down => cimgui.c.ImGuiKey_PageUp, + .kp_home => cimgui.c.ImGuiKey_Home, + .kp_end => cimgui.c.ImGuiKey_End, + .kp_insert => cimgui.c.ImGuiKey_Insert, + .kp_delete => cimgui.c.ImGuiKey_Delete, + .kp_begin => cimgui.c.ImGuiKey_NamedKey_BEGIN, .left_shift => cimgui.c.ImGuiKey_LeftShift, .left_control => cimgui.c.ImGuiKey_LeftCtrl, diff --git a/src/input/kitty.zig b/src/input/kitty.zig index a9b061107..f8faaa154 100644 --- a/src/input/kitty.zig +++ b/src/input/kitty.zig @@ -104,6 +104,18 @@ const raw_entries: []const RawEntry = &.{ .{ .kp_add, 57413, 'u', false }, .{ .kp_enter, 57414, 'u', false }, .{ .kp_equal, 57415, 'u', false }, + .{ .kp_separator, 57416, 'u', false }, + .{ .kp_left, 57417, 'u', false }, + .{ .kp_right, 57418, 'u', false }, + .{ .kp_up, 57419, 'u', false }, + .{ .kp_down, 57420, 'u', false }, + .{ .kp_page_up, 57421, 'u', false }, + .{ .kp_page_down, 57422, 'u', false }, + .{ .kp_home, 57423, 'u', false }, + .{ .kp_end, 57424, 'u', false }, + .{ .kp_insert, 57425, 'u', false }, + .{ .kp_delete, 57426, 'u', false }, + .{ .kp_begin, 57427, 'u', false }, .{ .left_shift, 57441, 'u', true }, .{ .right_shift, 57447, 'u', true },