input: binding set needs to clean up leader memory on manual put

This commit is contained in:
Mitchell Hashimoto
2024-08-15 19:55:24 -07:00
committed by Mitchell Hashimoto
parent 2bf20ec32c
commit bfb31c374e

View File

@ -1007,9 +1007,16 @@ pub const Set = struct {
const gop = try self.bindings.getOrPut(alloc, t);
if (gop.found_existing) switch (gop.value_ptr.*) {
// If we have a leader we need to clean up the memory
.leader => |s| {
s.deinit(alloc);
alloc.destroy(s);
},
// If we have an existing binding for this trigger, we have to
// update the reverse mapping to remove the old action.
if (gop.found_existing) {
.action, .action_unconsumed => {
const t_hash = t.hash();
var it = self.reverse.iterator();
while (it.next()) |reverse_entry| it: {
@ -1018,7 +1025,8 @@ pub const Set = struct {
break :it;
}
}
}
},
};
gop.value_ptr.* = if (consumed) .{
.action = action,
@ -1617,6 +1625,26 @@ test "set: parseAndPut sequence preserves reverse mapping" {
}
}
test "set: put overwrites sequence" {
const testing = std.testing;
const alloc = testing.allocator;
var s: Set = .{};
defer s.deinit(alloc);
try s.parseAndPut(alloc, "ctrl+a>b=new_window");
try s.put(alloc, .{
.mods = .{ .ctrl = true },
.key = .{ .translated = .a },
}, .{ .new_window = {} });
// Creates reverse mapping
{
const trigger = s.getTrigger(.{ .new_window = {} }).?;
try testing.expect(trigger.key.translated == .a);
}
}
test "set: maintains reverse mapping" {
const testing = std.testing;
const alloc = testing.allocator;