mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
input: CSIu should send full codepoint
Related to #1802 CSIu format sends a unicode codepoint but we were just sending the first byte of the utf8 sequence, which is very much not right. This fixes that by parsing the utf-8. It isn't defined what to do if the utf-8 sequence is invalid or has multiple codepoints so we just skip CSIu encoding in that case.
This commit is contained in:
@ -358,15 +358,21 @@ fn legacy(
|
|||||||
// Let's see if we should apply fixterms to this codepoint.
|
// Let's see if we should apply fixterms to this codepoint.
|
||||||
// At this stage of key processing, we only need to apply fixterms
|
// At this stage of key processing, we only need to apply fixterms
|
||||||
// to unicode codepoints if we have ctrl set.
|
// to unicode codepoints if we have ctrl set.
|
||||||
if (self.event.mods.ctrl) {
|
if (self.event.mods.ctrl) csiu: {
|
||||||
// Important: we want to use the original mods here, not the
|
// Important: we want to use the original mods here, not the
|
||||||
// effective mods. The fixterms spec states the shifted chars
|
// effective mods. The fixterms spec states the shifted chars
|
||||||
// should be sent uppercase but Kitty changes that behavior
|
// should be sent uppercase but Kitty changes that behavior
|
||||||
// so we'll send all the mods.
|
// so we'll send all the mods.
|
||||||
const csi_u_mods, const char = mods: {
|
const csi_u_mods, const char = mods: {
|
||||||
var char: u21 = @intCast(utf8[0]);
|
|
||||||
var mods = CsiUMods.fromInput(self.event.mods);
|
var mods = CsiUMods.fromInput(self.event.mods);
|
||||||
|
|
||||||
|
// Get our codepoint. If we have more than one codepoint this
|
||||||
|
// can't be valid CSIu.
|
||||||
|
const view = std.unicode.Utf8View.init(self.event.utf8) catch break :csiu;
|
||||||
|
var it = view.iterator();
|
||||||
|
var char = it.nextCodepoint() orelse break :csiu;
|
||||||
|
if (it.nextCodepoint() != null) break :csiu;
|
||||||
|
|
||||||
// If our character is A to Z and we have shift set, then
|
// If our character is A to Z and we have shift set, then
|
||||||
// we lowercase it. This is a Kitty-specific behavior that
|
// we lowercase it. This is a Kitty-specific behavior that
|
||||||
// we choose to follow and diverge from the fixterms spec.
|
// we choose to follow and diverge from the fixterms spec.
|
||||||
@ -2113,6 +2119,21 @@ test "legacy: right_shift+tab" {
|
|||||||
try testing.expectEqualStrings("\x1b[Z", actual);
|
try testing.expectEqualStrings("\x1b[Z", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "legacy: hu layout ctrl+ő sends proper codepoint" {
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
var enc: KeyEncoder = .{
|
||||||
|
.event = .{
|
||||||
|
.key = .left_bracket,
|
||||||
|
.physical_key = .left_bracket,
|
||||||
|
.mods = .{ .ctrl = true },
|
||||||
|
.utf8 = "ő",
|
||||||
|
.unshifted_codepoint = 337,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = try enc.legacy(&buf);
|
||||||
|
try testing.expectEqualStrings("[337;5u", actual[1..]);
|
||||||
|
}
|
||||||
test "ctrlseq: normal ctrl c" {
|
test "ctrlseq: normal ctrl c" {
|
||||||
const seq = ctrlSeq("c", 'c', .{ .ctrl = true });
|
const seq = ctrlSeq("c", 'c', .{ .ctrl = true });
|
||||||
try testing.expectEqual(@as(u8, 0x03), seq.?);
|
try testing.expectEqual(@as(u8, 0x03), seq.?);
|
||||||
|
Reference in New Issue
Block a user