From 1308a141389b80d11f3b6c54ecf43d2cb4e44503 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Fri, 26 Dec 2025 16:50:38 +0100 Subject: [PATCH] fix: crash on cancelling the change theme palette This commit also cleans up the handling of the previous theme variable. --- src/tui/mode/overlay/theme_palette.zig | 41 +++++++++++++++++++++----- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/tui/mode/overlay/theme_palette.zig b/src/tui/mode/overlay/theme_palette.zig index b0dbca3..a58e984 100644 --- a/src/tui/mode/overlay/theme_palette.zig +++ b/src/tui/mode/overlay/theme_palette.zig @@ -24,19 +24,22 @@ pub const Match = struct { matches: []const usize, }; -var previous_theme: ?[]const u8 = null; +pub const ValueType = struct { + previous_theme: ?[]const u8 = null, +}; +pub const defaultValue: ValueType = .{}; pub fn load_entries(palette: *Type) !usize { var longest_hint: usize = 0; var idx: usize = 0; - previous_theme = tui.theme().name; + try set_previous_theme(palette, tui.theme().name); for (Widget.themes) |theme| { idx += 1; (try palette.entries.addOne(palette.allocator)).* = .{ .label = theme.description, .name = theme.name, }; - if (previous_theme) |theme_name| if (std.mem.eql(u8, theme.name, theme_name)) { + if (get_previous_theme(palette)) |theme_name| if (std.mem.eql(u8, theme.name, theme_name)) { palette.initial_selected = idx; }; longest_hint = @max(longest_hint, theme.name.len); @@ -45,6 +48,27 @@ pub fn load_entries(palette: *Type) !usize { return longest_hint; } +pub fn deinit(palette: *Type) void { + clear_previous_theme(palette); +} + +fn clear_previous_theme(palette: *Type) void { + tp.trace(tp.channel.debug, .{ "clear_previous_theme", palette.value.previous_theme }); + if (palette.value.previous_theme) |old| palette.allocator.free(old); + palette.value.previous_theme = null; +} + +fn set_previous_theme(palette: *Type, theme: []const u8) error{OutOfMemory}!void { + tp.trace(tp.channel.debug, .{ "set_previous_theme", palette.value.previous_theme, theme }); + clear_previous_theme(palette); + palette.value.previous_theme = try palette.allocator.dupe(u8, theme); +} + +fn get_previous_theme(palette: *Type) ?[]const u8 { + tp.trace(tp.channel.debug, .{ "get_previous_theme", palette.value.previous_theme }); + return palette.value.previous_theme; +} + pub fn add_menu_entry(palette: *Type, entry: *Entry, matches: ?[]const usize) !void { var value: std.Io.Writer.Allocating = .init(palette.allocator); defer value.deinit(); @@ -57,15 +81,16 @@ pub fn add_menu_entry(palette: *Type, entry: *Entry, matches: ?[]const usize) !v } fn select(menu: **Type.MenuType, button: *Type.ButtonType, _: Type.Pos) void { + const palette = menu.*.opts.ctx; var description_: []const u8 = undefined; var name_: []const u8 = undefined; var iter = button.opts.label; if (!(cbor.matchString(&iter, &description_) catch false)) return; if (!(cbor.matchString(&iter, &name_) catch false)) return; - if (previous_theme) |prev| if (std.mem.eql(u8, prev, name_)) + if (get_previous_theme(palette)) |prev| if (std.mem.eql(u8, prev, name_)) return; - tp.self_pid().send(.{ "cmd", "set_theme", .{name_} }) catch |e| menu.*.opts.ctx.logger.err("theme_palette", e); - tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err("theme_palette", e); + tp.self_pid().send(.{ "cmd", "set_theme", .{name_} }) catch |e| palette.logger.err("theme_palette", e); + tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| palette.logger.err("theme_palette", e); } pub fn updated(palette: *Type, button_: ?*Type.ButtonType) !void { @@ -79,8 +104,8 @@ pub fn updated(palette: *Type, button_: ?*Type.ButtonType) !void { } pub fn cancel(palette: *Type) !void { - if (previous_theme) |name_| if (!std.mem.eql(u8, name_, tui.theme().name)) { - previous_theme = null; + if (get_previous_theme(palette)) |name_| if (!std.mem.eql(u8, name_, tui.theme().name)) { tp.self_pid().send(.{ "cmd", "set_theme", .{name_} }) catch |e| palette.logger.err("theme_palette cancel", e); + clear_previous_theme(palette); }; }