From 07e6cf900f78c0303116832e3dc93a2bda992aec Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 24 Nov 2023 13:56:47 -0600 Subject: [PATCH] key-encode: only set associated text when there is printable text Associated text should only be sent to the terminal when printable text is generated from the keypress. Prevent sending associated text when any modifier is pressed, except for Shift, NumLock, and Capslock This brings Ghostty inline with the output of Kitty. --- src/input/KeyEncoder.zig | 57 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/input/KeyEncoder.zig b/src/input/KeyEncoder.zig index aa58f3953..78b8a098f 100644 --- a/src/input/KeyEncoder.zig +++ b/src/input/KeyEncoder.zig @@ -175,7 +175,7 @@ fn kitty( } } - if (self.kitty_flags.report_associated) { + if (self.kitty_flags.report_associated and !seq.mods.preventsText()) { seq.text = self.event.utf8; } @@ -585,6 +585,19 @@ const KittyMods = packed struct(u8) { }; } + /// Returns true if the modifiers prevent printable text + pub fn preventsText(self: KittyMods) bool { + if (self.alt or + self.ctrl or + self.super or + self.hyper or + self.meta) + { + return true; + } + return false; + } + /// Returns the raw int value of this packed struct. pub fn int(self: KittyMods) u8 { return @bitCast(self); @@ -1167,6 +1180,48 @@ test "kitty: left shift with report all" { try testing.expectEqualStrings("\x1b[57441u", actual); } +test "kitty: report associated with modifiers" { + var buf: [128]u8 = undefined; + var enc: KeyEncoder = .{ + .event = .{ + .key = .j, + .mods = .{ .ctrl = true }, + .utf8 = "j", + .unshifted_codepoint = 106, + }, + .kitty_flags = .{ + .disambiguate = true, + .report_all = true, + .report_alternates = true, + .report_associated = true, + }, + }; + + const actual = try enc.kitty(&buf); + try testing.expectEqualStrings("\x1b[106;5u", actual); +} + +test "kitty: report associated" { + var buf: [128]u8 = undefined; + var enc: KeyEncoder = .{ + .event = .{ + .key = .j, + .mods = .{ .shift = true }, + .utf8 = "J", + .unshifted_codepoint = 106, + }, + .kitty_flags = .{ + .disambiguate = true, + .report_all = true, + .report_alternates = true, + .report_associated = true, + }, + }; + + const actual = try enc.kitty(&buf); + try testing.expectEqualStrings("\x1b[106:74;2;74u", actual); +} + test "kitty: alternates omit control characters" { var buf: [128]u8 = undefined; var enc: KeyEncoder = .{