mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
core: "all" bindings work
This commit is contained in:
@ -1590,7 +1590,7 @@ fn maybeHandleBinding(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Determine if this entry has an action or if its a leader key.
|
// Determine if this entry has an action or if its a leader key.
|
||||||
const action: input.Binding.Action, const consumed: bool = switch (entry) {
|
const leaf: input.Binding.Set.Leaf = switch (entry) {
|
||||||
.leader => |set| {
|
.leader => |set| {
|
||||||
// Setup the next set we'll look at.
|
// Setup the next set we'll look at.
|
||||||
self.keyboard.bindings = set;
|
self.keyboard.bindings = set;
|
||||||
@ -1605,7 +1605,20 @@ fn maybeHandleBinding(
|
|||||||
return .consumed;
|
return .consumed;
|
||||||
},
|
},
|
||||||
|
|
||||||
.leaf => |leaf| .{ leaf.action, leaf.flags.consumed },
|
.leaf => |leaf| leaf,
|
||||||
|
};
|
||||||
|
const action = leaf.action;
|
||||||
|
|
||||||
|
// consumed determines if the input is consumed or if we continue
|
||||||
|
// encoding the key (if we have a key to encode).
|
||||||
|
const consumed = consumed: {
|
||||||
|
// If the consumed flag is explicitly set, then we are consumed.
|
||||||
|
if (leaf.flags.consumed) break :consumed true;
|
||||||
|
|
||||||
|
// If the global or all flag is set, we always consume.
|
||||||
|
if (leaf.flags.global or leaf.flags.all) break :consumed true;
|
||||||
|
|
||||||
|
break :consumed false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We have an action, so at this point we're handling SOMETHING so
|
// We have an action, so at this point we're handling SOMETHING so
|
||||||
@ -1617,8 +1630,22 @@ fn maybeHandleBinding(
|
|||||||
self.keyboard.bindings = null;
|
self.keyboard.bindings = null;
|
||||||
|
|
||||||
// Attempt to perform the action
|
// Attempt to perform the action
|
||||||
log.debug("key event binding consumed={} action={}", .{ consumed, action });
|
log.debug("key event binding flags={} action={}", .{
|
||||||
const performed = try self.performBindingAction(action);
|
leaf.flags,
|
||||||
|
action,
|
||||||
|
});
|
||||||
|
const performed = performed: {
|
||||||
|
// If this is a global or all action, then we perform it on
|
||||||
|
// the app and it applies to every surface.
|
||||||
|
if (leaf.flags.global or leaf.flags.all) {
|
||||||
|
try self.app.performAllAction(self.rt_app, action);
|
||||||
|
|
||||||
|
// "All" actions are always performed since they are global.
|
||||||
|
break :performed true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break :performed try self.performBindingAction(action);
|
||||||
|
};
|
||||||
|
|
||||||
// If we performed an action and it was a closing action,
|
// If we performed an action and it was a closing action,
|
||||||
// our "self" pointer is not safe to use anymore so we need to
|
// our "self" pointer is not safe to use anymore so we need to
|
||||||
|
@ -1160,7 +1160,7 @@ pub const Set = struct {
|
|||||||
set.remove(alloc, t);
|
set.remove(alloc, t);
|
||||||
if (old) |entry| switch (entry) {
|
if (old) |entry| switch (entry) {
|
||||||
.leader => unreachable, // Handled above
|
.leader => unreachable, // Handled above
|
||||||
.leaf => |leaf| set.put_(
|
.leaf => |leaf| set.putFlags(
|
||||||
alloc,
|
alloc,
|
||||||
t,
|
t,
|
||||||
leaf.action,
|
leaf.action,
|
||||||
@ -1179,11 +1179,12 @@ pub const Set = struct {
|
|||||||
return error.SequenceUnbind;
|
return error.SequenceUnbind;
|
||||||
},
|
},
|
||||||
|
|
||||||
else => if (b.flags.consumed) {
|
else => try set.putFlags(
|
||||||
try set.put(alloc, b.trigger, b.action);
|
alloc,
|
||||||
} else {
|
b.trigger,
|
||||||
try set.putUnconsumed(alloc, b.trigger, b.action);
|
b.action,
|
||||||
},
|
b.flags,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1196,24 +1197,11 @@ pub const Set = struct {
|
|||||||
t: Trigger,
|
t: Trigger,
|
||||||
action: Action,
|
action: Action,
|
||||||
) Allocator.Error!void {
|
) Allocator.Error!void {
|
||||||
try self.put_(alloc, t, action, .{});
|
try self.putFlags(alloc, t, action, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as put but marks the trigger as unconsumed. An unconsumed
|
/// Add a binding to the set with explicit flags.
|
||||||
/// trigger will evaluate the action and continue to encode for the
|
pub fn putFlags(
|
||||||
/// terminal.
|
|
||||||
///
|
|
||||||
/// This is a separate function because this case is rare.
|
|
||||||
pub fn putUnconsumed(
|
|
||||||
self: *Set,
|
|
||||||
alloc: Allocator,
|
|
||||||
t: Trigger,
|
|
||||||
action: Action,
|
|
||||||
) Allocator.Error!void {
|
|
||||||
try self.put_(alloc, t, action, .{ .consumed = false });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn put_(
|
|
||||||
self: *Set,
|
self: *Set,
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
t: Trigger,
|
t: Trigger,
|
||||||
@ -1486,6 +1474,49 @@ test "parse: global triggers" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "parse: all triggers" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
// all keys
|
||||||
|
try testing.expectEqual(Binding{
|
||||||
|
.trigger = .{
|
||||||
|
.mods = .{ .shift = true },
|
||||||
|
.key = .{ .translated = .a },
|
||||||
|
},
|
||||||
|
.action = .{ .ignore = {} },
|
||||||
|
.flags = .{ .all = true },
|
||||||
|
}, try parseSingle("all:shift+a=ignore"));
|
||||||
|
|
||||||
|
// all physical keys
|
||||||
|
try testing.expectEqual(Binding{
|
||||||
|
.trigger = .{
|
||||||
|
.mods = .{ .shift = true },
|
||||||
|
.key = .{ .physical = .a },
|
||||||
|
},
|
||||||
|
.action = .{ .ignore = {} },
|
||||||
|
.flags = .{ .all = true },
|
||||||
|
}, try parseSingle("all:physical:a+shift=ignore"));
|
||||||
|
|
||||||
|
// all unconsumed keys
|
||||||
|
try testing.expectEqual(Binding{
|
||||||
|
.trigger = .{
|
||||||
|
.mods = .{ .shift = true },
|
||||||
|
.key = .{ .translated = .a },
|
||||||
|
},
|
||||||
|
.action = .{ .ignore = {} },
|
||||||
|
.flags = .{
|
||||||
|
.all = true,
|
||||||
|
.consumed = false,
|
||||||
|
},
|
||||||
|
}, try parseSingle("unconsumed:all:a+shift=ignore"));
|
||||||
|
|
||||||
|
// all sequences not allowed
|
||||||
|
{
|
||||||
|
var p = try Parser.init("all:a>b=ignore");
|
||||||
|
try testing.expectError(Error.InvalidFormat, p.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "parse: modifier aliases" {
|
test "parse: modifier aliases" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user