diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 80180b543..34053c2b5 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1444,8 +1444,13 @@ fn keyEvent( // a text value. We have to do this because GTK will not process // "Ctrl+Shift+1" (on US keyboards) as "Ctrl+!" but instead as "". // But the keyval is set correctly so we can at least extract that. - if (self.im_len == 0 and keyval_unicode > 0) { + if (self.im_len == 0 and keyval_unicode > 0) im: { if (std.math.cast(u21, keyval_unicode)) |cp| { + // We don't want to send control characters as IM + // text. Control characters are handled already by + // the encoder directly. + if (cp < 0x20) break :im; + if (std.unicode.utf8Encode(cp, &self.im_buf)) |len| { self.im_len = len; } else |_| {} diff --git a/src/input/KeyEncoder.zig b/src/input/KeyEncoder.zig index 887e522fc..6738b93fe 100644 --- a/src/input/KeyEncoder.zig +++ b/src/input/KeyEncoder.zig @@ -711,8 +711,19 @@ const KittySequence = struct { const mods = self.mods.seqInt(); var emit_prior = false; if (self.event != .none) { - try writer.print(";{d}:{d}", .{ mods, @intFromEnum(self.event) }); - emit_prior = true; + // Easier to understand if you De Morgan this: we skip + // if we have no mods AND its a press event. In that case + // both are "1" and empty also means default. In theory + // there is no harm being explicit here but Kitty doesn't + // output in this case and we want to match here. This is + // unit tested. + if (self.event != .press or mods > 1) { + try writer.print( + ";{d}:{d}", + .{ mods, @intFromEnum(self.event) }, + ); + emit_prior = true; + } } else if (mods > 1) { try writer.print(";{d}", .{mods}); emit_prior = true; @@ -947,6 +958,22 @@ test "kitty: enter, backspace, tab" { } } +test "kitty: enter with all flags" { + var buf: [128]u8 = undefined; + var enc: KeyEncoder = .{ + .event = .{ .key = .enter, .mods = .{}, .utf8 = "" }, + .kitty_flags = .{ + .disambiguate = true, + .report_events = true, + .report_alternates = true, + .report_all = true, + .report_associated = true, + }, + }; + const actual = try enc.kitty(&buf); + try testing.expectEqualStrings("[13u", actual[1..]); +} + test "kitty: delete" { var buf: [128]u8 = undefined; {