mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
Merge pull request #1088 from mitchellh/kitty-mods
macos: proper event when sided mod released with other side pressed
This commit is contained in:
@ -905,10 +905,32 @@ extension Ghostty {
|
||||
// but this is super cheap and flagsChanged isn't that common.
|
||||
let mods = Ghostty.ghosttyMods(event.modifierFlags)
|
||||
|
||||
// If the key that pressed this is active, its a press, else release
|
||||
// If the key that pressed this is active, its a press, else release.
|
||||
var action = GHOSTTY_ACTION_RELEASE
|
||||
if (mods.rawValue & mod != 0) { action = GHOSTTY_ACTION_PRESS }
|
||||
|
||||
if (mods.rawValue & mod != 0) {
|
||||
// If the key is pressed, its slightly more complicated, because we
|
||||
// want to check if the pressed modifier is the correct side. If the
|
||||
// correct side is pressed then its a press event otherwise its a release
|
||||
// event with the opposite modifier still held.
|
||||
let sidePressed: Bool
|
||||
switch (event.keyCode) {
|
||||
case 0x3C:
|
||||
sidePressed = event.modifierFlags.rawValue & UInt(NX_DEVICERSHIFTKEYMASK) != 0;
|
||||
case 0x3E:
|
||||
sidePressed = event.modifierFlags.rawValue & UInt(NX_DEVICERCTLKEYMASK) != 0;
|
||||
case 0x3D:
|
||||
sidePressed = event.modifierFlags.rawValue & UInt(NX_DEVICERALTKEYMASK) != 0;
|
||||
case 0x36:
|
||||
sidePressed = event.modifierFlags.rawValue & UInt(NX_DEVICERCMDKEYMASK) != 0;
|
||||
default:
|
||||
sidePressed = true
|
||||
}
|
||||
|
||||
if (sidePressed) {
|
||||
action = GHOSTTY_ACTION_PRESS
|
||||
}
|
||||
}
|
||||
|
||||
keyAction(action, event: event)
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,11 @@ fn kitty(
|
||||
var seq: KittySequence = .{
|
||||
.key = entry.code,
|
||||
.final = entry.final,
|
||||
.mods = KittyMods.fromInput(all_mods),
|
||||
.mods = KittyMods.fromInput(
|
||||
self.event.action,
|
||||
self.event.key,
|
||||
all_mods,
|
||||
),
|
||||
};
|
||||
|
||||
if (self.kitty_flags.report_events) {
|
||||
@ -596,12 +600,27 @@ const KittyMods = packed struct(u8) {
|
||||
num_lock: bool = false,
|
||||
|
||||
/// Convert an input mods value into the CSI u mods value.
|
||||
pub fn fromInput(mods: key.Mods) KittyMods {
|
||||
pub fn fromInput(
|
||||
action: key.Action,
|
||||
k: key.Key,
|
||||
mods: key.Mods,
|
||||
) KittyMods {
|
||||
// Annoying boolean logic, but according to the Kitty spec:
|
||||
// "When both left and right control keys are pressed and one is
|
||||
// released, the release event must again have the modifier bit reset"
|
||||
// In other words, we allow a modifier if it is set AND the action
|
||||
// is NOT a release. Or if the action is a release, then the key being
|
||||
// released must not be the associated modifier key.
|
||||
const shift = mods.shift and (action != .release or (k != .left_shift and k != .right_shift));
|
||||
const alt = mods.alt and (action != .release or (k != .left_alt and k != .right_alt));
|
||||
const ctrl = mods.ctrl and (action != .release or (k != .left_control and k != .right_control));
|
||||
const super = mods.super and (action != .release or (k != .left_super and k != .right_super));
|
||||
|
||||
return .{
|
||||
.shift = mods.shift,
|
||||
.alt = mods.alt,
|
||||
.ctrl = mods.ctrl,
|
||||
.super = mods.super,
|
||||
.shift = shift,
|
||||
.alt = alt,
|
||||
.ctrl = ctrl,
|
||||
.super = super,
|
||||
.caps_lock = mods.caps_lock,
|
||||
.num_lock = mods.num_lock,
|
||||
};
|
||||
@ -982,6 +1001,27 @@ test "kitty: ctrl with all flags" {
|
||||
try testing.expectEqualStrings("[57442;5u", actual[1..]);
|
||||
}
|
||||
|
||||
test "kitty: ctrl release with ctrl mod set" {
|
||||
var buf: [128]u8 = undefined;
|
||||
var enc: KeyEncoder = .{
|
||||
.event = .{
|
||||
.action = .release,
|
||||
.key = .left_control,
|
||||
.mods = .{ .ctrl = true },
|
||||
.utf8 = "",
|
||||
},
|
||||
.kitty_flags = .{
|
||||
.disambiguate = true,
|
||||
.report_events = true,
|
||||
.report_alternates = true,
|
||||
.report_all = true,
|
||||
.report_associated = true,
|
||||
},
|
||||
};
|
||||
const actual = try enc.kitty(&buf);
|
||||
try testing.expectEqualStrings("[57442;1:3u", actual[1..]);
|
||||
}
|
||||
|
||||
test "kitty: delete" {
|
||||
var buf: [128]u8 = undefined;
|
||||
{
|
||||
|
Reference in New Issue
Block a user