core: input bindings support unmapped bindings

This commit is contained in:
Mitchell Hashimoto
2023-03-25 15:36:37 -07:00
parent f092cce69e
commit c774e37548

View File

@ -53,11 +53,18 @@ pub fn parse(input: []const u8) !Binding {
} }
} }
// If the key starts with "unmapped" then this is an unmapped key.
const unmapped_prefix = "unmapped:";
const key_part = if (std.mem.startsWith(u8, part, unmapped_prefix)) key_part: {
result.unmapped = true;
break :key_part part[unmapped_prefix.len..];
} else part;
// Check if its a key // Check if its a key
const keysInfo = @typeInfo(key.Key).Enum; const keysInfo = @typeInfo(key.Key).Enum;
inline for (keysInfo.fields) |field| { inline for (keysInfo.fields) |field| {
if (!std.mem.eql(u8, field.name, "invalid")) { if (!std.mem.eql(u8, field.name, "invalid")) {
if (std.mem.eql(u8, part, field.name)) { if (std.mem.eql(u8, key_part, field.name)) {
// Repeat not allowed // Repeat not allowed
if (result.key != .invalid) return Error.InvalidFormat; if (result.key != .invalid) return Error.InvalidFormat;
@ -237,11 +244,18 @@ pub const Trigger = struct {
/// The key modifiers that must be active for this to match. /// The key modifiers that must be active for this to match.
mods: key.Mods = .{}, mods: key.Mods = .{},
/// key is the "unmapped" version. This is the same as mapped for
/// standard US keyboard layouts. For non-US keyboard layouts, this
/// is used to bind to a physical key location rather than a translated
/// key.
unmapped: bool = false,
/// Returns a hash code that can be used to uniquely identify this trigger. /// Returns a hash code that can be used to uniquely identify this trigger.
pub fn hash(self: Binding) u64 { pub fn hash(self: Binding) u64 {
var hasher = std.hash.Wyhash.init(0); var hasher = std.hash.Wyhash.init(0);
std.hash.autoHash(&hasher, self.key); std.hash.autoHash(&hasher, self.key);
std.hash.autoHash(&hasher, self.mods); std.hash.autoHash(&hasher, self.mods);
std.hash.autoHash(&hasher, self.unmapped);
return hasher.final(); return hasher.final();
} }
}; };
@ -326,6 +340,16 @@ test "parse: triggers" {
.action = .{ .ignore = {} }, .action = .{ .ignore = {} },
}, try parse("a+shift=ignore")); }, try parse("a+shift=ignore"));
// unmapped keys
try testing.expectEqual(Binding{
.trigger = .{
.mods = .{ .shift = true },
.key = .a,
.unmapped = true,
},
.action = .{ .ignore = {} },
}, try parse("shift+unmapped:a=ignore"));
// invalid key // invalid key
try testing.expectError(Error.InvalidFormat, parse("foo=ignore")); try testing.expectError(Error.InvalidFormat, parse("foo=ignore"));