input: fix associated text on macOS

Ghostty does not report associated text on macOS when
macos-option-as-alt is enabled for _any_ key press, whether or not the
Alt modifier is actually present. The "option as alt" decision should
only be made when the alt modifier is present.
This commit is contained in:
Gregory Anders
2024-03-25 13:39:20 -05:00
parent badedf81a7
commit c634ba363a

View File

@ -200,27 +200,20 @@ fn kitty(
} }
if (self.kitty_flags.report_associated and seq.event != .release) associated: { if (self.kitty_flags.report_associated and seq.event != .release) associated: {
if (comptime builtin.target.isDarwin()) { // Determine if the Alt modifier should be treated as an actual
// macOS has special logic because alt+key can produce unicode // modifier (in which case it prevents associated text) or as
// characters. If we are treating option as alt, then we do NOT // the macOS Option key, which does not prevent associated text.
// report associated text. If we are not treating alt as alt, const alt_prevents_text = if (comptime builtin.target.isDarwin())
// we do. switch (self.macos_option_as_alt) {
if (switch (self.macos_option_as_alt) {
.left => all_mods.sides.alt == .left, .left => all_mods.sides.alt == .left,
.right => all_mods.sides.alt == .right, .right => all_mods.sides.alt == .right,
.true => true, .true => true,
.false => false,
}
else
true;
// This is the main weird one. If we are NOT treating if (seq.mods.preventsText(alt_prevents_text)) break :associated;
// option as alt, we still want to prevent text if we
// have modifiers set WITHOUT alt. If alt is present,
// macOS will handle generating the unicode character.
// If alt is not present, we want to suppress.
.false => !seq.mods.alt and seq.mods.preventsText(),
}) break :associated;
} else {
// If any modifiers are present, we don't report associated text.
if (seq.mods.preventsText()) break :associated;
}
seq.text = self.event.utf8; seq.text = self.event.utf8;
} }
@ -736,10 +729,11 @@ const KittyMods = packed struct(u8) {
/// Returns true if the modifiers prevent printable text. /// Returns true if the modifiers prevent printable text.
/// ///
/// Note on macOS: this logic alone is not enough, since you must /// The alt_prevents_text parameter determines whether or not the Alt
/// consider macos_option_as_alt. See the Kitty encoder for more details. /// modifier prevents printable text. On Linux, this is always true. On
pub fn preventsText(self: KittyMods) bool { /// macOS, this is only true if macos-option-as-alt is set.
return self.alt or pub fn preventsText(self: KittyMods, alt_prevents_text: bool) bool {
return (self.alt and alt_prevents_text) or
self.ctrl or self.ctrl or
self.super or self.super or
self.hyper or self.hyper or
@ -1475,25 +1469,51 @@ test "kitty: report associated with alt text on macOS with option" {
test "kitty: report associated with alt text on macOS with alt" { test "kitty: report associated with alt text on macOS with alt" {
if (comptime !builtin.target.isDarwin()) return error.SkipZigTest; if (comptime !builtin.target.isDarwin()) return error.SkipZigTest;
var buf: [128]u8 = undefined; {
var enc: KeyEncoder = .{ // With Alt modifier
.event = .{ var buf: [128]u8 = undefined;
.key = .w, var enc: KeyEncoder = .{
.mods = .{ .alt = true }, .event = .{
.utf8 = "", .key = .w,
.unshifted_codepoint = 119, .mods = .{ .alt = true },
}, .utf8 = "",
.kitty_flags = .{ .unshifted_codepoint = 119,
.disambiguate = true, },
.report_all = true, .kitty_flags = .{
.report_alternates = true, .disambiguate = true,
.report_associated = true, .report_all = true,
}, .report_alternates = true,
.macos_option_as_alt = .true, .report_associated = true,
}; },
.macos_option_as_alt = .true,
};
const actual = try enc.kitty(&buf); const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("\x1b[119;3u", actual); try testing.expectEqualStrings("\x1b[119;3u", actual);
}
{
// Without Alt modifier
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{
.event = .{
.key = .w,
.mods = .{},
.utf8 = "",
.unshifted_codepoint = 119,
},
.kitty_flags = .{
.disambiguate = true,
.report_all = true,
.report_alternates = true,
.report_associated = true,
},
.macos_option_as_alt = .true,
};
const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("\x1b[119;;8721u", actual);
}
} }
test "kitty: report associated with modifiers" { test "kitty: report associated with modifiers" {