From c774e37548e8d4cf84c764c1ee5c1b5e220512b0 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 25 Mar 2023 15:36:37 -0700 Subject: [PATCH] core: input bindings support unmapped bindings --- src/input/Binding.zig | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 746ccbff7..9e4341f56 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -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 const keysInfo = @typeInfo(key.Key).Enum; inline for (keysInfo.fields) |field| { 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 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. 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. pub fn hash(self: Binding) u64 { var hasher = std.hash.Wyhash.init(0); std.hash.autoHash(&hasher, self.key); std.hash.autoHash(&hasher, self.mods); + std.hash.autoHash(&hasher, self.unmapped); return hasher.final(); } }; @@ -326,6 +340,16 @@ test "parse: triggers" { .action = .{ .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 try testing.expectError(Error.InvalidFormat, parse("foo=ignore"));