commit 67af604eb290497b057f72820a8ac3db11702217
parent dadf6bdd225f5efe54f4364db9fa89e496a05c2b
Author: Tomas Nemec <owl@gtms.dev>
Date: Fri, 31 May 2024 18:36:43 +0200
update zig 0.12
Diffstat:
13 files changed, 53 insertions(+), 392 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -4,9 +4,6 @@
[submodule "deps/zig-pixman"]
path = deps/zig-pixman
url = https://github.com/ifreund/zig-pixman
-[submodule "deps/zig-udev"]
- path = deps/zig-udev
- url = https://git.sr.ht/~andreafeletto/zig-udev
[submodule "deps/zig-fcft"]
path = deps/zig-fcft
url = https://git.sr.ht/~novakane/zig-fcft
diff --git a/build.zig b/build.zig
@@ -1,14 +1,13 @@
const std = @import("std");
-const Builder = std.build.Builder;
const Scanner = @import("deps/zig-wayland/build.zig").Scanner;
-pub fn build(b: *Builder) void {
+pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const scanner = Scanner.create(b, .{});
- const wayland = b.createModule(.{ .source_file = scanner.result });
+ const wayland = b.createModule(.{ .root_source_file = scanner.result });
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
scanner.addSystemProtocol("stable/viewporter/viewporter.xml");
@@ -29,17 +28,12 @@ pub fn build(b: *Builder) void {
scanner.generate("zriver_control_v1", 1);
const pixman = b.createModule(.{
- .source_file = .{ .path = "deps/zig-pixman/pixman.zig" },
+ .root_source_file = .{ .path = "deps/zig-pixman/pixman.zig" },
});
const fcft = b.createModule(.{
- .source_file = .{ .path = "deps/zig-fcft/fcft.zig" },
- .dependencies = &.{
- .{ .name = "pixman", .module = pixman },
- },
- });
- const udev = b.createModule(.{
- .source_file = .{ .path = "deps/zig-udev/udev.zig" },
+ .root_source_file = .{ .path = "deps/zig-fcft/fcft.zig" },
});
+ fcft.addImport("pixman", pixman);
const exe = b.addExecutable(.{
.name = "levee",
@@ -48,10 +42,9 @@ pub fn build(b: *Builder) void {
.optimize = optimize,
});
- exe.addModule("fcft", fcft);
- exe.addModule("pixman", pixman);
- exe.addModule("udev", udev);
- exe.addModule("wayland", wayland);
+ exe.root_module.addImport("fcft", fcft);
+ exe.root_module.addImport("pixman", pixman);
+ exe.root_module.addImport("wayland", wayland);
exe.linkLibC();
exe.linkSystemLibrary("fcft");
diff --git a/deps/zig-udev b/deps/zig-udev
@@ -1 +0,0 @@
-Subproject commit 199ed84cc9e797e315be030326908fd25d88cc19
diff --git a/src/Buffer.zig b/src/Buffer.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const mem = std.mem;
-const os = std.os;
+const posix = std.posix;
+const linux = std.os.linux;
const pixman = @import("pixman");
const wl = @import("wayland").client.wl;
@@ -24,14 +25,14 @@ pub fn resize(self: *Buffer, shm: *wl.Shm, width: u31, height: u31) !void {
self.width = width;
self.height = height;
- const fd = try os.memfd_create("levee-shm", os.linux.MFD.CLOEXEC);
- defer os.close(fd);
+ const fd = try posix.memfd_create("levee-shm", linux.MFD.CLOEXEC);
+ defer posix.close(fd);
const stride = width * 4;
self.size = stride * height;
- try os.ftruncate(fd, self.size);
+ try posix.ftruncate(fd, self.size);
- self.mmap = try os.mmap(null, self.size, os.PROT.READ | os.PROT.WRITE, os.MAP.SHARED, fd, 0);
+ self.mmap = try posix.mmap(null, self.size, posix.PROT.READ | posix.PROT.WRITE, .{ .TYPE = .SHARED }, fd, 0);
self.data = mem.bytesAsSlice(u32, self.mmap.?);
const pool = try shm.createPool(fd, self.size);
@@ -47,7 +48,7 @@ pub fn resize(self: *Buffer, shm: *wl.Shm, width: u31, height: u31) !void {
pub fn deinit(self: *Buffer) void {
if (self.pix) |pix| _ = pix.unref();
if (self.buffer) |buf| buf.destroy();
- if (self.mmap) |mmap| os.munmap(mmap);
+ if (self.mmap) |mmap| posix.munmap(mmap);
}
fn listener(_: *wl.Buffer, event: wl.Buffer.Event, buffer: *Buffer) void {
diff --git a/src/Config.zig b/src/Config.zig
@@ -29,6 +29,6 @@ pub fn init() !Config {
},
.border = 2,
.font = try fcft.Font.fromName(&font_names, null),
- .clockFormat = "%d %b %Y - %R",
+ .clockFormat = "%d/%m %R:%S",
};
}
diff --git a/src/Loop.zig b/src/Loop.zig
@@ -1,23 +1,24 @@
const std = @import("std");
const log = std.log;
const mem = std.mem;
-const os = std.os;
+const posix = std.posix;
+const linux = std.os.linux;
const utils = @import("utils.zig");
const Loop = @This();
const state = &@import("root").state;
-sfd: os.fd_t,
+sfd: posix.fd_t,
pub fn init() !Loop {
- var mask = os.empty_sigset;
- os.linux.sigaddset(&mask, os.linux.SIG.INT);
- os.linux.sigaddset(&mask, os.linux.SIG.TERM);
- os.linux.sigaddset(&mask, os.linux.SIG.QUIT);
+ var mask = posix.empty_sigset;
+ linux.sigaddset(&mask, linux.SIG.INT);
+ linux.sigaddset(&mask, linux.SIG.TERM);
+ linux.sigaddset(&mask, linux.SIG.QUIT);
- _ = os.linux.sigprocmask(os.linux.SIG.BLOCK, &mask, null);
- const sfd = os.linux.signalfd(-1, &mask, os.linux.SFD.NONBLOCK);
+ _ = linux.sigprocmask(linux.SIG.BLOCK, &mask, null);
+ const sfd = linux.signalfd(-1, &mask, linux.SFD.NONBLOCK);
return Loop{ .sfd = @intCast(sfd) };
}
@@ -26,30 +27,20 @@ pub fn run(self: *Loop) !void {
const wayland = &state.wayland;
const modules = &state.modules;
- var fds = [_]os.pollfd{
+ var fds = [_]posix.pollfd{
.{
.fd = self.sfd,
- .events = os.POLL.IN,
+ .events = posix.POLL.IN,
.revents = undefined,
},
.{
.fd = wayland.fd,
- .events = os.POLL.IN,
- .revents = undefined,
- },
- .{
- .fd = if (modules.backlight) |mod| mod.fd else -1,
- .events = os.POLL.IN,
- .revents = undefined,
- },
- .{
- .fd = if (modules.battery) |mod| mod.fd else -1,
- .events = os.POLL.IN,
+ .events = posix.POLL.IN,
.revents = undefined,
},
.{
.fd = if (modules.pulse) |mod| mod.fd else -1,
- .events = os.POLL.IN,
+ .events = posix.POLL.IN,
.revents = undefined,
},
};
@@ -61,42 +52,34 @@ pub fn run(self: *Loop) !void {
if (ret == .SUCCESS) break;
}
- _ = os.poll(&fds, -1) catch |err| {
+ _ = posix.poll(&fds, -1) catch |err| {
log.err("poll failed: {s}", .{@errorName(err)});
return;
};
for (fds) |fd| {
- if (fd.revents & os.POLL.HUP != 0 or fd.revents & os.POLL.ERR != 0) {
+ if (fd.revents & posix.POLL.HUP != 0 or fd.revents & posix.POLL.ERR != 0) {
return;
}
}
// signals
- if (fds[0].revents & os.POLL.IN != 0) {
+ if (fds[0].revents & posix.POLL.IN != 0) {
return;
}
// wayland
- if (fds[1].revents & os.POLL.IN != 0) {
+ if (fds[1].revents & posix.POLL.IN != 0) {
const errno = wayland.display.dispatch();
if (errno != .SUCCESS) return;
}
- if (fds[1].revents & os.POLL.OUT != 0) {
+ if (fds[1].revents & posix.POLL.OUT != 0) {
const errno = wayland.display.flush();
if (errno != .SUCCESS) return;
}
// modules
- if (modules.backlight) |*mod| if (fds[2].revents & os.POLL.IN != 0) {
- log.info("backlight", .{});
- mod.refresh() catch return;
- };
- if (modules.battery) |*mod| if (fds[3].revents & os.POLL.IN != 0) {
- log.info("battery", .{});
- mod.refresh() catch return;
- };
- if (modules.pulse) |*mod| if (fds[4].revents & os.POLL.IN != 0) {
+ if (modules.pulse) |*mod| if (fds[2].revents & posix.POLL.IN != 0) {
log.info("pulse", .{});
mod.refresh() catch return;
};
diff --git a/src/Modules.zig b/src/Modules.zig
@@ -4,16 +4,12 @@ const ArrayList = std.ArrayList;
const Modules = @This();
-const Backlight = @import("modules/Backlight.zig");
-const Battery = @import("modules/Battery.zig");
const Pulse = @import("modules/Pulse.zig");
var state = &@import("root").state;
-const Tag = enum { backlight, battery, pulse };
+const Tag = enum { pulse };
-backlight: ?Backlight = null,
-battery: ?Battery = null,
pulse: ?Pulse = null,
order: ArrayList(Tag),
@@ -22,20 +18,12 @@ pub fn init() Modules {
}
pub fn deinit(self: *Modules) void {
- if (self.backlight) |*mod| mod.deinit();
- if (self.battery) |*mod| mod.deinit();
if (self.pulse) |*mod| mod.deinit();
self.order.deinit();
}
pub fn register(self: *Modules, name: []const u8) !void {
- if (mem.eql(u8, name, "backlight")) {
- self.backlight = try Backlight.init();
- try self.order.append(.backlight);
- } else if (mem.eql(u8, name, "battery")) {
- self.battery = try Battery.init();
- try self.order.append(.battery);
- } else if (mem.eql(u8, name, "pulse")) {
+ if (mem.eql(u8, name, "pulse")) {
self.pulse = try Pulse.init();
try self.pulse.?.start();
try self.order.append(.pulse);
diff --git a/src/Wayland.zig b/src/Wayland.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const log = std.log;
const mem = std.mem;
const meta = std.meta;
-const os = std.os;
+const posix = std.posix;
const wl = @import("wayland").client.wl;
const wp = @import("wayland").client.wp;
@@ -19,7 +19,7 @@ const Wayland = @This();
const state = &@import("root").state;
display: *wl.Display,
-fd: os.fd_t,
+fd: posix.fd_t,
compositor: ?*wl.Compositor = null,
subcompositor: ?*wl.Subcompositor = null,
diff --git a/src/main.zig b/src/main.zig
@@ -76,8 +76,6 @@ fn help(program_name: []const u8) void {
\\Usage: {s} [module]...
\\
\\Available modules:
- \\ backlight screen brightness
- \\ battery battery capacity
\\ pulse speaker volume with pulseaudio
\\
;
diff --git a/src/modules/Backlight.zig b/src/modules/Backlight.zig
@@ -1,119 +0,0 @@
-const std = @import("std");
-const fmt = std.fmt;
-const log = std.log;
-const mem = std.mem;
-const os = std.os;
-
-const udev = @import("udev");
-
-const render = @import("../render.zig");
-const utils = @import("../utils.zig");
-const Backlight = @This();
-
-const state = &@import("root").state;
-
-context: *udev.Udev,
-monitor: *udev.Monitor,
-fd: os.fd_t,
-devices: DeviceList,
-
-const Device = struct {
- name: []const u8,
- value: u64,
- max: u64,
-};
-
-const DeviceList = std.ArrayList(Device);
-
-pub fn init() !Backlight {
- const context = try udev.Udev.new();
-
- const monitor = try udev.Monitor.newFromNetlink(context, "udev");
- try monitor.filterAddMatchSubsystemDevType("backlight", null);
- try monitor.filterAddMatchSubsystemDevType("power_supply", null);
- try monitor.enableReceiving();
-
- var devices = DeviceList.init(state.gpa);
- try updateDevices(state.gpa, context, &devices);
-
- return Backlight{
- .context = context,
- .monitor = monitor,
- .fd = try monitor.getFd(),
- .devices = devices,
- };
-}
-
-pub fn deinit(self: *Backlight) void {
- _ = self.context.unref();
- for (self.devices.items) |*device| {
- state.gpa.free(device.name);
- }
- self.devices.deinit();
-}
-
-pub fn refresh(self: *Backlight) !void {
- _ = try self.monitor.receiveDevice();
-
- for (state.wayland.monitors.items) |monitor| {
- if (monitor.bar) |bar| {
- if (bar.configured) {
- render.renderModules(bar) catch continue;
- bar.modules.surface.commit();
- bar.background.surface.commit();
- }
- }
- }
-}
-
-pub fn print(self: *Backlight, writer: anytype) !void {
- try updateDevices(state.gpa, self.context, &self.devices);
- const device = self.devices.items[0];
- var percent = @as(f64, @floatFromInt(device.value)) * 100.0;
- percent /= @as(f64, @floatFromInt(device.max));
- const value = @as(u8, @intFromFloat(@round(percent)));
-
- try writer.print("💡 {d}%", .{value});
-}
-
-fn updateDevices(
- gpa: mem.Allocator,
- context: *udev.Udev,
- devices: *DeviceList,
-) !void {
- const enumerate = try udev.Enumerate.new(context);
- try enumerate.addMatchSubsystem("backlight");
- try enumerate.scanDevices();
- const entries = enumerate.getListEntry();
-
- var maybe_entry = entries;
- while (maybe_entry) |entry| : (maybe_entry = entry.getNext()) {
- const path = entry.getName();
- const device = try udev.Device.newFromSyspath(context, path);
- try updateOrAppend(gpa, devices, device);
- }
-}
-
-fn updateOrAppend(
- gpa: mem.Allocator,
- devices: *DeviceList,
- dev: *udev.Device,
-) !void {
- const value = try dev.getSysattrValue("actual_brightness");
- const max = try dev.getSysattrValue("max_brightness");
- const name = try dev.getSysname();
-
- const device = blk: {
- for (devices.items) |*device| {
- if (mem.eql(u8, device.name, name)) {
- break :blk device;
- }
- } else {
- const device = try devices.addOne();
- device.name = try gpa.dupe(u8, name);
- break :blk device;
- }
- };
- device.value = try fmt.parseInt(u64, value, 10);
- device.max = try fmt.parseInt(u64, max, 10);
-}
diff --git a/src/modules/Battery.zig b/src/modules/Battery.zig
@@ -1,176 +0,0 @@
-const std = @import("std");
-const fmt = std.fmt;
-const log = std.log;
-const mem = std.mem;
-const os = std.os;
-
-const udev = @import("udev");
-
-const Module = @import("../Modules.zig").Module;
-const Event = @import("../Loop.zig").Event;
-const render = @import("../render.zig");
-const utils = @import("../utils.zig");
-const Battery = @This();
-
-const state = &@import("root").state;
-
-context: *udev.Udev,
-fd: os.fd_t,
-devices: DeviceList,
-
-const Device = struct {
- name: []const u8,
- status: []const u8,
- capacity: u8,
-};
-
-const DeviceList = std.ArrayList(Device);
-
-pub fn init() !Battery {
- const tfd = tfd: {
- const fd = os.linux.timerfd_create(
- os.CLOCK.MONOTONIC,
- os.linux.TFD.CLOEXEC,
- );
- const interval: os.linux.itimerspec = .{
- .it_interval = .{ .tv_sec = 10, .tv_nsec = 0 },
- .it_value = .{ .tv_sec = 10, .tv_nsec = 0 },
- };
- _ = os.linux.timerfd_settime(@as(i32, @intCast(fd)), 0, &interval, null);
- break :tfd @as(os.fd_t, @intCast(fd));
- };
-
- const context = try udev.Udev.new();
-
- var devices = DeviceList.init(state.gpa);
- try updateDevices(state.gpa, context, &devices);
-
- return Battery{
- .context = context,
- .fd = tfd,
- .devices = devices,
- };
-}
-
-pub fn deinit(self: *Battery) void {
- _ = self.context.unref();
- for (self.devices.items) |*device| {
- state.gpa.free(device.name);
- state.gpa.free(device.status);
- }
- self.devices.deinit();
-}
-
-pub fn print(self: *Battery, writer: anytype) !void {
- try updateDevices(state.gpa, self.context, &self.devices);
- const device = self.devices.items[0];
-
- var icon: []const u8 = "❓";
- if (mem.eql(u8, device.status, "Discharging")) {
- icon = "🔋";
- } else if (mem.eql(u8, device.status, "Charging")) {
- icon = "🔌";
- } else if (mem.eql(u8, device.status, "Full")) {
- icon = "⚡";
- }
-
- try fmt.format(writer, "{s} {d}%", .{ icon, device.capacity });
-}
-
-pub fn refresh(self: *Battery) !void {
- var expirations = mem.zeroes([8]u8);
- _ = try os.read(self.fd, &expirations);
-
- for (state.wayland.monitors.items) |monitor| {
- if (monitor.bar) |bar| {
- if (bar.configured) {
- render.renderClock(bar) catch continue;
- render.renderModules(bar) catch continue;
- bar.clock.surface.commit();
- bar.modules.surface.commit();
- bar.background.surface.commit();
- }
- }
- }
-}
-
-fn updateDevices(
- gpa: mem.Allocator,
- context: *udev.Udev,
- devices: *DeviceList,
-) !void {
- const enumerate = try udev.Enumerate.new(context);
- defer _ = enumerate.unref();
-
- try enumerate.addMatchSubsystem("power_supply");
- try enumerate.addMatchSysattr("type", "Battery");
- try enumerate.scanDevices();
-
- const entries = enumerate.getListEntry();
-
- var maybe_entry = entries;
- while (maybe_entry) |entry| : (maybe_entry = entry.getNext()) {
- const path = entry.getName();
- const device = try udev.Device.newFromSyspath(context, path);
- try updateOrAppend(gpa, devices, device);
- }
-}
-
-fn updateOrAppend(
- gpa: mem.Allocator,
- devices: *DeviceList,
- dev: *udev.Device,
-) !void {
- const name = dev.getSysname() catch return;
- const status = dev.getSysattrValue("status") catch return;
- const capacity = getCapacity(dev) catch return;
-
- const device = blk: {
- for (devices.items) |*device| {
- if (mem.eql(u8, device.name, name)) {
- gpa.free(device.status);
- break :blk device;
- }
- } else {
- const device = try devices.addOne();
- device.name = try gpa.dupe(u8, name);
- break :blk device;
- }
- };
-
- device.status = try gpa.dupe(u8, status);
- device.capacity = capacity;
-}
-
-fn getCapacity(dev: *udev.Device) !u8 {
- const capacity_str = dev.getSysattrValue("capacity") catch {
- return computeCapacityFromCharge(dev) catch {
- return computeCapacityFromEnergy(dev);
- };
- };
-
- const capacity = try fmt.parseInt(u8, capacity_str, 10);
- return capacity;
-}
-
-fn computeCapacityFromEnergy(dev: *udev.Device) !u8 {
- const energy_str = try dev.getSysattrValue("energy_now");
- const energy_full_str = try dev.getSysattrValue("energy_full");
-
- const energy = try fmt.parseFloat(f64, energy_str);
- const energy_full = try fmt.parseFloat(f64, energy_full_str);
-
- const capacity = energy * 100.0 / energy_full;
- return @as(u8, @intFromFloat(@round(capacity)));
-}
-
-fn computeCapacityFromCharge(dev: *udev.Device) !u8 {
- const charge_str = try dev.getSysattrValue("charge_now");
- const charge_full_str = try dev.getSysattrValue("charge_full");
-
- const charge = try fmt.parseFloat(f64, charge_str);
- const charge_full = try fmt.parseFloat(f64, charge_full_str);
-
- const capacity = charge * 100.0 / charge_full;
- return @as(u8, @intFromFloat(@round(capacity)));
-}
diff --git a/src/modules/Pulse.zig b/src/modules/Pulse.zig
@@ -1,7 +1,8 @@
const std = @import("std");
const log = std.log;
const mem = std.mem;
-const os = std.os;
+const posix = std.posix;
+const linux = std.os.linux;
const pulse = @cImport(@cInclude("pulse/pulseaudio.h"));
@@ -13,7 +14,7 @@ const Pulse = @This();
const state = &@import("root").state;
-fd: os.fd_t,
+fd: posix.fd_t,
mainloop: *pulse.pa_threaded_mainloop,
api: *pulse.pa_mainloop_api,
context: *pulse.pa_context,
@@ -26,8 +27,8 @@ muted: bool,
pub fn init() !Pulse {
// create descriptor for poll in Loop
const efd = efd: {
- const fd = try os.eventfd(0, os.linux.EFD.NONBLOCK);
- break :efd @as(os.fd_t, @intCast(fd));
+ const fd = try posix.eventfd(0, linux.EFD.NONBLOCK);
+ break :efd @as(posix.fd_t, @intCast(fd));
};
// setup pulseaudio api
@@ -71,7 +72,7 @@ pub fn start(self: *Pulse) !void {
pub fn refresh(self: *Pulse) !void {
var data = mem.zeroes([8]u8);
- _ = try os.read(self.fd, &data);
+ _ = try posix.read(self.fd, &data);
for (state.wayland.monitors.items) |monitor| {
if (monitor.bar) |bar| {
@@ -90,7 +91,7 @@ pub fn print(self: *Pulse, writer: anytype) !void {
if (self.muted) {
try writer.print(" 🔇 ", .{});
} else {
- try writer.print("🔊 {d}%", .{self.volume});
+ try writer.print("🔊 {d}%", .{self.volume});
}
}
@@ -194,5 +195,5 @@ export fn sinkInfoCallback(
self.muted = info.mute != 0;
const increment = mem.asBytes(&@as(u64, 1));
- _ = os.write(self.fd, increment) catch return;
+ _ = posix.write(self.fd, increment) catch return;
}
diff --git a/src/render.zig b/src/render.zig
@@ -10,8 +10,6 @@ const Bar = @import("Bar.zig");
const Tag = @import("Tags.zig").Tag;
const utils = @import("utils.zig");
-const Backlight = @import("modules/Backlight.zig");
-const Battery = @import("modules/Battery.zig");
const Pulse = @import("modules/Pulse.zig");
const state = &@import("root").state;
@@ -81,7 +79,7 @@ pub fn renderClock(bar: *Bar) !void {
var x: i32 = 0;
i = 0;
- var color = pixman.Image.createSolidFill(&state.config.foregroundColor).?;
+ const color = pixman.Image.createSolidFill(&state.config.foregroundColor).?;
while (i < run.count) : (i += 1) {
const glyph = run.glyphs[i];
x += @as(i32, @intCast(glyph.x));
@@ -107,8 +105,6 @@ pub fn renderModules(bar: *Bar) !void {
for (state.modules.order.items) |tag| {
try writer.print(" | ", .{});
switch (tag) {
- .backlight => try state.modules.backlight.?.print(writer),
- .battery => try state.modules.battery.?.print(writer),
.pulse => try state.modules.pulse.?.print(writer),
}
}
@@ -131,8 +127,8 @@ pub fn renderModules(bar: *Bar) !void {
// set subsurface offset
const font_height = @as(u32, @intCast(state.config.font.height));
- var x_offset = @as(i32, @intCast(bar.width - width));
- var y_offset = @as(i32, @intCast(@divFloor(bar.height - font_height, 2)));
+ const x_offset = @as(i32, @intCast(bar.width - width));
+ const y_offset = @as(i32, @intCast(@divFloor(bar.height - font_height, 2)));
bar.modules.subsurface.setPosition(x_offset, y_offset);
const buffers = &bar.modules.buffers;
@@ -148,7 +144,7 @@ pub fn renderModules(bar: *Bar) !void {
var x: i32 = 0;
i = 0;
- var color = pixman.Image.createSolidFill(&state.config.foregroundColor).?;
+ const color = pixman.Image.createSolidFill(&state.config.foregroundColor).?;
while (i < run.count) : (i += 1) {
const glyph = run.glyphs[i];
x += @as(i32, @intCast(glyph.x));
@@ -200,7 +196,7 @@ fn renderTag(
break :blk &state.config.foregroundColor;
};
const font = state.config.font;
- var char = pixman.Image.createSolidFill(glyph_color).?;
+ const char = pixman.Image.createSolidFill(glyph_color).?;
const glyph = try font.rasterizeCharUtf32(tag.label, .default);
const x = offset + @divFloor(size - glyph.width, 2);
const y = @divFloor(size - glyph.height, 2);
@@ -208,7 +204,7 @@ fn renderTag(
}
fn formatDatetime() ![]const u8 {
- var buf = try state.gpa.alloc(u8, 256);
+ const buf = try state.gpa.alloc(u8, 256);
const now = time.time(null);
const local = time.localtime(&now);
const len = time.strftime(