From 564b35d26d7f90cea26379af71366d428719e7fe Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 16 Sep 2026 12:26:38 -0300 Subject: Forward Option chords to the child on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In raw tty mode Alt-n reached the child as a bare `n`: the ESC prefix was dropped on the floor, and only on macOS. ghostty's encoder refuses the legacy alt-esc prefix on a macOS build unless macos_option_as_alt says Option really is Alt, and KeyEncodeOptions.fromTerminal cannot know that one — it says so in a comment — so it defaults to false. False is right for an app that lets macOS translate the chord and hands the encoder the composed text. Every pardes shell decides the modifier itself and hands the core the BASE key with the alt bit and no text at all, which PardesView.keyDown and app.mjs both spell the same way, so by the time the encoder runs there is nothing left to translate. The unit suite has been catching this on macOS all along; it is only invisible on Linux, where that branch does not compile in. Co-Authored-By: Claude Opus 5 (1M context) --- src/panes.zig | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/panes.zig b/src/panes.zig index 88e6a8ea..93abae30 100644 --- a/src/panes.zig +++ b/src/panes.zig @@ -6803,7 +6803,20 @@ pub const Terminal = struct { .consumed_mods = .{ .shift = key.text.len > 0 and key.shift }, .utf8 = text, .unshifted_codepoint = if (key.cp >= 'A' and key.cp <= 'Z') key.cp - 'A' + 'a' else if (key.cp < Key.up) key.cp else 0, - }, input.KeyEncodeOptions.fromTerminal(&state.vt)) catch return; + }, options: { + var opts = input.KeyEncodeOptions.fromTerminal(&state.vt); + // fromTerminal cannot know this one and says so, defaulting to + // "option is not alt" — right for an app that lets macOS do the + // unicode translation and hands the encoder the composed text. + // Every pardes shell resolves the modifier itself and hands the + // core the BASE key with the alt bit and no text at all (see + // PardesView.keyDown, and app.mjs doing the same with the same + // two bits), so by the time this runs alt already means alt. + // Left at the default, a macOS build drops the ESC prefix on + // the floor and forwards Alt-n to the child as a bare `n`. + opts.macos_option_as_alt = .true; + break :options opts; + }) catch return; if (writer.end > 0) p.emit(.{ .write = .{ .pane = @intCast(id), .bytes = .from(writer.buffered()) } }); return; } -- cgit v1.3