mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
terminal: implement CSI = u for setting kitty keyboard flags
This commit is contained in:
@ -19,6 +19,24 @@ pub const KeyFlagStack = struct {
|
|||||||
return self.flags[self.idx];
|
return self.flags[self.idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform the "set" operation as described in the spec for
|
||||||
|
/// the CSI = u sequence.
|
||||||
|
pub fn set(
|
||||||
|
self: *KeyFlagStack,
|
||||||
|
mode: KeySetMode,
|
||||||
|
v: KeyFlags,
|
||||||
|
) void {
|
||||||
|
switch (mode) {
|
||||||
|
.set => self.flags[self.idx] = v,
|
||||||
|
.@"or" => self.flags[self.idx] = @bitCast(
|
||||||
|
self.flags[self.idx].int() | v.int(),
|
||||||
|
),
|
||||||
|
.not => self.flags[self.idx] = @bitCast(
|
||||||
|
self.flags[self.idx].int() & ~v.int(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Push a new set of flags onto the stack. If the stack is full
|
/// Push a new set of flags onto the stack. If the stack is full
|
||||||
/// then the oldest entry is evicted.
|
/// then the oldest entry is evicted.
|
||||||
pub fn push(self: *KeyFlagStack, flags: KeyFlags) void {
|
pub fn push(self: *KeyFlagStack, flags: KeyFlags) void {
|
||||||
@ -87,6 +105,9 @@ pub const KeyFlags = packed struct(u5) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The possible modes for setting the key flags.
|
||||||
|
pub const KeySetMode = enum { set, @"or", not };
|
||||||
|
|
||||||
test "KeyFlagStack: push pop" {
|
test "KeyFlagStack: push pop" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
var stack: KeyFlagStack = .{};
|
var stack: KeyFlagStack = .{};
|
||||||
@ -106,3 +127,28 @@ test "KeyFlagStack: pop big number" {
|
|||||||
stack.pop(100);
|
stack.pop(100);
|
||||||
try testing.expectEqual(KeyFlags{}, stack.current());
|
try testing.expectEqual(KeyFlags{}, stack.current());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "KeyFlagStack: set" {
|
||||||
|
const testing = std.testing;
|
||||||
|
var stack: KeyFlagStack = .{};
|
||||||
|
stack.set(.set, .{ .disambiguate = true });
|
||||||
|
try testing.expectEqual(
|
||||||
|
KeyFlags{ .disambiguate = true },
|
||||||
|
stack.current(),
|
||||||
|
);
|
||||||
|
|
||||||
|
stack.set(.@"or", .{ .report_events = true });
|
||||||
|
try testing.expectEqual(
|
||||||
|
KeyFlags{
|
||||||
|
.disambiguate = true,
|
||||||
|
.report_events = true,
|
||||||
|
},
|
||||||
|
stack.current(),
|
||||||
|
);
|
||||||
|
|
||||||
|
stack.set(.not, .{ .report_events = true });
|
||||||
|
try testing.expectEqual(
|
||||||
|
KeyFlags{ .disambiguate = true },
|
||||||
|
stack.current(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -673,7 +673,35 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
try self.handler.popKittyKeyboard(number);
|
try self.handler.popKittyKeyboard(number);
|
||||||
},
|
},
|
||||||
|
|
||||||
'=' => @panic("TODO! DO NOT MERGE"),
|
'=' => if (@hasDecl(T, "setKittyKeyboard")) set: {
|
||||||
|
const flags: u5 = if (action.params.len >= 1)
|
||||||
|
std.math.cast(u5, action.params[0]) orelse {
|
||||||
|
log.warn("invalid setKittyKeyboard command: {}", .{action});
|
||||||
|
break :set;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
0;
|
||||||
|
|
||||||
|
const number: u16 = if (action.params.len >= 2)
|
||||||
|
action.params[1]
|
||||||
|
else
|
||||||
|
1;
|
||||||
|
|
||||||
|
const mode: kitty.KeySetMode = switch (number) {
|
||||||
|
0 => .set,
|
||||||
|
1 => .@"or",
|
||||||
|
2 => .not,
|
||||||
|
else => {
|
||||||
|
log.warn("invalid setKittyKeyboard command: {}", .{action});
|
||||||
|
break :set;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.handler.setKittyKeyboard(
|
||||||
|
mode,
|
||||||
|
@bitCast(flags),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI s with intermediate: {}",
|
"unknown CSI s with intermediate: {}",
|
||||||
|
@ -1435,6 +1435,15 @@ const StreamHandler = struct {
|
|||||||
self.terminal.screen.kitty_keyboard.pop(@intCast(n));
|
self.terminal.screen.kitty_keyboard.pop(@intCast(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setKittyKeyboard(
|
||||||
|
self: *StreamHandler,
|
||||||
|
mode: terminal.kitty.KeySetMode,
|
||||||
|
flags: terminal.kitty.KeyFlags,
|
||||||
|
) !void {
|
||||||
|
// log.debug("setting kitty keyboard mode: {} {}", .{mode, flags});
|
||||||
|
self.terminal.screen.kitty_keyboard.set(mode, flags);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// OSC
|
// OSC
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user