macos: don't put 0x7F as text in key event

Fixes #13869

We already checked `< 0x20` but missed `0x7F` which causes similar
problems.
This commit is contained in:
Mitchell Hashimoto
2026-08-17 06:38:21 -07:00
parent b97b17f06b
commit f4309055fb
3 changed files with 28 additions and 5 deletions

View File

@@ -1484,11 +1484,12 @@ extension Ghostty {
var key_ev = event.ghosttyKeyEvent(action, translationMods: translationEvent?.modifierFlags)
key_ev.composing = composing
// For text, we only encode UTF8 if we don't have a single control
// character. Control characters are encoded by Ghostty itself.
// Without this, `ctrl+enter` does the wrong thing.
if let text, text.count > 0,
let codepoint = text.utf8.first, codepoint >= 0x20 {
// Control characters are encoded by Ghostty itself so that the
// physical key and its modifiers remain available to protocols
// such as the Kitty keyboard protocol.
if let text,
!text.isEmpty,
!text.startsWithASCIIControlCharacter {
return text.withCString { ptr in
key_ev.text = ptr
return ghostty_surface_key(surface, key_ev)

View File

@@ -1,4 +1,10 @@
extension String {
/// True when the first scalar is an ASCII control character (C0 or DEL).
var startsWithASCIIControlCharacter: Bool {
guard let scalar = unicodeScalars.first else { return false }
return scalar.value < 0x20 || scalar.value == 0x7F
}
func truncate(length: Int, trailing: String = "") -> String {
let maxLength = length - trailing.count
guard maxLength > 0, !self.isEmpty, self.count > length else {

View File

@@ -1359,6 +1359,22 @@ test "kitty: shift+backspace emits CSI u" {
try testing.expectEqualStrings("\x1b[127;2u", writer.buffered());
}
test "kitty: alt+backspace emits CSI u" {
var buf: [128]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
try kitty(&writer, .{
.key = .backspace,
.mods = .{ .alt = true },
// macOS may mark Option as consumed while translating the key. With
// no attached control text, all modifiers must remain effective.
.consumed_mods = .{ .alt = true },
.utf8 = "",
}, .{
.kitty_flags = .{ .disambiguate = true },
});
try testing.expectEqualStrings("\x1b[127;3u", writer.buffered());
}
test "kitty: shift+enter emits CSI u" {
var buf: [128]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);