From 022ef938962a525653eb8df783ba0d603da3eadc Mon Sep 17 00:00:00 2001 From: AnErrupTion Date: Sun, 5 Jul 2026 23:17:33 +0200 Subject: [PATCH] Review part 1 Signed-off-by: AnErrupTion --- res/config.ini | 12 ++-- src/main.zig | 163 +++++++++++-------------------------------------- 2 files changed, 42 insertions(+), 133 deletions(-) diff --git a/res/config.ini b/res/config.ini index 805792f..c57c7f4 100644 --- a/res/config.ini +++ b/res/config.ini @@ -169,18 +169,18 @@ colormix_col3 = 0x20000000 # # The order defines the vertical stack (first item is at the edge). -# Top left -corner_top_left = keys - -# Top right -corner_top_right = clock tty - # Bottom left corner_bottom_left = version # Bottom right corner_bottom_right = labels +# Top left +corner_top_left = keys + +# Top right +corner_top_right = clock tty + # For custom binds: the horizontal limit in characters for each # line of custom binds before moving on to the next. # If null, defaults to the width of the terminal instead. diff --git a/src/main.zig b/src/main.zig index 503936e..f77f63a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2063,22 +2063,15 @@ fn updateSessionSpecifier(self: *Label, ptr: *anyopaque) !void { } const Corner = enum { - corner_bottom_left, - corner_bottom_right, - corner_top_left, - corner_top_right, + bottomLeft, + bottomRight, + topLeft, + topRight, }; const PositionedWidgets = struct { binds: []bool, labels: []bool, - keys: bool = false, - clock: bool = false, - tty: bool = false, - battery: bool = false, - version: bool = false, - numlock: bool = false, - capslock: bool = false, }; fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, current_y: usize, is_left: bool, is_top: bool, positioned: *PositionedWidgets) !bool { @@ -2089,7 +2082,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu var local_x = current_x.*; var local_y = current_y; - var lines_consumed: usize = 0; const labels = [_]?*Label{ &state.shutdown_label, @@ -2109,7 +2101,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu if (local_x + width > state.buffer.width - state.edge_margin.x) { local_x = base_x; if (is_top) local_y += 1 else local_y -= 1; - lines_consumed += 1; } label.positionXY(Position.init(local_x, local_y)); local_x += width + 1; @@ -2117,14 +2108,12 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu if (width + state.edge_margin.x > local_x) { local_x = state.buffer.width - state.edge_margin.x; if (is_top) local_y += 1 else local_y -= 1; - lines_consumed += 1; } label.positionXY(Position.init(local_x - width, local_y)); local_x -= width + 1; } } current_x.* = local_x; - positioned.keys = true; return true; } else if (std.mem.eql(u8, item, "clock") or std.mem.eql(u8, item, "time")) { if (state.config.clock == null) return false; @@ -2136,7 +2125,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.clock_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.clock = true; return true; } else if (std.mem.eql(u8, item, "tty")) { if (!state.config.show_tty) return false; @@ -2148,7 +2136,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.tty_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.tty = true; return true; } else if (std.mem.eql(u8, item, "battery")) { if (state.config.battery_id == null) return false; @@ -2160,7 +2147,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.battery_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.battery = true; return true; } else if (std.mem.eql(u8, item, "version")) { if (state.config.hide_version_string) return false; @@ -2172,7 +2158,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.version_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.version = true; return true; } else if (std.mem.eql(u8, item, "numlock")) { if (state.config.hide_keyboard_locks) return false; @@ -2184,7 +2169,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.numlock_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.numlock = true; return true; } else if (std.mem.eql(u8, item, "capslock")) { if (state.config.hide_keyboard_locks) return false; @@ -2196,7 +2180,6 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu state.capslock_label.positionXY(Position.init(current_x.* - width, current_y)); current_x.* -= width + 1; } - positioned.capslock = true; return true; } else if (std.mem.eql(u8, item, "labels")) { for (state.custom_info.items, 0..) |*info, i| { @@ -2240,7 +2223,7 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu current_x.* = local_x; return true; } else if (std.mem.startsWith(u8, item, "lbl:")) { - const name = item[4..]; + const name = item["lbl:".len..]; for (state.custom_info.items, 0..) |*info, i| { if (std.mem.eql(u8, info.info.name, name)) { if (positioned.labels[i]) return false; @@ -2257,7 +2240,7 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu } } } else if (std.mem.startsWith(u8, item, "cmd:")) { - const key = item[4..]; + const key = item["cmd:".len..]; for (state.custom_binds.items, 0..) |*bind, i| { if (std.mem.eql(u8, bind.key, key)) { if (positioned.binds[i]) return false; @@ -2277,99 +2260,34 @@ fn positionSingleWidget(state: *UiState, item: []const u8, current_x: *usize, cu return false; } -fn positionItem(state: *UiState, item: []const u8, current_x: *usize, current_y: usize, is_left: bool, is_top: bool, positioned: *PositionedWidgets) !bool { +fn positionItem(state: *UiState, item: []const u8, current_x: usize, current_y: usize, is_left: bool, is_top: bool, positioned: *PositionedWidgets) !bool { // Check if item contains a comma for compound widgets - if (std.mem.indexOf(u8, item, ",") != null) { - var it = std.mem.tokenizeAny(u8, item, ","); - var success = false; - - // First, collect all subitems that will be positioned - var subitems: [8][]const u8 = undefined; - var count: usize = 0; - - while (it.next()) |subitem| { - const trimmed = std.mem.trim(u8, subitem, " "); - if (count < subitems.len) { - subitems[count] = trimmed; - count += 1; - } - } - - if (count == 0) return false; - - // Check if we can fit all subitems on this line - var total_width: usize = 0; - for (subitems[0..count]) |subitem| { - // Get width without positioning - const width = try getWidgetWidth(state, subitem); - if (width == 0) continue; - total_width += width + 1; // +1 for spacing - } - if (total_width > 0) total_width -= 1; // Remove last spacing - - // Check if we need to wrap to next line - var line_x = current_x.*; - - // Now position each subitem - for (subitems[0..count]) |subitem| { - if (try positionSingleWidget(state, subitem, &line_x, current_y, is_left, is_top, positioned)) { - success = true; - } - } - - if (success) { - current_x.* = line_x; - } - return success; - } else { - return positionSingleWidget(state, item, current_x, current_y, is_left, is_top, positioned); + if (std.mem.indexOf(u8, item, ",") == null) { + var line_x = current_x; + return positionSingleWidget(state, item, &line_x, current_y, is_left, is_top, positioned); } -} -// Helper function to get widget width without positioning -fn getWidgetWidth(state: *UiState, item: []const u8) !usize { - if (std.mem.eql(u8, item, "keys")) { - if (state.config.hide_key_hints) return 0; - var total: usize = 0; - const labels = [_]?*Label{ - &state.shutdown_label, - &state.restart_label, - if (state.config.sleep_cmd != null) &state.sleep_label else null, - if (state.config.hibernate_cmd != null) &state.hibernate_label else null, - &state.toggle_password_label, - if (state.config.brightness_down_key != null) &state.brightness_down_label else null, - if (state.config.brightness_up_key != null) &state.brightness_up_label else null, - }; - for (labels) |maybe_label| { - const label = maybe_label orelse continue; - total += TerminalBuffer.strWidth(label.text) + 1; + var it = std.mem.tokenizeAny(u8, item, ","); + var success = false; + + // Check if we need to wrap to next line + var line_x = current_x; + + // Now position each subitem + while (it.next()) |subitem| { + const trimmed = std.mem.trim(u8, subitem, " "); + + if (try positionSingleWidget(state, trimmed, &line_x, current_y, is_left, is_top, positioned)) { + success = true; } - return if (total > 0) total - 1 else 0; - } else if (std.mem.eql(u8, item, "numlock")) { - if (state.config.hide_keyboard_locks) return 0; - return TerminalBuffer.strWidth(state.lang.numlock); - } else if (std.mem.eql(u8, item, "capslock")) { - if (state.config.hide_keyboard_locks) return 0; - return TerminalBuffer.strWidth(state.lang.capslock); - } else if (std.mem.eql(u8, item, "clock") or std.mem.eql(u8, item, "time")) { - if (state.config.clock == null) return 0; - return TerminalBuffer.strWidth(state.clock_label.text); - } else if (std.mem.eql(u8, item, "tty")) { - if (!state.config.show_tty) return 0; - return TerminalBuffer.strWidth(state.tty_label.text); - } else if (std.mem.eql(u8, item, "battery")) { - if (state.config.battery_id == null) return 0; - return TerminalBuffer.strWidth(state.battery_label.text); - } else if (std.mem.eql(u8, item, "version")) { - if (state.config.hide_version_string) return 0; - return TerminalBuffer.strWidth(state.version_label.text); } - return 0; + + return success; } fn positionCorner(state: *UiState, config_str: []const u8, corner: Corner, positioned: *PositionedWidgets) !void { - const is_left = corner == .corner_top_left or corner == .corner_bottom_left; - const is_top = corner == .corner_top_left or corner == .corner_top_right; + const is_left = corner == .topLeft or corner == .bottomLeft; + const is_top = corner == .topLeft or corner == .topRight; var y_offset: usize = 0; var i: usize = 0; @@ -2382,25 +2300,16 @@ fn positionCorner(state: *UiState, config_str: []const u8, corner: Corner, posit } if (i >= len) break; - var token: []const u8 = undefined; - if (config_str[i] == '"') { + const start = i; + while (i < len and config_str[i] != ' ' and config_str[i] != '\t' and config_str[i] != '[' and config_str[i] != ']') { i += 1; - const start = i; - while (i < len and config_str[i] != '"') i += 1; - token = config_str[start..i]; - if (i < len) i += 1; // skip closing quote - } else { - const start = i; - while (i < len and config_str[i] != ' ' and config_str[i] != '\t' and config_str[i] != '[' and config_str[i] != ']') { - i += 1; - } - token = config_str[start..i]; } + const token = config_str[start..i]; - var current_x = if (is_left) state.edge_margin.x else state.buffer.width - state.edge_margin.x; + const current_x = if (is_left) state.edge_margin.x else state.buffer.width - state.edge_margin.x; const current_y = if (is_top) state.edge_margin.y + y_offset else state.buffer.height - 1 - state.edge_margin.y - y_offset; - if (try positionItem(state, token, ¤t_x, current_y, is_left, is_top, positioned)) { + if (try positionItem(state, token, current_x, current_y, is_left, is_top, positioned)) { y_offset += 1; } } @@ -2409,7 +2318,7 @@ fn positionCorner(state: *UiState, config_str: []const u8, corner: Corner, posit fn positionWidgets(ptr: *anyopaque) !void { var state: *UiState = @ptrCast(@alignCast(ptr)); - const offscreen = Position.init(9999, 9999); + const offscreen = Position.init(state.buffer.width + 1, state.buffer.height + 1); // Reset all potential corner widgets to offscreen state.shutdown_label.positionXY(offscreen); @@ -2443,10 +2352,10 @@ fn positionWidgets(ptr: *anyopaque) !void { @memset(positioned.binds, false); @memset(positioned.labels, false); - try positionCorner(state, state.config.corner_top_left, .corner_top_left, &positioned); - try positionCorner(state, state.config.corner_top_right, .corner_top_right, &positioned); - try positionCorner(state, state.config.corner_bottom_left, .corner_bottom_left, &positioned); - try positionCorner(state, state.config.corner_bottom_right, .corner_bottom_right, &positioned); + try positionCorner(state, state.config.corner_top_left, .topLeft, &positioned); + try positionCorner(state, state.config.corner_top_right, .topRight, &positioned); + try positionCorner(state, state.config.corner_bottom_left, .bottomLeft, &positioned); + try positionCorner(state, state.config.corner_bottom_right, .bottomRight, &positioned); var bb_height = state.box.height; var bb_width = state.box.width;