From 8b50c7a3affc453c43ab980f7ce47dd2bb1eaf45 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Wed, 5 Nov 2025 16:39:35 +0100 Subject: [PATCH] fix: fully deinit keybind.Mode to avoid race when switching modes --- src/keybind/keybind.zig | 23 ++++++++++++++++++----- src/tui/tui.zig | 6 +++--- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/keybind/keybind.zig b/src/keybind/keybind.zig index 92f8a3f..4fe2d67 100644 --- a/src/keybind/keybind.zig +++ b/src/keybind/keybind.zig @@ -100,7 +100,7 @@ const Handler = struct { pub const Mode = struct { allocator: std.mem.Allocator, - input_handler: EventHandler, + input_handler: ?EventHandler, event_handler: ?EventHandler = null, mode: []const u8, @@ -121,11 +121,24 @@ pub const Mode = struct { } pub fn deinit(self: *Mode) void { - if (self.deinit_command) |deinit_command| - deinit_command.execute_const(); - self.allocator.free(self.mode); - self.input_handler.deinit(); + if (self.deinit_command) |deinit_command| deinit_command.execute_const(); if (self.event_handler) |eh| eh.deinit(); + if (self.input_handler) |ih| ih.deinit(); + self.allocator.free(self.mode); + + self.deinit_command = null; + self.event_handler = null; + self.input_handler = null; + self.mode = &.{}; + + self.name = ""; + self.line_numbers = .inherit; + self.keybind_hints = &.{}; + self.cursor_shape = null; + self.selection_style = .normal; + self.init_command = null; + self.deinit_command = null; + self.initialized = false; } }; diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 917fc50..a465633 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -554,7 +554,7 @@ fn active_event_handler(self: *Self) ?EventHandler { fn dispatch_flush_input_event(self: *Self) error{ Exit, NoSpaceLeft }!void { var buf: [32]u8 = undefined; const mode = self.input_mode_ orelse return; - try mode.input_handler.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"})); + if (mode.input_handler) |ih| try ih.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"})); if (mode.event_handler) |eh| try eh.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"})); } @@ -577,8 +577,8 @@ fn dispatch_input(ctx: *anyopaque, cbor_msg: []const u8) void { break :ret false; }) return; - if (self.input_mode_) |mode| - mode.input_handler.send(from, m) catch |e| self.logger.err("input handler", e); + if (self.input_mode_) |mode| if (mode.input_handler) |ih| + ih.send(from, m) catch |e| self.logger.err("input handler", e); } fn dispatch_mouse(ctx: *anyopaque, y: c_int, x: c_int, cbor_msg: []const u8) void {