Skip to content

Commit da165fc

Browse files
authored
input: modify other keys 2 should use all mods, ignore consumed mods (ghostty-org#9289)
Fixes ghostty-org#8900 Our xterm modify other keys state 2 encoding was stripped consumed mods from the keyboard event. This doesn't match xterm or other popular terminal emulators (but most importantly: xterm). Use the full set of mods and add a test to verify this. Reproduction: ``` printf '\033[>4;2m' cat ``` Then press `ctrl+shift+h` and compare across terminals.
1 parent 0546606 commit da165fc

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

src/input/key_encode.zig

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn encode(
7777
event: key.KeyEvent,
7878
opts: Options,
7979
) std.Io.Writer.Error!void {
80-
// log.warn("KEYENCODER self={}", .{self.*});
80+
//std.log.warn("KEYENCODER event={} opts={}", .{ event, opts });
8181
return if (opts.kitty_flags.int() != 0) try kitty(
8282
writer,
8383
event,
@@ -411,6 +411,10 @@ fn legacy(
411411
// ever be a multi-codepoint sequence that triggers this.
412412
if (it.nextCodepoint() != null) break :modify_other;
413413

414+
// The mods we encode for this are just the binding mods (shift, ctrl,
415+
// super, alt).
416+
const mods = event.mods.binding();
417+
414418
// This copies xterm's `ModifyOtherKeys` function that returns
415419
// whether modify other keys should be encoded for the given
416420
// input.
@@ -420,7 +424,7 @@ fn legacy(
420424
break :should_modify true;
421425

422426
// If we have anything other than shift pressed, encode.
423-
var mods_no_shift = binding_mods;
427+
var mods_no_shift = mods;
424428
mods_no_shift.shift = false;
425429
if (!mods_no_shift.empty()) break :should_modify true;
426430

@@ -435,7 +439,7 @@ fn legacy(
435439

436440
if (should_modify) {
437441
for (function_keys.modifiers, 2..) |modset, code| {
438-
if (!binding_mods.equal(modset)) continue;
442+
if (!mods.equal(modset)) continue;
439443
return try writer.print(
440444
"\x1B[27;{};{}~",
441445
.{ code, codepoint },
@@ -1970,6 +1974,20 @@ test "legacy: ctrl+shift+char with modify other state 2" {
19701974
try testing.expectEqualStrings("\x1b[27;6;72~", writer.buffered());
19711975
}
19721976

1977+
test "legacy: ctrl+shift+char with modify other state 2 and consumed mods" {
1978+
var buf: [128]u8 = undefined;
1979+
var writer: std.Io.Writer = .fixed(&buf);
1980+
try legacy(&writer, .{
1981+
.key = .key_h,
1982+
.mods = .{ .ctrl = true, .shift = true },
1983+
.consumed_mods = .{ .shift = true },
1984+
.utf8 = "H",
1985+
}, .{
1986+
.modify_other_keys_state_2 = true,
1987+
});
1988+
try testing.expectEqualStrings("\x1b[27;6;72~", writer.buffered());
1989+
}
1990+
19731991
test "legacy: fixterm awkward letters" {
19741992
var buf: [128]u8 = undefined;
19751993
{

0 commit comments

Comments
 (0)