diff --git a/src/config/Config.zig b/src/config/Config.zig index ca53468fe..e0ed6fcc8 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -3317,13 +3317,7 @@ pub const Keybinds = struct { /// Deep copy of the struct. Required by Config. pub fn clone(self: *const Keybinds, alloc: Allocator) !Keybinds { - // TODO: leaders - return .{ - .set = .{ - .bindings = try self.set.bindings.clone(alloc), - .reverse = try self.set.reverse.clone(alloc), - }, - }; + return .{ .set = try self.set.clone(alloc) }; } /// Compare if two of our value are requal. Required by Config. diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 7bf74292a..41b862eeb 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -1089,6 +1089,32 @@ pub const Set = struct { } } + /// Deep clone the set. + pub fn clone(self: *const Set, alloc: Allocator) !Set { + var result: Set = .{ + .bindings = try self.bindings.clone(alloc), + .reverse = try self.reverse.clone(alloc), + }; + + // If we have any leaders we need to clone them. + var it = result.bindings.iterator(); + while (it.next()) |entry| switch (entry.value_ptr.*) { + // No data to clone + .action, .action_unconsumed => {}, + + // Must be deep cloned. + .leader => |*s| { + const ptr = try alloc.create(Set); + errdefer alloc.destroy(ptr); + ptr.* = try s.*.clone(alloc); + errdefer ptr.deinit(alloc); + s.* = ptr; + }, + }; + + return result; + } + /// The hash map context for the set. This defines how the hash map /// gets the hash key and checks for equality. fn Context(comptime KeyType: type) type {