mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-01 23:48:35 +00:00
macos: do not send UTF-8 PUA codepoints to key events
Fixes #7337 AppKit encodes functional keys as PUA codepoints. We don't want to send that down as valid text encoding for a key event because KKP uses that in particular to change the encoding with associated text. I think there may be a more specific solution to this by only doing this within the KKP encoding part of KeyEncoder but that was filled with edge cases and I didn't want to risk breaking anything else.
This commit is contained in:
@@ -56,13 +56,20 @@ extension NSEvent {
|
||||
// If we have no characters associated with this event we do nothing.
|
||||
guard let characters else { return nil }
|
||||
|
||||
// If we have a single control character, then we return the characters
|
||||
// without control pressed. We do this because we handle control character
|
||||
// encoding directly within Ghostty's KeyEncoder.
|
||||
if characters.count == 1,
|
||||
let scalar = characters.unicodeScalars.first,
|
||||
scalar.value < 0x20 {
|
||||
return self.characters(byApplyingModifiers: modifierFlags.subtracting(.control))
|
||||
let scalar = characters.unicodeScalars.first {
|
||||
// If we have a single control character, then we return the characters
|
||||
// without control pressed. We do this because we handle control character
|
||||
// encoding directly within Ghostty's KeyEncoder.
|
||||
if scalar.value < 0x20 {
|
||||
return self.characters(byApplyingModifiers: modifierFlags.subtracting(.control))
|
||||
}
|
||||
|
||||
// If we have a single value in the PUA, then it's a function key and
|
||||
// we don't want to send PUA ranges down to Ghostty.
|
||||
if scalar.value >= 0xF700 && scalar.value <= 0xF8FF {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return characters
|
||||
|
@@ -146,7 +146,9 @@ fn kitty(
|
||||
// the real world issue is usually control characters.
|
||||
const view = try std.unicode.Utf8View.init(self.event.utf8);
|
||||
var it = view.iterator();
|
||||
while (it.nextCodepoint()) |cp| if (isControl(cp)) break :plain_text;
|
||||
while (it.nextCodepoint()) |cp| {
|
||||
if (isControl(cp)) break :plain_text;
|
||||
}
|
||||
|
||||
return try copyToBuf(buf, self.event.utf8);
|
||||
}
|
||||
@@ -212,7 +214,9 @@ fn kitty(
|
||||
}
|
||||
}
|
||||
|
||||
if (self.kitty_flags.report_associated and seq.event != .release) associated: {
|
||||
if (self.kitty_flags.report_associated and
|
||||
seq.event != .release)
|
||||
associated: {
|
||||
// Determine if the Alt modifier should be treated as an actual
|
||||
// modifier (in which case it prevents associated text) or as
|
||||
// the macOS Option key, which does not prevent associated text.
|
||||
|
@@ -83,6 +83,15 @@ pub const Flags = packed struct(u5) {
|
||||
report_all: bool = false,
|
||||
report_associated: bool = false,
|
||||
|
||||
/// Sets all modes on.
|
||||
pub const @"true": Flags = .{
|
||||
.disambiguate = true,
|
||||
.report_events = true,
|
||||
.report_alternates = true,
|
||||
.report_all = true,
|
||||
.report_associated = true,
|
||||
};
|
||||
|
||||
pub fn int(self: Flags) u5 {
|
||||
return @bitCast(self);
|
||||
}
|
||||
|
Reference in New Issue
Block a user