Implement configuration for the Bar
This adds a few new options for the bar (instead of hardcoding all of them). fonts, text_color, background_color, positoon, and margins. Also fixed a couple of bugs when reloading the config and destroying layer shell and wl surfaces in the wrong order.
This commit is contained in:
parent
ce9a972b60
commit
5922107579
9 changed files with 371 additions and 84 deletions
|
|
@ -71,6 +71,38 @@ borders {
|
||||||
|
|
||||||
Colors are specified in `0xRRGGBB` or `0xRRGGBBAA` hex format.
|
Colors are specified in `0xRRGGBB` or `0xRRGGBBAA` hex format.
|
||||||
|
|
||||||
|
## Bar
|
||||||
|
|
||||||
|
The bar is an optional widget that shows the time on your screen. Right now, that's it.
|
||||||
|
It is only created when a `bar` block is present in the config. All settings have
|
||||||
|
defaults, with the color based on the Catppuccin Mocha theme. An empty block can be used
|
||||||
|
to enable the widget with all defaults:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
bar {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bar Settings
|
||||||
|
|
||||||
|
| Setting | Type | Default | Description |
|
||||||
|
|--------------------|--------|--------------------|-----------------------------------|
|
||||||
|
| `fonts` | string | `monospace:size=14` | Comma-separated FontConfig fonts |
|
||||||
|
| `text_color` | color | `0xcdd6f4` | Text color |
|
||||||
|
| `background_color` | color | `0x1e1e2e` | Background color |
|
||||||
|
| `position` | enum | `top` | Bar position (`top` or `bottom`) |
|
||||||
|
|
||||||
|
### Margins
|
||||||
|
|
||||||
|
The `margins` child block sets pixel offsets from the anchored edge(s).
|
||||||
|
|
||||||
|
| Setting | Type | Default |
|
||||||
|
|----------|------|---------|
|
||||||
|
| `top` | i32 | `0` |
|
||||||
|
| `right` | i32 | `0` |
|
||||||
|
| `bottom` | i32 | `0` |
|
||||||
|
| `left` | i32 | `0` |
|
||||||
|
|
||||||
## Tag Overlay
|
## Tag Overlay
|
||||||
|
|
||||||
The tag overlay is an optional widget that briefly shows your tag state when switching tags.
|
The tag overlay is an optional widget that briefly shows your tag state when switching tags.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
These are in rough order of my priority, though no promises I do them in this order.
|
These are in rough order of my priority, though no promises I do them in this order.
|
||||||
|
|
||||||
- [ ] Add options to the bar
|
|
||||||
- [ ] Make a Rect struct to combine x, y, width, and height
|
- [ ] Make a Rect struct to combine x, y, width, and height
|
||||||
- [ ] Support window rules (float/tags/SSD by app-id/title)
|
- [ ] Support window rules (float/tags/SSD by app-id/title)
|
||||||
- [ ] Support overriding config location
|
- [ ] Support overriding config location
|
||||||
|
|
@ -31,3 +30,4 @@ These are in rough order of my priority, though no promises I do them in this or
|
||||||
- [x] Implement an optional clock bar
|
- [x] Implement an optional clock bar
|
||||||
- [x] Implement a river-tag-overlay clone
|
- [x] Implement a river-tag-overlay clone
|
||||||
- [x] Add options to the tag overlay
|
- [x] Add options to the tag overlay
|
||||||
|
- [x] Add options to the bar
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,11 @@ borders {
|
||||||
color_focused "0x89b4fa"
|
color_focused "0x89b4fa"
|
||||||
color_unfocused "0x1e1e2e"
|
color_unfocused "0x1e1e2e"
|
||||||
}
|
}
|
||||||
// Tag overlay widget — shown briefly when switching tags
|
// Bar widget - shows the time
|
||||||
|
bar {
|
||||||
|
position top
|
||||||
|
}
|
||||||
|
// Tag overlay widget - shown briefly when switching tags
|
||||||
// Remove this block to disable the overlay entirely
|
// Remove this block to disable the overlay entirely
|
||||||
tag_overlay {
|
tag_overlay {
|
||||||
tag_amount 10
|
tag_amount 10
|
||||||
|
|
|
||||||
69
src/Bar.zig
69
src/Bar.zig
|
|
@ -12,8 +12,10 @@ context: *Context,
|
||||||
/// The timezone of the computer.
|
/// The timezone of the computer.
|
||||||
timezone: zeit.timezone.TimeZone,
|
timezone: zeit.timezone.TimeZone,
|
||||||
|
|
||||||
fonts: *fcft.Font,
|
options: Options,
|
||||||
font_scale: u31 = 0,
|
|
||||||
|
fcft_fonts: *fcft.Font,
|
||||||
|
font_scale: u31,
|
||||||
|
|
||||||
output: *Output,
|
output: *Output,
|
||||||
|
|
||||||
|
|
@ -28,22 +30,40 @@ surfaces: ?struct {
|
||||||
|
|
||||||
configured: bool = false,
|
configured: bool = false,
|
||||||
|
|
||||||
pub fn init(context: *Context, output: *Output) !Bar {
|
pub const Position = enum { top, bottom };
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
/// Comma separated list of FontConfig formatted font specifications
|
||||||
|
fonts: []const u8 = "monospace:size=14",
|
||||||
|
/// Color of text on the bar
|
||||||
|
text_color: pixman.Color = utils.parseRgbaPixmanComptime("0xcdd6f4"),
|
||||||
|
/// Background color of the bar
|
||||||
|
background_color: pixman.Color = utils.parseRgbaPixmanComptime("0x1e1e2e"),
|
||||||
|
|
||||||
|
/// Whether the bar is at the top or bottom of the screen
|
||||||
|
position: Position = .top,
|
||||||
|
/// Directional margins top, right, bottom, left, in pixels
|
||||||
|
margins: struct { top: i32 = 0, right: i32 = 0, bottom: i32 = 0, left: i32 = 0 } = .{},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(context: *Context, output: *Output, options: Options) !Bar {
|
||||||
const timezone = try zeit.local(utils.gpa, &context.env);
|
const timezone = try zeit.local(utils.gpa, &context.env);
|
||||||
errdefer timezone.deinit();
|
errdefer timezone.deinit();
|
||||||
|
|
||||||
const fonts = try getFcftFonts("monospace:size=14", 1);
|
const scale = output.scale;
|
||||||
errdefer fonts.destroy();
|
const fcft_fonts = try getFcftFonts(options.fonts, scale);
|
||||||
|
errdefer fcft_fonts.destroy();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.context = context,
|
.context = context,
|
||||||
.fonts = fonts,
|
.options = options,
|
||||||
|
.fcft_fonts = fcft_fonts,
|
||||||
|
.font_scale = scale,
|
||||||
.timezone = timezone,
|
.timezone = timezone,
|
||||||
.output = output,
|
.output = output,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add config options for whether it's top or bottom
|
|
||||||
pub fn initSurface(bar: *Bar) !void {
|
pub fn initSurface(bar: *Bar) !void {
|
||||||
if (bar.surfaces) |_| {
|
if (bar.surfaces) |_| {
|
||||||
// This bar already has a surface, we can exit early
|
// This bar already has a surface, we can exit early
|
||||||
|
|
@ -51,6 +71,7 @@ pub fn initSurface(bar: *Bar) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = bar.context;
|
const context = bar.context;
|
||||||
|
const options = bar.options;
|
||||||
|
|
||||||
const wl_surface = try context.wl_compositor.createSurface();
|
const wl_surface = try context.wl_compositor.createSurface();
|
||||||
errdefer wl_surface.destroy();
|
errdefer wl_surface.destroy();
|
||||||
|
|
@ -60,7 +81,6 @@ pub fn initSurface(bar: *Bar) !void {
|
||||||
.getLayerSurface(wl_surface, bar.output.wl_output, .top, "beansprout-bar");
|
.getLayerSurface(wl_surface, bar.output.wl_output, .top, "beansprout-bar");
|
||||||
errdefer layer_surface.destroy();
|
errdefer layer_surface.destroy();
|
||||||
|
|
||||||
// TODO: Allow clicking on tags to switch between them?
|
|
||||||
// We don't want our surface to have any input region (default is infinite)
|
// We don't want our surface to have any input region (default is infinite)
|
||||||
const empty_region = try context.wl_compositor.createRegion();
|
const empty_region = try context.wl_compositor.createRegion();
|
||||||
defer empty_region.destroy();
|
defer empty_region.destroy();
|
||||||
|
|
@ -68,9 +88,11 @@ pub fn initSurface(bar: *Bar) !void {
|
||||||
|
|
||||||
// TODO: Add padding to config
|
// TODO: Add padding to config
|
||||||
const vertical_padding = 5;
|
const vertical_padding = 5;
|
||||||
const bar_height: u31 = @intCast(bar.fonts.height + 2 * vertical_padding);
|
const bar_height: u31 = @intCast(bar.fcft_fonts.height + 2 * vertical_padding);
|
||||||
layer_surface.setSize(0, bar_height);
|
layer_surface.setSize(0, bar_height);
|
||||||
layer_surface.setAnchor(.{ .top = true, .right = true, .left = true });
|
|
||||||
|
layer_surface.setAnchor(.{ .top = options.position == .top, .bottom = options.position == .bottom, .left = true, .right = true });
|
||||||
|
layer_surface.setMargin(options.margins.top, options.margins.right, options.margins.bottom, options.margins.left);
|
||||||
|
|
||||||
bar.surfaces = .{
|
bar.surfaces = .{
|
||||||
.wl_surface = wl_surface,
|
.wl_surface = wl_surface,
|
||||||
|
|
@ -85,10 +107,9 @@ pub fn initSurface(bar: *Bar) !void {
|
||||||
pub fn deinit(bar: *Bar) void {
|
pub fn deinit(bar: *Bar) void {
|
||||||
bar.configured = false;
|
bar.configured = false;
|
||||||
bar.timezone.deinit();
|
bar.timezone.deinit();
|
||||||
bar.fonts.destroy();
|
|
||||||
if (bar.surfaces) |surfaces| {
|
if (bar.surfaces) |surfaces| {
|
||||||
surfaces.wl_surface.destroy();
|
|
||||||
surfaces.layer_surface.destroy();
|
surfaces.layer_surface.destroy();
|
||||||
|
surfaces.wl_surface.destroy();
|
||||||
bar.context.buffer_pool.surface_count -= 1;
|
bar.context.buffer_pool.surface_count -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -144,13 +165,14 @@ pub fn layerSurfaceListener(
|
||||||
/// Renders the bar and its components
|
/// Renders the bar and its components
|
||||||
pub fn render(bar: *Bar) !void {
|
pub fn render(bar: *Bar) !void {
|
||||||
const context = bar.context;
|
const context = bar.context;
|
||||||
|
const options = bar.options;
|
||||||
|
|
||||||
const scale = bar.output.scale;
|
const scale = bar.output.scale;
|
||||||
|
|
||||||
// Recreate fonts at the output's new scale
|
// Recreate fonts at the output's new scale
|
||||||
if (scale != bar.font_scale) {
|
if (scale != bar.font_scale) {
|
||||||
bar.fonts.destroy();
|
bar.fcft_fonts.destroy();
|
||||||
bar.fonts = try getFcftFonts("monospace:size=14", scale);
|
bar.fcft_fonts = try getFcftFonts(bar.options.fonts, scale);
|
||||||
bar.font_scale = scale;
|
bar.font_scale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,8 +187,7 @@ pub fn render(bar: *Bar) !void {
|
||||||
const buffer = try context.buffer_pool.nextBuffer(bar.context.wl_shm, render_width, render_height);
|
const buffer = try context.buffer_pool.nextBuffer(bar.context.wl_shm, render_width, render_height);
|
||||||
|
|
||||||
// Fill with a solid color (e.g., dark background)
|
// Fill with a solid color (e.g., dark background)
|
||||||
// TODO: Configure text/bg colors
|
const bg_color = options.background_color;
|
||||||
const bg_color: pixman.Color = .{ .red = 0x1e1e, .green = 0x1e1e, .blue = 0x2e2e, .alpha = 0xffff };
|
|
||||||
_ = pixman.Image.fillRectangles(
|
_ = pixman.Image.fillRectangles(
|
||||||
.src,
|
.src,
|
||||||
buffer.pixman_image,
|
buffer.pixman_image,
|
||||||
|
|
@ -181,7 +202,7 @@ pub fn render(bar: *Bar) !void {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set-up text color
|
// Set-up text color
|
||||||
const text_color: pixman.Color = .{ .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff };
|
const text_color = options.text_color;
|
||||||
const color = pixman.Image.createSolidFill(&text_color) orelse return error.FailedToCreatePixmanImage;
|
const color = pixman.Image.createSolidFill(&text_color) orelse return error.FailedToCreatePixmanImage;
|
||||||
defer _ = color.unref();
|
defer _ = color.unref();
|
||||||
|
|
||||||
|
|
@ -214,7 +235,7 @@ pub fn render(bar: *Bar) !void {
|
||||||
|
|
||||||
const text_width = try bar.textWidth(codepoints);
|
const text_width = try bar.textWidth(codepoints);
|
||||||
var x: i32 = @divFloor(buffer.width - text_width, 2);
|
var x: i32 = @divFloor(buffer.width - text_width, 2);
|
||||||
const y: i32 = @divFloor(buffer.height - bar.fonts.height, 2);
|
const y: i32 = @divFloor(buffer.height - bar.fcft_fonts.height, 2);
|
||||||
|
|
||||||
// Actually render the unicode codepoints
|
// Actually render the unicode codepoints
|
||||||
try bar.renderChars(codepoints, buffer, &x, y, color);
|
try bar.renderChars(codepoints, buffer, &x, y, color);
|
||||||
|
|
@ -233,11 +254,11 @@ pub fn render(bar: *Bar) !void {
|
||||||
fn textWidth(bar: *Bar, text: []const u32) !i32 {
|
fn textWidth(bar: *Bar, text: []const u32) !i32 {
|
||||||
var width: i32 = 0;
|
var width: i32 = 0;
|
||||||
for (text, 0..) |cp, i| {
|
for (text, 0..) |cp, i| {
|
||||||
const glyph = try bar.fonts.rasterizeCharUtf32(cp, .default);
|
const glyph = try bar.fcft_fonts.rasterizeCharUtf32(cp, .default);
|
||||||
width += glyph.advance.x;
|
width += glyph.advance.x;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
var x_kern: c_long = 0;
|
var x_kern: c_long = 0;
|
||||||
if (bar.fonts.kerning(text[i - 1], cp, &x_kern, null)) {
|
if (bar.fcft_fonts.kerning(text[i - 1], cp, &x_kern, null)) {
|
||||||
width += @intCast(x_kern);
|
width += @intCast(x_kern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -261,12 +282,12 @@ fn renderChars(
|
||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < text.len) : (i += 1) {
|
while (i < text.len) : (i += 1) {
|
||||||
glyphs[i] = try bar.fonts.rasterizeCharUtf32(text[i], .default);
|
glyphs[i] = try bar.fcft_fonts.rasterizeCharUtf32(text[i], .default);
|
||||||
|
|
||||||
kerns[i] = 0;
|
kerns[i] = 0;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
var x_kern: c_long = 0;
|
var x_kern: c_long = 0;
|
||||||
if (bar.fonts.kerning(text[i - 1], text[i], &x_kern, null)) {
|
if (bar.fcft_fonts.kerning(text[i - 1], text[i], &x_kern, null)) {
|
||||||
kerns[i] = x_kern;
|
kerns[i] = x_kern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -303,7 +324,7 @@ fn renderGlyphs(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
x.* + @as(i32, @intCast(glyphs[i].x)),
|
x.* + @as(i32, @intCast(glyphs[i].x)),
|
||||||
y + bar.fonts.ascent - @as(i32, @intCast(glyphs[i].y)),
|
y + bar.fcft_fonts.ascent - @as(i32, @intCast(glyphs[i].y)),
|
||||||
glyphs[i].width,
|
glyphs[i].width,
|
||||||
glyphs[i].height,
|
glyphs[i].height,
|
||||||
);
|
);
|
||||||
|
|
@ -320,7 +341,7 @@ fn renderGlyphs(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
x.* + @as(i32, @intCast(glyphs[i].x)),
|
x.* + @as(i32, @intCast(glyphs[i].x)),
|
||||||
y + bar.fonts.ascent - @as(i32, @intCast(glyphs[i].y)),
|
y + bar.fcft_fonts.ascent - @as(i32, @intCast(glyphs[i].y)),
|
||||||
glyphs[i].width,
|
glyphs[i].width,
|
||||||
glyphs[i].height,
|
glyphs[i].height,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,9 @@ pointer_warp_on_focus_change: bool = true,
|
||||||
wallpaper_image_path: ?[]const u8 = null,
|
wallpaper_image_path: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Tag overlay configuration. If null, no overlay is created.
|
/// Tag overlay configuration. If null, no overlay is created.
|
||||||
tag_overlay: ?TagOverlayConfig = null,
|
tag_overlay_config: ?TagOverlayConfig = null,
|
||||||
|
/// Bar configuration. If null, no bar is created.
|
||||||
|
bar_config: ?BarConfig = null,
|
||||||
|
|
||||||
/// Tag bind entries parsed from config (tag_bind nodes in keybinds block)
|
/// Tag bind entries parsed from config (tag_bind nodes in keybinds block)
|
||||||
tag_binds: std.ArrayList(Keybind) = .{},
|
tag_binds: std.ArrayList(Keybind) = .{},
|
||||||
|
|
@ -44,6 +46,7 @@ input_configs: std.ArrayList(InputConfig) = .{},
|
||||||
pub const Keybind = keybind_helper.Keybind;
|
pub const Keybind = keybind_helper.Keybind;
|
||||||
pub const PointerBind = pointer_bind_helper.PointerBind;
|
pub const PointerBind = pointer_bind_helper.PointerBind;
|
||||||
|
|
||||||
|
pub const BarConfig = bar_helper.BarConfig;
|
||||||
pub const TagOverlayConfig = tag_overlay_helper.TagOverlayConfig;
|
pub const TagOverlayConfig = tag_overlay_helper.TagOverlayConfig;
|
||||||
pub const InputConfig = input_helper.InputConfig;
|
pub const InputConfig = input_helper.InputConfig;
|
||||||
|
|
||||||
|
|
@ -60,10 +63,11 @@ const NodeName = enum {
|
||||||
pointer_warp_on_focus_change,
|
pointer_warp_on_focus_change,
|
||||||
wallpaper_image_path,
|
wallpaper_image_path,
|
||||||
// Sections with child blocks
|
// Sections with child blocks
|
||||||
|
bar,
|
||||||
borders,
|
borders,
|
||||||
|
input,
|
||||||
keybinds,
|
keybinds,
|
||||||
pointer_binds,
|
pointer_binds,
|
||||||
input,
|
|
||||||
tag_overlay,
|
tag_overlay,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,6 +106,9 @@ pub fn create() !*Config {
|
||||||
if (ic.name) |name| utils.gpa.free(name);
|
if (ic.name) |name| utils.gpa.free(name);
|
||||||
}
|
}
|
||||||
config.input_configs.clearAndFree(utils.gpa);
|
config.input_configs.clearAndFree(utils.gpa);
|
||||||
|
if (config.bar_config) |bc| {
|
||||||
|
if (bc.fonts) |fonts| utils.gpa.free(fonts);
|
||||||
|
}
|
||||||
if (config.wallpaper_image_path) |path| {
|
if (config.wallpaper_image_path) |path| {
|
||||||
utils.gpa.free(path);
|
utils.gpa.free(path);
|
||||||
}
|
}
|
||||||
|
|
@ -129,6 +136,9 @@ pub fn destroy(config: *Config) void {
|
||||||
if (ic.name) |name| utils.gpa.free(name);
|
if (ic.name) |name| utils.gpa.free(name);
|
||||||
}
|
}
|
||||||
config.input_configs.deinit(utils.gpa);
|
config.input_configs.deinit(utils.gpa);
|
||||||
|
if (config.bar_config) |bc| {
|
||||||
|
if (bc.fonts) |fonts| utils.gpa.free(fonts);
|
||||||
|
}
|
||||||
if (config.wallpaper_image_path) |path| {
|
if (config.wallpaper_image_path) |path| {
|
||||||
utils.gpa.free(path);
|
utils.gpa.free(path);
|
||||||
}
|
}
|
||||||
|
|
@ -231,15 +241,8 @@ fn load(config: *Config, reader: *Io.Reader) !void {
|
||||||
};
|
};
|
||||||
logDebugSettingNode(name, path_str);
|
logDebugSettingNode(name, path_str);
|
||||||
},
|
},
|
||||||
.borders => {
|
.bar => next_child_block = .bar,
|
||||||
next_child_block = .borders;
|
.borders => next_child_block = .borders,
|
||||||
},
|
|
||||||
.keybinds => {
|
|
||||||
next_child_block = .keybinds;
|
|
||||||
},
|
|
||||||
.pointer_binds => {
|
|
||||||
next_child_block = .pointer_binds;
|
|
||||||
},
|
|
||||||
.input => {
|
.input => {
|
||||||
pending_input_name = if (node.prop(&parser, "name")) |n|
|
pending_input_name = if (node.prop(&parser, "name")) |n|
|
||||||
try utils.gpa.dupe(u8, utils.stripQuotes(n))
|
try utils.gpa.dupe(u8, utils.stripQuotes(n))
|
||||||
|
|
@ -247,6 +250,12 @@ fn load(config: *Config, reader: *Io.Reader) !void {
|
||||||
null;
|
null;
|
||||||
next_child_block = .input;
|
next_child_block = .input;
|
||||||
},
|
},
|
||||||
|
.keybinds => {
|
||||||
|
next_child_block = .keybinds;
|
||||||
|
},
|
||||||
|
.pointer_binds => {
|
||||||
|
next_child_block = .pointer_binds;
|
||||||
|
},
|
||||||
.tag_overlay => {
|
.tag_overlay => {
|
||||||
next_child_block = .tag_overlay;
|
next_child_block = .tag_overlay;
|
||||||
},
|
},
|
||||||
|
|
@ -258,6 +267,7 @@ fn load(config: *Config, reader: *Io.Reader) !void {
|
||||||
.child_block_begin => {
|
.child_block_begin => {
|
||||||
if (next_child_block) |child_block| {
|
if (next_child_block) |child_block| {
|
||||||
switch (child_block) {
|
switch (child_block) {
|
||||||
|
.bar => try bar_helper.load(config, &parser, hostname),
|
||||||
.borders => try borders_helper.load(config, &parser, hostname),
|
.borders => try borders_helper.load(config, &parser, hostname),
|
||||||
.keybinds => try keybind_helper.load(config, &parser, hostname),
|
.keybinds => try keybind_helper.load(config, &parser, hostname),
|
||||||
.pointer_binds => try pointer_bind_helper.load(config, &parser, hostname),
|
.pointer_binds => try pointer_bind_helper.load(config, &parser, hostname),
|
||||||
|
|
@ -311,6 +321,7 @@ const utils = @import("utils.zig");
|
||||||
const RiverColor = utils.RiverColor;
|
const RiverColor = utils.RiverColor;
|
||||||
const XkbBindings = @import("XkbBindings.zig");
|
const XkbBindings = @import("XkbBindings.zig");
|
||||||
|
|
||||||
|
const bar_helper = @import("config/bar.zig");
|
||||||
const borders_helper = @import("config/borders.zig");
|
const borders_helper = @import("config/borders.zig");
|
||||||
const input_helper = @import("config/input.zig");
|
const input_helper = @import("config/input.zig");
|
||||||
const keybind_helper = @import("config/keybinds.zig");
|
const keybind_helper = @import("config/keybinds.zig");
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ pub fn create(options: Options) !*Context {
|
||||||
const env = try process.getEnvMap(utils.gpa);
|
const env = try process.getEnvMap(utils.gpa);
|
||||||
errdefer env.deinit();
|
errdefer env.deinit();
|
||||||
|
|
||||||
const tag_overlay_timer_fd: ?posix.fd_t = if (options.config.tag_overlay) |_|
|
const tag_overlay_timer_fd: ?posix.fd_t = if (options.config.tag_overlay_config) |_|
|
||||||
posix.timerfd_create(.MONOTONIC, .{ .CLOEXEC = true }) catch |e| blk: {
|
posix.timerfd_create(.MONOTONIC, .{ .CLOEXEC = true }) catch |e| blk: {
|
||||||
log.err("Failed to create tag overlay timer: {}", .{e});
|
log.err("Failed to create tag overlay timer: {}", .{e});
|
||||||
break :blk null;
|
break :blk null;
|
||||||
|
|
@ -133,6 +133,10 @@ pub fn manage(context: *Context) void {
|
||||||
binding.destroy();
|
binding.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Capture old config state before destroying
|
||||||
|
const had_overlay = context.config.tag_overlay_config != null;
|
||||||
|
const had_bar = context.config.bar_config != null;
|
||||||
|
|
||||||
// Check if wallpaper path changed before destroying old config
|
// Check if wallpaper path changed before destroying old config
|
||||||
const wallpaper_changed = !pathsEqual(
|
const wallpaper_changed = !pathsEqual(
|
||||||
context.config.wallpaper_image_path,
|
context.config.wallpaper_image_path,
|
||||||
|
|
@ -150,8 +154,7 @@ pub fn manage(context: *Context) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle tag overlay config changes
|
// Handle tag overlay config changes
|
||||||
const had_overlay = context.config.tag_overlay != null;
|
const has_overlay = new_config.tag_overlay_config != null;
|
||||||
const has_overlay = new_config.tag_overlay != null;
|
|
||||||
|
|
||||||
if (!had_overlay and has_overlay) {
|
if (!had_overlay and has_overlay) {
|
||||||
// Create timerfd for newly enabled tag overlay
|
// Create timerfd for newly enabled tag overlay
|
||||||
|
|
@ -176,7 +179,7 @@ pub fn manage(context: *Context) void {
|
||||||
}
|
}
|
||||||
// Create new overlay if configured
|
// Create new overlay if configured
|
||||||
// Create new overlay struct if configured (surfaces created on-demand)
|
// Create new overlay struct if configured (surfaces created on-demand)
|
||||||
if (new_config.tag_overlay) |tag_overlay_config| {
|
if (new_config.tag_overlay_config) |tag_overlay_config| {
|
||||||
output.tag_overlay = TagOverlay.init(context, output, tag_overlay_config.toTagOverlayOptions()) catch |e| {
|
output.tag_overlay = TagOverlay.init(context, output, tag_overlay_config.toTagOverlayOptions()) catch |e| {
|
||||||
log.err("Failed to create tag overlay: {}", .{e});
|
log.err("Failed to create tag overlay: {}", .{e});
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -185,6 +188,32 @@ pub fn manage(context: *Context) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recreate or destroy bars on all outputs
|
||||||
|
const has_bar = new_config.bar_config != null;
|
||||||
|
if (had_bar or has_bar) {
|
||||||
|
var out_it = context.wm.outputs.iterator(.forward);
|
||||||
|
while (out_it.next()) |output| {
|
||||||
|
// Destroy existing bar
|
||||||
|
if (output.bar) |*bar| {
|
||||||
|
bar.deinit();
|
||||||
|
output.bar = null;
|
||||||
|
}
|
||||||
|
// Create new bar if configured
|
||||||
|
if (new_config.bar_config) |bar_config| {
|
||||||
|
output.bar = Bar.init(context, output, bar_config.toBarOptions()) catch |e| {
|
||||||
|
log.err("Failed to create bar: {}", .{e});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// If the output already has a wl_output, init the surface immediately
|
||||||
|
if (output.wl_output != null) {
|
||||||
|
output.bar.?.initSurface() catch |e| {
|
||||||
|
log.err("Failed to init bar surface: {}", .{e});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wallpaper_changed) {
|
if (wallpaper_changed) {
|
||||||
if (context.wallpaper_image) |img| img.destroy();
|
if (context.wallpaper_image) |img| img.destroy();
|
||||||
context.wallpaper_image = loadWallpaperImage(new_config);
|
context.wallpaper_image = loadWallpaperImage(new_config);
|
||||||
|
|
@ -239,6 +268,7 @@ const wl = wayland.client.wl;
|
||||||
const zwlr = wayland.client.zwlr;
|
const zwlr = wayland.client.zwlr;
|
||||||
|
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
|
const Bar = @import("Bar.zig");
|
||||||
const BufferPool = @import("BufferPool.zig");
|
const BufferPool = @import("BufferPool.zig");
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
const InputManager = @import("InputManager.zig");
|
const InputManager = @import("InputManager.zig");
|
||||||
|
|
|
||||||
|
|
@ -92,13 +92,15 @@ pub fn create(context: *Context, river_output_v1: *river.OutputV1) !*Output {
|
||||||
var output = try utils.gpa.create(Output);
|
var output = try utils.gpa.create(Output);
|
||||||
errdefer utils.gpa.destroy(output);
|
errdefer utils.gpa.destroy(output);
|
||||||
|
|
||||||
var bar = Bar.init(context, output) catch |e| blk: {
|
var bar = if (context.config.bar_config) |bar_config| blk: {
|
||||||
log.err("Failed to create a bar: {}", .{e});
|
break :blk Bar.init(context, output, bar_config.toBarOptions()) catch |e| {
|
||||||
break :blk null;
|
log.err("Failed to create a bar: {}", .{e});
|
||||||
};
|
break :blk null;
|
||||||
|
};
|
||||||
|
} else null;
|
||||||
errdefer if (bar) |*b| b.deinit();
|
errdefer if (bar) |*b| b.deinit();
|
||||||
|
|
||||||
var tag_overlay = if (context.config.tag_overlay) |tag_overlay_config| blk: {
|
var tag_overlay = if (context.config.tag_overlay_config) |tag_overlay_config| blk: {
|
||||||
break :blk TagOverlay.init(context, output, tag_overlay_config.toTagOverlayOptions()) catch |e| {
|
break :blk TagOverlay.init(context, output, tag_overlay_config.toTagOverlayOptions()) catch |e| {
|
||||||
log.err("Failed to create a tag overlay: {}", .{e});
|
log.err("Failed to create a tag overlay: {}", .{e});
|
||||||
break :blk null;
|
break :blk null;
|
||||||
|
|
@ -377,8 +379,8 @@ pub fn initWallpaperLayerSurface(output: *Output) !void {
|
||||||
|
|
||||||
pub fn deinitWallpaperLayerSurface(output: *Output) void {
|
pub fn deinitWallpaperLayerSurface(output: *Output) void {
|
||||||
if (output.surfaces) |surfaces| {
|
if (output.surfaces) |surfaces| {
|
||||||
surfaces.wl_surface.destroy();
|
|
||||||
surfaces.layer_surface.destroy();
|
surfaces.layer_surface.destroy();
|
||||||
|
surfaces.wl_surface.destroy();
|
||||||
output.context.buffer_pool.surface_count -= 1;
|
output.context.buffer_pool.surface_count -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
186
src/config/bar.zig
Normal file
186
src/config/bar.zig
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 Ben Buhse <me@benbuhse.email>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
pub const NodeName = enum {
|
||||||
|
fonts,
|
||||||
|
text_color,
|
||||||
|
background_color,
|
||||||
|
position,
|
||||||
|
margins,
|
||||||
|
};
|
||||||
|
pub const MarginsNodeName = enum { top, right, bottom, left };
|
||||||
|
|
||||||
|
pub const BarConfig = struct {
|
||||||
|
// Comma separated list of FontConfig formatted font specifications.
|
||||||
|
// null means use the default ("monospace:size=14").
|
||||||
|
fonts: ?[]const u8 = null,
|
||||||
|
text_color: pixman.Color = utils.parseRgbaPixmanComptime("0xcdd6f4"),
|
||||||
|
background_color: pixman.Color = utils.parseRgbaPixmanComptime("0x1e1e2e"),
|
||||||
|
position: Bar.Position = .top,
|
||||||
|
margin_top: i32 = 0,
|
||||||
|
margin_right: i32 = 0,
|
||||||
|
margin_bottom: i32 = 0,
|
||||||
|
margin_left: i32 = 0,
|
||||||
|
// TODO: Support only having the bar on specific outputs
|
||||||
|
// output: []const u8,
|
||||||
|
|
||||||
|
pub fn toBarOptions(config: BarConfig) Bar.Options {
|
||||||
|
return .{
|
||||||
|
.fonts = config.fonts orelse "monospace:size=14",
|
||||||
|
.text_color = config.text_color,
|
||||||
|
.background_color = config.background_color,
|
||||||
|
.position = config.position,
|
||||||
|
.margins = .{
|
||||||
|
.top = config.margin_top,
|
||||||
|
.right = config.margin_right,
|
||||||
|
.bottom = config.margin_bottom,
|
||||||
|
.left = config.margin_left,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn load(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
||||||
|
config.bar_config = .{}; // Presence of block = enabled; initialize with defaults
|
||||||
|
|
||||||
|
const BarChild = enum { margins };
|
||||||
|
var next_child_block: ?BarChild = null;
|
||||||
|
|
||||||
|
while (try parser.next()) |event| {
|
||||||
|
switch (event) {
|
||||||
|
.node => |node| {
|
||||||
|
if (next_child_block) |child| {
|
||||||
|
log.warn("Expected child block for bar.{s}, got node instead. Ignoring", .{@tagName(child)});
|
||||||
|
next_child_block = null;
|
||||||
|
}
|
||||||
|
const node_name = std.meta.stringToEnum(NodeName, node.name);
|
||||||
|
if (node_name) |name| {
|
||||||
|
if (!helpers.hostMatches(node, parser, hostname)) {
|
||||||
|
logDebugHostMismatch(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const val_str = utils.stripQuotes(node.arg(parser, 0) orelse "");
|
||||||
|
switch (name) {
|
||||||
|
.fonts => {
|
||||||
|
if (node.argcount() < 1) {
|
||||||
|
logWarnMissingNodeArg(name, "font specification");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
config.bar_config.?.fonts = utils.gpa.dupe(u8, val_str) catch @panic("Out of memory");
|
||||||
|
logDebugSettingNode(name, val_str);
|
||||||
|
},
|
||||||
|
.position => {
|
||||||
|
if (std.meta.stringToEnum(Bar.Position, val_str)) |pos| {
|
||||||
|
config.bar_config.?.position = pos;
|
||||||
|
logDebugSettingNode(name, val_str);
|
||||||
|
} else {
|
||||||
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.margins => next_child_block = .margins,
|
||||||
|
inline .background_color,
|
||||||
|
.text_color,
|
||||||
|
=> |tag| {
|
||||||
|
@field(config.bar_config.?, @tagName(tag)) = utils.parseRgbaPixman(val_str) catch {
|
||||||
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
logDebugSettingNode(name, val_str);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
helpers.logWarnInvalidNode(node.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.child_block_begin => {
|
||||||
|
if (next_child_block) |child| {
|
||||||
|
switch (child) {
|
||||||
|
.margins => try loadMarginsBlock(config, parser, hostname),
|
||||||
|
}
|
||||||
|
next_child_block = null;
|
||||||
|
} else {
|
||||||
|
try helpers.skipChildBlock(parser);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.child_block_end => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loadMarginsBlock(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
||||||
|
while (try parser.next()) |event| {
|
||||||
|
switch (event) {
|
||||||
|
.node => |node| {
|
||||||
|
const node_name = std.meta.stringToEnum(MarginsNodeName, node.name);
|
||||||
|
if (node_name) |name| {
|
||||||
|
if (!helpers.hostMatches(node, parser, hostname)) {
|
||||||
|
logDebugHostMismatch(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const val_str = utils.stripQuotes(node.arg(parser, 0) orelse "");
|
||||||
|
const val = fmt.parseInt(i32, val_str, 10) catch {
|
||||||
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
switch (name) {
|
||||||
|
.top => config.bar_config.?.margin_top = val,
|
||||||
|
.right => config.bar_config.?.margin_right = val,
|
||||||
|
.bottom => config.bar_config.?.margin_bottom = val,
|
||||||
|
.left => config.bar_config.?.margin_left = val,
|
||||||
|
}
|
||||||
|
logDebugSettingNode(name, val_str);
|
||||||
|
} else {
|
||||||
|
helpers.logWarnInvalidNode(node.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.child_block_begin => try helpers.skipChildBlock(parser),
|
||||||
|
.child_block_end => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn logDebugSettingNode(node_name: anytype, node_value: []const u8) void {
|
||||||
|
const node_name_type = @TypeOf(node_name);
|
||||||
|
switch (node_name_type) {
|
||||||
|
NodeName => log.debug("Setting bar.{s} to {s}", .{ @tagName(node_name), node_value }),
|
||||||
|
MarginsNodeName => log.debug("Setting bar.margins.{s} to {s}", .{ @tagName(node_name), node_value }),
|
||||||
|
else => @compileError("This function does not (yet) support type \"" ++ @typeName(@TypeOf(node_name)) ++ "\""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn logDebugHostMismatch(node_name: anytype) void {
|
||||||
|
const node_name_type = @TypeOf(node_name);
|
||||||
|
switch (node_name_type) {
|
||||||
|
NodeName => log.debug("Skipping \"bar.{s}\" (host mismatch)", .{@tagName(node_name)}),
|
||||||
|
MarginsNodeName => log.debug("Skipping \"bar.margins.{s}\" (host mismatch)", .{@tagName(node_name)}),
|
||||||
|
else => @compileError("This function does not (yet) support type \"" ++ @typeName(node_name_type) ++ "\""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn logWarnInvalidNodeArg(node_name: anytype, node_value: []const u8) void {
|
||||||
|
const node_name_type = @TypeOf(node_name);
|
||||||
|
switch (node_name_type) {
|
||||||
|
NodeName => log.warn("Invalid \"bar.{s}\" ({s}). Using default value", .{ @tagName(node_name), node_value }),
|
||||||
|
MarginsNodeName => log.warn("Invalid \"bar.margins.{s}\" ({s}). Using default value", .{ @tagName(node_name), node_value }),
|
||||||
|
else => @compileError("This function does not (yet) support type \"" ++ @typeName(node_name_type) ++ "\""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn logWarnMissingNodeArg(node_name: NodeName, comptime arg: []const u8) void {
|
||||||
|
log.warn("\"bar.{s}\" missing " ++ arg ++ " argument. Ignoring", .{@tagName(node_name)});
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const fmt = std.fmt;
|
||||||
|
|
||||||
|
const kdl = @import("kdl");
|
||||||
|
const pixman = @import("pixman");
|
||||||
|
|
||||||
|
const utils = @import("../utils.zig");
|
||||||
|
const Bar = @import("../Bar.zig");
|
||||||
|
const Config = @import("../Config.zig");
|
||||||
|
|
||||||
|
const helpers = @import("helpers.zig");
|
||||||
|
|
||||||
|
const log = std.log.scoped(.config_bar);
|
||||||
|
|
@ -52,42 +52,42 @@ pub const TagOverlayConfig = struct {
|
||||||
margin_bottom: i32 = 0,
|
margin_bottom: i32 = 0,
|
||||||
margin_left: i32 = 0,
|
margin_left: i32 = 0,
|
||||||
|
|
||||||
pub fn toTagOverlayOptions(self: TagOverlayConfig) TagOverlay.Options {
|
pub fn toTagOverlayOptions(config: TagOverlayConfig) TagOverlay.Options {
|
||||||
return .{
|
return .{
|
||||||
.border_width = self.border_width,
|
.border_width = config.border_width,
|
||||||
.tag_amount = @intCast(std.math.clamp(@as(u32, self.tag_amount), 1, 32)),
|
.tag_amount = @intCast(std.math.clamp(@as(u32, config.tag_amount), 1, 32)),
|
||||||
.tags_per_row = @intCast(std.math.clamp(@as(u32, self.tags_per_row), 1, 32)),
|
.tags_per_row = @intCast(std.math.clamp(@as(u32, config.tags_per_row), 1, 32)),
|
||||||
.square_size = self.square_size,
|
.square_size = config.square_size,
|
||||||
.square_inner_padding = self.square_inner_padding,
|
.square_inner_padding = config.square_inner_padding,
|
||||||
.square_padding = self.square_padding,
|
.square_padding = config.square_padding,
|
||||||
.square_border_width = self.square_border_width,
|
.square_border_width = config.square_border_width,
|
||||||
.background_color = self.background_color,
|
.background_color = config.background_color,
|
||||||
.border_color = self.border_color,
|
.border_color = config.border_color,
|
||||||
.square_active_background_color = self.square_active_background_color,
|
.square_active_background_color = config.square_active_background_color,
|
||||||
.square_active_border_color = self.square_active_border_color,
|
.square_active_border_color = config.square_active_border_color,
|
||||||
.square_active_occupied_color = self.square_active_occupied_color,
|
.square_active_occupied_color = config.square_active_occupied_color,
|
||||||
.square_inactive_background_color = self.square_inactive_background_color,
|
.square_inactive_background_color = config.square_inactive_background_color,
|
||||||
.square_inactive_border_color = self.square_inactive_border_color,
|
.square_inactive_border_color = config.square_inactive_border_color,
|
||||||
.square_inactive_occupied_color = self.square_inactive_occupied_color,
|
.square_inactive_occupied_color = config.square_inactive_occupied_color,
|
||||||
.anchors = .{
|
.anchors = .{
|
||||||
.top = self.anchor_top,
|
.top = config.anchor_top,
|
||||||
.right = self.anchor_right,
|
.right = config.anchor_right,
|
||||||
.bottom = self.anchor_bottom,
|
.bottom = config.anchor_bottom,
|
||||||
.left = self.anchor_left,
|
.left = config.anchor_left,
|
||||||
},
|
},
|
||||||
.margins = .{
|
.margins = .{
|
||||||
.top = self.margin_top,
|
.top = config.margin_top,
|
||||||
.right = self.margin_right,
|
.right = config.margin_right,
|
||||||
.bottom = self.margin_bottom,
|
.bottom = config.margin_bottom,
|
||||||
.left = self.margin_left,
|
.left = config.margin_left,
|
||||||
},
|
},
|
||||||
.timeout = self.timeout,
|
.timeout = config.timeout,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn load(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
pub fn load(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
||||||
config.tag_overlay = .{}; // Presence of block = enabled; initialize with defaults
|
config.tag_overlay_config = .{}; // Presence of block = enabled; initialize with defaults
|
||||||
|
|
||||||
const TagOverlayChild = enum { anchors, margins };
|
const TagOverlayChild = enum { anchors, margins };
|
||||||
var next_child_block: ?TagOverlayChild = null;
|
var next_child_block: ?TagOverlayChild = null;
|
||||||
|
|
@ -122,11 +122,11 @@ pub fn load(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
||||||
logWarnInvalidNodeArg(name, val_str);
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@field(config.tag_overlay.?, @tagName(tag)) = val;
|
@field(config.tag_overlay_config.?, @tagName(tag)) = val;
|
||||||
logDebugSettingNode(name, val_str);
|
logDebugSettingNode(name, val_str);
|
||||||
},
|
},
|
||||||
.timeout => {
|
.timeout => {
|
||||||
config.tag_overlay.?.timeout = fmt.parseInt(u32, val_str, 10) catch {
|
config.tag_overlay_config.?.timeout = fmt.parseInt(u32, val_str, 10) catch {
|
||||||
logWarnInvalidNodeArg(name, val_str);
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -141,7 +141,7 @@ pub fn load(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8) !void {
|
||||||
.square_inactive_border_color,
|
.square_inactive_border_color,
|
||||||
.square_inactive_occupied_color,
|
.square_inactive_occupied_color,
|
||||||
=> |tag| {
|
=> |tag| {
|
||||||
@field(config.tag_overlay.?, @tagName(tag)) = utils.parseRgbaPixman(val_str) catch {
|
@field(config.tag_overlay_config.?, @tagName(tag)) = utils.parseRgbaPixman(val_str) catch {
|
||||||
logWarnInvalidNodeArg(name, val_str);
|
logWarnInvalidNodeArg(name, val_str);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -181,10 +181,10 @@ fn loadAnchorsBlock(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8)
|
||||||
const val_str = utils.stripQuotes(node.arg(parser, 0) orelse "");
|
const val_str = utils.stripQuotes(node.arg(parser, 0) orelse "");
|
||||||
if (helpers.boolFromKdlStr(val_str)) |val| {
|
if (helpers.boolFromKdlStr(val_str)) |val| {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
.top => config.tag_overlay.?.anchor_top = val,
|
.top => config.tag_overlay_config.?.anchor_top = val,
|
||||||
.right => config.tag_overlay.?.anchor_right = val,
|
.right => config.tag_overlay_config.?.anchor_right = val,
|
||||||
.bottom => config.tag_overlay.?.anchor_bottom = val,
|
.bottom => config.tag_overlay_config.?.anchor_bottom = val,
|
||||||
.left => config.tag_overlay.?.anchor_left = val,
|
.left => config.tag_overlay_config.?.anchor_left = val,
|
||||||
}
|
}
|
||||||
logDebugSettingNode(name, val_str);
|
logDebugSettingNode(name, val_str);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -216,10 +216,10 @@ fn loadMarginsBlock(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8)
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
switch (name) {
|
switch (name) {
|
||||||
.top => config.tag_overlay.?.margin_top = val,
|
.top => config.tag_overlay_config.?.margin_top = val,
|
||||||
.right => config.tag_overlay.?.margin_right = val,
|
.right => config.tag_overlay_config.?.margin_right = val,
|
||||||
.bottom => config.tag_overlay.?.margin_bottom = val,
|
.bottom => config.tag_overlay_config.?.margin_bottom = val,
|
||||||
.left => config.tag_overlay.?.margin_left = val,
|
.left => config.tag_overlay_config.?.margin_left = val,
|
||||||
}
|
}
|
||||||
logDebugSettingNode(name, val_str);
|
logDebugSettingNode(name, val_str);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -231,6 +231,7 @@ fn loadMarginsBlock(config: *Config, parser: *kdl.Parser, hostname: ?[]const u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn logDebugSettingNode(node_name: anytype, node_value: []const u8) void {
|
inline fn logDebugSettingNode(node_name: anytype, node_value: []const u8) void {
|
||||||
const node_name_type = @TypeOf(node_name);
|
const node_name_type = @TypeOf(node_name);
|
||||||
switch (node_name_type) {
|
switch (node_name_type) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue