mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
Merge pull request #1267 from mitchellh/keypad
input: manage application keypad state with mode 1035
This commit is contained in:
@ -1322,6 +1322,7 @@ pub fn keyCallback(
|
|||||||
.alt_esc_prefix = t.modes.get(.alt_esc_prefix),
|
.alt_esc_prefix = t.modes.get(.alt_esc_prefix),
|
||||||
.cursor_key_application = t.modes.get(.cursor_keys),
|
.cursor_key_application = t.modes.get(.cursor_keys),
|
||||||
.keypad_key_application = t.modes.get(.keypad_keys),
|
.keypad_key_application = t.modes.get(.keypad_keys),
|
||||||
|
.ignore_keypad_with_numlock = t.modes.get(.ignore_keypad_with_numlock),
|
||||||
.modify_other_keys_state_2 = t.flags.modify_other_keys_2,
|
.modify_other_keys_state_2 = t.flags.modify_other_keys_2,
|
||||||
.kitty_flags = t.screen.kitty_keyboard.current(),
|
.kitty_flags = t.screen.kitty_keyboard.current(),
|
||||||
};
|
};
|
||||||
|
@ -26,6 +26,7 @@ macos_option_as_alt: config.OptionAsAlt = .false,
|
|||||||
alt_esc_prefix: bool = false,
|
alt_esc_prefix: bool = false,
|
||||||
cursor_key_application: bool = false,
|
cursor_key_application: bool = false,
|
||||||
keypad_key_application: bool = false,
|
keypad_key_application: bool = false,
|
||||||
|
ignore_keypad_with_numlock: bool = false,
|
||||||
modify_other_keys_state_2: bool = false,
|
modify_other_keys_state_2: bool = false,
|
||||||
kitty_flags: KittyFlags = .{},
|
kitty_flags: KittyFlags = .{},
|
||||||
|
|
||||||
@ -245,6 +246,7 @@ fn legacy(
|
|||||||
all_mods,
|
all_mods,
|
||||||
self.cursor_key_application,
|
self.cursor_key_application,
|
||||||
self.keypad_key_application,
|
self.keypad_key_application,
|
||||||
|
self.ignore_keypad_with_numlock,
|
||||||
self.modify_other_keys_state_2,
|
self.modify_other_keys_state_2,
|
||||||
)) |sequence| pc_style: {
|
)) |sequence| pc_style: {
|
||||||
// If we're pressing enter and have UTF-8 text, we probably are
|
// If we're pressing enter and have UTF-8 text, we probably are
|
||||||
@ -416,7 +418,8 @@ fn pcStyleFunctionKey(
|
|||||||
keyval: key.Key,
|
keyval: key.Key,
|
||||||
mods: key.Mods,
|
mods: key.Mods,
|
||||||
cursor_key_application: bool,
|
cursor_key_application: bool,
|
||||||
keypad_key_application: bool,
|
keypad_key_application_req: bool,
|
||||||
|
ignore_keypad_with_numlock: bool,
|
||||||
modify_other_keys: bool, // True if state 2
|
modify_other_keys: bool, // True if state 2
|
||||||
) ?[]const u8 {
|
) ?[]const u8 {
|
||||||
// We only want binding-sensitive mods because lock keys
|
// We only want binding-sensitive mods because lock keys
|
||||||
@ -424,6 +427,24 @@ fn pcStyleFunctionKey(
|
|||||||
// pc-style function keys.
|
// pc-style function keys.
|
||||||
const mods_int = mods.binding().int();
|
const mods_int = mods.binding().int();
|
||||||
|
|
||||||
|
// Keypad application keymode isn't super straightforward.
|
||||||
|
// On xterm, in VT220 mode, numlock alone is enough to trigger
|
||||||
|
// application mode. But in more modern modes, numlock is
|
||||||
|
// ignored by default via mode 1035 (default true). If mode
|
||||||
|
// 1035 is on, we always are in numerical keypad mode. If
|
||||||
|
// mode 1035 is off, we are in application mode if the
|
||||||
|
// proper numlock state is pressed. The numlock state is implicitly
|
||||||
|
// determined based on the keycode sent (i.e. 1 with numlock
|
||||||
|
// on will be kp_end).
|
||||||
|
const keypad_key_application = keypad: {
|
||||||
|
// If we're ignoring keypad then this is always false.
|
||||||
|
// In other words, we're always in numerical keypad mode.
|
||||||
|
if (ignore_keypad_with_numlock) break :keypad false;
|
||||||
|
|
||||||
|
// If we're not ignoring then we enable the desired state.
|
||||||
|
break :keypad keypad_key_application_req;
|
||||||
|
};
|
||||||
|
|
||||||
for (function_keys.keys.get(keyval)) |entry| {
|
for (function_keys.keys.get(keyval)) |entry| {
|
||||||
switch (entry.cursor) {
|
switch (entry.cursor) {
|
||||||
.any => {},
|
.any => {},
|
||||||
@ -1677,6 +1698,70 @@ test "legacy: keypad enter" {
|
|||||||
try testing.expectEqualStrings("\r", actual);
|
try testing.expectEqualStrings("\r", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "legacy: keypad 1" {
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
var enc: KeyEncoder = .{
|
||||||
|
.event = .{
|
||||||
|
.key = .kp_1,
|
||||||
|
.mods = .{},
|
||||||
|
.consumed_mods = .{},
|
||||||
|
.utf8 = "1",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = try enc.legacy(&buf);
|
||||||
|
try testing.expectEqualStrings("1", actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "legacy: keypad 1 with application keypad" {
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
var enc: KeyEncoder = .{
|
||||||
|
.event = .{
|
||||||
|
.key = .kp_1,
|
||||||
|
.mods = .{},
|
||||||
|
.consumed_mods = .{},
|
||||||
|
.utf8 = "1",
|
||||||
|
},
|
||||||
|
.keypad_key_application = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = try enc.legacy(&buf);
|
||||||
|
try testing.expectEqualStrings("\x1bOq", actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "legacy: keypad 1 with application keypad and numlock" {
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
var enc: KeyEncoder = .{
|
||||||
|
.event = .{
|
||||||
|
.key = .kp_1,
|
||||||
|
.mods = .{ .num_lock = true },
|
||||||
|
.consumed_mods = .{},
|
||||||
|
.utf8 = "1",
|
||||||
|
},
|
||||||
|
.keypad_key_application = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = try enc.legacy(&buf);
|
||||||
|
try testing.expectEqualStrings("\x1bOq", actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "legacy: keypad 1 with application keypad and numlock ignore" {
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
var enc: KeyEncoder = .{
|
||||||
|
.event = .{
|
||||||
|
.key = .kp_1,
|
||||||
|
.mods = .{ .num_lock = false },
|
||||||
|
.consumed_mods = .{},
|
||||||
|
.utf8 = "1",
|
||||||
|
},
|
||||||
|
.keypad_key_application = true,
|
||||||
|
.ignore_keypad_with_numlock = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = try enc.legacy(&buf);
|
||||||
|
try testing.expectEqualStrings("1", actual);
|
||||||
|
}
|
||||||
|
|
||||||
test "legacy: f1" {
|
test "legacy: f1" {
|
||||||
var buf: [128]u8 = undefined;
|
var buf: [128]u8 = undefined;
|
||||||
var enc: KeyEncoder = .{
|
var enc: KeyEncoder = .{
|
||||||
|
@ -121,6 +121,7 @@ pub const keys = keys: {
|
|||||||
result.set(.kp_down, pcStyle("\x1b[1;{}B") ++ cursorKey("\x1b[B", "\x1bOB"));
|
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_right, pcStyle("\x1b[1;{}C") ++ cursorKey("\x1b[C", "\x1bOC"));
|
||||||
result.set(.kp_left, pcStyle("\x1b[1;{}D") ++ cursorKey("\x1b[D", "\x1bOD"));
|
result.set(.kp_left, pcStyle("\x1b[1;{}D") ++ cursorKey("\x1b[D", "\x1bOD"));
|
||||||
|
result.set(.kp_begin, pcStyle("\x1b[1;{}E") ++ cursorKey("\x1b[E", "\x1bOE"));
|
||||||
result.set(.kp_home, pcStyle("\x1b[1;{}H") ++ cursorKey("\x1b[H", "\x1bOH"));
|
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_end, pcStyle("\x1b[1;{}F") ++ cursorKey("\x1b[F", "\x1bOF"));
|
||||||
result.set(.kp_insert, pcStyle("\x1b[2;{}~") ++ .{.{ .sequence = "\x1B[2~" }});
|
result.set(.kp_insert, pcStyle("\x1b[2;{}~") ++ .{.{ .sequence = "\x1B[2~" }});
|
||||||
|
@ -206,6 +206,7 @@ const entries: []const ModeEntry = &.{
|
|||||||
.{ .name = "mouse_alternate_scroll", .value = 1007, .default = true },
|
.{ .name = "mouse_alternate_scroll", .value = 1007, .default = true },
|
||||||
.{ .name = "mouse_format_urxvt", .value = 1015 },
|
.{ .name = "mouse_format_urxvt", .value = 1015 },
|
||||||
.{ .name = "mouse_format_sgr_pixels", .value = 1016 },
|
.{ .name = "mouse_format_sgr_pixels", .value = 1016 },
|
||||||
|
.{ .name = "ignore_keypad_with_numlock", .value = 1035, .default = true },
|
||||||
.{ .name = "alt_esc_prefix", .value = 1036, .default = true },
|
.{ .name = "alt_esc_prefix", .value = 1036, .default = true },
|
||||||
.{ .name = "alt_sends_escape", .value = 1039 },
|
.{ .name = "alt_sends_escape", .value = 1039 },
|
||||||
.{ .name = "reverse_wrap_extended", .value = 1045 },
|
.{ .name = "reverse_wrap_extended", .value = 1045 },
|
||||||
|
Reference in New Issue
Block a user