stevee

My wayland statusbar
git clone git://gtms.dev/stevee
Log | Files | Refs | Submodules | README | LICENSE

commit dadf6bdd225f5efe54f4364db9fa89e496a05c2b
parent 4fa32287b0695c6f3d209141f7e451b37d043e8c
Author: Andrea Feletto <andrea@andreafeletto.com>
Date:   Fri, 13 Oct 2023 16:39:13 +0200

update to zig 0.11

Diffstat:
M.build.yml | 6+++---
MREADME.md | 2+-
Mbuild.zig | 77++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Bar.zig | 4++--
Msrc/Input.zig | 4++--
Msrc/Loop.zig | 2+-
Msrc/Tags.zig | 16++++++++--------
Msrc/Wayland.zig | 28+++++++++++++---------------
Msrc/modules/Backlight.zig | 6+++---
Msrc/modules/Battery.zig | 8++++----
Msrc/modules/Pulse.zig | 10+++++-----
Msrc/render.zig | 38+++++++++++++++++++-------------------
Msrc/utils.zig | 12+++++-------
13 files changed, 104 insertions(+), 109 deletions(-)

diff --git a/.build.yml b/.build.yml @@ -12,9 +12,9 @@ secrets: - 8a791f75-2c57-4cd6-8cae-710da7d992cc tasks: - zig: | - curl -O https://ziglang.org/download/0.10.0/zig-linux-x86_64-0.10.0.tar.xz - tar xf zig-linux-x86_64-0.10.0.tar.xz - mv zig-linux-x86_64-0.10.0 zig + curl -O https://ziglang.org/download/0.11.0/zig-linux-x86_64-0.11.0.tar.xz + tar xf zig-linux-x86_64-0.11.0.tar.xz + mv zig-linux-x86_64-0.11.0 zig - submodules: | cd levee git submodule update --init diff --git a/README.md b/README.md @@ -25,7 +25,7 @@ riverctl spawn "levee pulse backlight battery" ## Dependencies -* [zig] 0.10.0 +* [zig] 0.11.0 * [wayland] 1.21.0 * [pixman] 0.42.0 * [fcft] 3.1.5 diff --git a/build.zig b/build.zig @@ -1,23 +1,21 @@ const std = @import("std"); -const Pkg = std.build.Pkg; +const Builder = std.build.Builder; -const ScanProtocolsStep = @import("deps/zig-wayland/build.zig").ScanProtocolsStep; +const Scanner = @import("deps/zig-wayland/build.zig").Scanner; -pub fn build(b: *std.build.Builder) void { +pub fn build(b: *Builder) void { const target = b.standardTargetOptions(.{}); - const mode = b.standardReleaseOptions(); + const optimize = b.standardOptimizeOption(.{}); - const exe = b.addExecutable("levee", "src/main.zig"); - exe.setTarget(target); - exe.setBuildMode(mode); + const scanner = Scanner.create(b, .{}); + const wayland = b.createModule(.{ .source_file = scanner.result }); - const scanner = ScanProtocolsStep.create(b); scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml"); scanner.addSystemProtocol("stable/viewporter/viewporter.xml"); scanner.addSystemProtocol("staging/single-pixel-buffer/single-pixel-buffer-v1.xml"); - scanner.addProtocolPath("protocol/wlr-layer-shell-unstable-v1.xml"); - scanner.addProtocolPath("protocol/river-status-unstable-v1.xml"); - scanner.addProtocolPath("protocol/river-control-unstable-v1.xml"); + scanner.addCustomProtocol("protocol/wlr-layer-shell-unstable-v1.xml"); + scanner.addCustomProtocol("protocol/river-status-unstable-v1.xml"); + scanner.addCustomProtocol("protocol/river-control-unstable-v1.xml"); scanner.generate("wl_compositor", 4); scanner.generate("wl_subcompositor", 1); @@ -30,31 +28,30 @@ pub fn build(b: *std.build.Builder) void { scanner.generate("zriver_status_manager_v1", 1); scanner.generate("zriver_control_v1", 1); - exe.step.dependOn(&scanner.step); - scanner.addCSource(exe); + const pixman = b.createModule(.{ + .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" }, + }); - const wayland = Pkg{ - .name = "wayland", - .source = .{ .generated = &scanner.result }, - }; - const pixman = Pkg{ - .name = "pixman", - .source = .{ .path = "deps/zig-pixman/pixman.zig" }, - }; - const fcft = Pkg{ - .name = "fcft", - .source = .{ .path = "deps/zig-fcft/fcft.zig" }, - .dependencies = &[_]Pkg{pixman}, - }; - const udev = Pkg{ - .name = "udev", - .source = .{ .path = "deps/zig-udev/udev.zig" }, - }; + const exe = b.addExecutable(.{ + .name = "levee", + .root_source_file = .{ .path = "src/main.zig" }, + .target = target, + .optimize = optimize, + }); - exe.addPackage(fcft); - exe.addPackage(pixman); - exe.addPackage(udev); - exe.addPackage(wayland); + exe.addModule("fcft", fcft); + exe.addModule("pixman", pixman); + exe.addModule("udev", udev); + exe.addModule("wayland", wayland); exe.linkLibC(); exe.linkSystemLibrary("fcft"); @@ -63,14 +60,16 @@ pub fn build(b: *std.build.Builder) void { exe.linkSystemLibrary("libpulse"); exe.linkSystemLibrary("wayland-client"); - exe.install(); + scanner.addCSource(exe); + + b.installArtifact(exe); - const run_cmd = exe.run(); - run_cmd.step.dependOn(b.getInstallStep()); + const run = b.addRunArtifact(exe); + run.step.dependOn(b.getInstallStep()); if (b.args) |args| { - run_cmd.addArgs(args); + run.addArgs(args); } const run_step = b.step("run", "Run levee"); - run_step.dependOn(&run_cmd.step); + run_step.dependOn(&run.step); } diff --git a/src/Bar.zig b/src/Bar.zig @@ -90,8 +90,8 @@ fn layerSurfaceListener( switch (event) { .configure => |data| { bar.configured = true; - bar.width = @intCast(u16, data.width); - bar.height = @intCast(u16, data.height); + bar.width = @intCast(data.width); + bar.height = @intCast(data.height); layerSurface.ackConfigure(data.serial); diff --git a/src/Input.zig b/src/Input.zig @@ -86,9 +86,9 @@ fn pointerListener( const tagsSurface = bar.tags.surface; if (input.pointer.surface != tagsSurface) return; - const x = @intCast(u32, input.pointer.x); + const x = input.pointer.x; if (x < bar.height * 9) { - bar.monitor.tags.handleClick(x, input) catch return; + bar.monitor.tags.handleClick(@intCast(x), input) catch return; } } }, diff --git a/src/Loop.zig b/src/Loop.zig @@ -19,7 +19,7 @@ pub fn init() !Loop { _ = os.linux.sigprocmask(os.linux.SIG.BLOCK, &mask, null); const sfd = os.linux.signalfd(-1, &mask, os.linux.SFD.NONBLOCK); - return Loop{ .sfd = @intCast(os.fd_t, sfd) }; + return Loop{ .sfd = @intCast(sfd) }; } pub fn run(self: *Loop) !void { diff --git a/src/Tags.zig b/src/Tags.zig @@ -25,8 +25,8 @@ pub fn create(monitor: *Monitor) !*Tags { self.monitor = monitor; self.output_status = try manager.getRiverOutputStatus(monitor.output); - for (self.tags) |*tag, i| { - tag.label = '1' + @intCast(u8, i); + for (&self.tags, 0..) |*tag, i| { + tag.label = '1' + @as(u8, @intCast(i)); } self.output_status.setListener(*Tags, outputStatusListener, self); @@ -45,18 +45,18 @@ fn outputStatusListener( ) void { switch (event) { .focused_tags => |data| { - for (tags.tags) |*tag, i| { - const mask = @as(u32, 1) << @intCast(u5, i); + for (&tags.tags, 0..) |*tag, i| { + const mask = @as(u32, 1) << @as(u5, @intCast(i)); tag.focused = data.tags & mask != 0; } }, .view_tags => |data| { - for (tags.tags) |*tag| { + for (&tags.tags) |*tag| { tag.occupied = false; } for (data.tags.slice(u32)) |view| { - for (tags.tags) |*tag, i| { - const mask = @as(u32, 1) << @intCast(u5, i); + for (&tags.tags, 0..) |*tag, i| { + const mask = @as(u32, 1) << @as(u5, @intCast(i)); if (view & mask != 0) tag.occupied = true; } } @@ -79,7 +79,7 @@ pub fn handleClick(self: *Tags, x: u32, input: *Input) !void { const payload = try std.fmt.allocPrintZ( state.gpa, "{d}", - .{@as(u32, 1) << @intCast(u5, index)}, + .{@as(u32, 1) << @as(u5, @intCast(index))}, ); defer state.gpa.free(payload); diff --git a/src/Wayland.zig b/src/Wayland.zig @@ -3,7 +3,6 @@ const log = std.log; const mem = std.mem; const meta = std.meta; const os = std.os; -const strcmp = std.cstr.cmp; const wl = @import("wayland").client.wl; const wp = @import("wayland").client.wp; @@ -36,11 +35,10 @@ inputs: std.ArrayList(*Input), pub fn init() !Wayland { const display = try wl.Display.connect(null); - const wfd = @intCast(os.fd_t, display.getFd()); return Wayland{ .display = display, - .fd = wfd, + .fd = @intCast(display.getFd()), .monitors = std.ArrayList(*Monitor).init(state.gpa), .inputs = std.ArrayList(*Input).init(state.gpa), }; @@ -98,13 +96,13 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Way self.bindGlobal(registry, g.name, g.interface) catch unreachable; }, .global_remove => |g| { - for (self.monitors.items) |monitor, i| { + for (self.monitors.items, 0..) |monitor, i| { if (monitor.globalName == g.name) { self.monitors.swapRemove(i).destroy(); break; } } - for (self.inputs.items) |input, i| { + for (self.inputs.items, 0..) |input, i| { if (input.globalName == g.name) { self.inputs.swapRemove(i).destroy(); break; @@ -115,26 +113,26 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Way } fn bindGlobal(self: *Wayland, registry: *wl.Registry, name: u32, iface: [*:0]const u8) !void { - if (strcmp(iface, wl.Compositor.getInterface().name) == 0) { + if (mem.orderZ(u8, iface, wl.Compositor.getInterface().name) == .eq) { self.compositor = try registry.bind(name, wl.Compositor, 4); - } else if (strcmp(iface, wl.Subcompositor.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wl.Subcompositor.getInterface().name) == .eq) { self.subcompositor = try registry.bind(name, wl.Subcompositor, 1); - } else if (strcmp(iface, wl.Shm.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wl.Shm.getInterface().name) == .eq) { self.shm = try registry.bind(name, wl.Shm, 1); - } else if (strcmp(iface, wp.Viewporter.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wp.Viewporter.getInterface().name) == .eq) { self.viewporter = try registry.bind(name, wp.Viewporter, 1); - } else if (strcmp(iface, wp.SinglePixelBufferManagerV1.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wp.SinglePixelBufferManagerV1.getInterface().name) == .eq) { self.single_pixel_buffer_manager = try registry.bind(name, wp.SinglePixelBufferManagerV1, 1); - } else if (strcmp(iface, zwlr.LayerShellV1.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, zwlr.LayerShellV1.getInterface().name) == .eq) { self.layer_shell = try registry.bind(name, zwlr.LayerShellV1, 1); - } else if (strcmp(iface, zriver.StatusManagerV1.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, zriver.StatusManagerV1.getInterface().name) == .eq) { self.status_manager = try registry.bind(name, zriver.StatusManagerV1, 1); - } else if (strcmp(iface, zriver.ControlV1.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, zriver.ControlV1.getInterface().name) == .eq) { self.control = try registry.bind(name, zriver.ControlV1, 1); - } else if (strcmp(iface, wl.Output.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wl.Output.getInterface().name) == .eq) { const monitor = try Monitor.create(registry, name); try self.monitors.append(monitor); - } else if (strcmp(iface, wl.Seat.getInterface().name) == 0) { + } else if (mem.orderZ(u8, iface, wl.Seat.getInterface().name) == .eq) { const input = try Input.create(registry, name); try self.inputs.append(input); } diff --git a/src/modules/Backlight.zig b/src/modules/Backlight.zig @@ -69,9 +69,9 @@ pub fn refresh(self: *Backlight) !void { pub fn print(self: *Backlight, writer: anytype) !void { try updateDevices(state.gpa, self.context, &self.devices); const device = self.devices.items[0]; - var percent = @intToFloat(f64, device.value) * 100.0; - percent /= @intToFloat(f64, device.max); - const value = @floatToInt(u8, @round(percent)); + 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}); } diff --git a/src/modules/Battery.zig b/src/modules/Battery.zig @@ -36,8 +36,8 @@ pub fn init() !Battery { .it_interval = .{ .tv_sec = 10, .tv_nsec = 0 }, .it_value = .{ .tv_sec = 10, .tv_nsec = 0 }, }; - _ = os.linux.timerfd_settime(@intCast(i32, fd), 0, &interval, null); - break :tfd @intCast(os.fd_t, fd); + _ = 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(); @@ -161,7 +161,7 @@ fn computeCapacityFromEnergy(dev: *udev.Device) !u8 { const energy_full = try fmt.parseFloat(f64, energy_full_str); const capacity = energy * 100.0 / energy_full; - return @floatToInt(u8, @round(capacity)); + return @as(u8, @intFromFloat(@round(capacity))); } fn computeCapacityFromCharge(dev: *udev.Device) !u8 { @@ -172,5 +172,5 @@ fn computeCapacityFromCharge(dev: *udev.Device) !u8 { const charge_full = try fmt.parseFloat(f64, charge_full_str); const capacity = charge * 100.0 / charge_full; - return @floatToInt(u8, @round(capacity)); + return @as(u8, @intFromFloat(@round(capacity))); } diff --git a/src/modules/Pulse.zig b/src/modules/Pulse.zig @@ -27,7 +27,7 @@ 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 @intCast(os.fd_t, fd); + break :efd @as(os.fd_t, @intCast(fd)); }; // setup pulseaudio api @@ -63,7 +63,7 @@ pub fn start(self: *Pulse) !void { pulse.pa_context_set_state_callback( self.context, contextStateCallback, - @ptrCast(*anyopaque, self), + @as(*anyopaque, @ptrCast(self)), ); const started = pulse.pa_threaded_mainloop_start(self.mainloop); if (started < 0) return error.StartFailed; @@ -187,9 +187,9 @@ export fn sinkInfoCallback( self.volume = volume: { const avg = pulse.pa_cvolume_avg(&info.volume); - const norm = @intToFloat(f64, pulse.PA_VOLUME_NORM); - const ratio = 100 * @intToFloat(f64, avg) / norm; - break :volume @floatToInt(u8, @round(ratio)); + const norm = @as(f64, @floatFromInt(pulse.PA_VOLUME_NORM)); + const ratio = 100 * @as(f64, @floatFromInt(avg)) / norm; + break :volume @as(u8, @intFromFloat(@round(ratio))); }; self.muted = info.mute != 0; diff --git a/src/render.zig b/src/render.zig @@ -30,9 +30,9 @@ pub fn renderTags(bar: *Bar) !void { if (buffer.buffer == null) return; buffer.busy = true; - for (tags) |*tag, i| { - const offset = @intCast(i16, bar.height * i); - try renderTag(buffer.pix.?, tag, bar.height, offset); + for (&tags, 0..) |*tag, i| { + const offset = bar.height * i; + try renderTag(buffer.pix.?, tag, bar.height, @intCast(offset)); } surface.setBufferScale(bar.monitor.scale); @@ -59,13 +59,13 @@ pub fn renderClock(bar: *Bar) !void { var i: usize = 0; var width: u16 = 0; while (i < run.count) : (i += 1) { - width += @intCast(u16, run.glyphs[i].advance.x); + width += @as(u16, @intCast(run.glyphs[i].advance.x)); } // set subsurface offset - const font_height = @intCast(u32, font.height); - const x_offset = @intCast(i32, (bar.width - width) / 2); - const y_offset = @intCast(i32, (bar.height - font_height) / 2); + const font_height = @as(u32, @intCast(font.height)); + const x_offset = @as(i32, @intCast((bar.width - width) / 2)); + const y_offset = @as(i32, @intCast((bar.height - font_height) / 2)); bar.clock.subsurface.setPosition(x_offset, y_offset); const buffers = &bar.clock.buffers; @@ -84,10 +84,10 @@ pub fn renderClock(bar: *Bar) !void { var color = pixman.Image.createSolidFill(&state.config.foregroundColor).?; while (i < run.count) : (i += 1) { const glyph = run.glyphs[i]; - x += @intCast(i32, glyph.x); - const y = state.config.font.ascent - @intCast(i32, glyph.y); + x += @as(i32, @intCast(glyph.x)); + const y = state.config.font.ascent - @as(i32, @intCast(glyph.y)); pixman.Image.composite32(.over, color, glyph.pix, buffer.pix.?, 0, 0, 0, 0, x, y, glyph.width, glyph.height); - x += glyph.advance.x - @intCast(i32, glyph.x); + x += glyph.advance.x - @as(i32, @intCast(glyph.x)); } surface.setBufferScale(bar.monitor.scale); @@ -126,13 +126,13 @@ pub fn renderModules(bar: *Bar) !void { var i: usize = 0; var width: u16 = 0; while (i < run.count) : (i += 1) { - width += @intCast(u16, run.glyphs[i].advance.x); + width += @as(u16, @intCast(run.glyphs[i].advance.x)); } // set subsurface offset - const font_height = @intCast(u32, state.config.font.height); - var x_offset = @intCast(i32, bar.width - width); - var y_offset = @intCast(i32, @divFloor(bar.height - font_height, 2)); + 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))); bar.modules.subsurface.setPosition(x_offset, y_offset); const buffers = &bar.modules.buffers; @@ -151,10 +151,10 @@ pub fn renderModules(bar: *Bar) !void { var color = pixman.Image.createSolidFill(&state.config.foregroundColor).?; while (i < run.count) : (i += 1) { const glyph = run.glyphs[i]; - x += @intCast(i32, glyph.x); - const y = state.config.font.ascent - @intCast(i32, glyph.y); + x += @as(i32, @intCast(glyph.x)); + const y = state.config.font.ascent - @as(i32, @intCast(glyph.y)); pixman.Image.composite32(.over, color, glyph.pix, buffer.pix.?, 0, 0, 0, 0, x, y, glyph.width, glyph.height); - x += glyph.advance.x - @intCast(i32, glyph.x); + x += glyph.advance.x - @as(i32, @intCast(glyph.x)); } surface.setBufferScale(bar.monitor.scale); @@ -168,7 +168,7 @@ fn renderTag( height: u16, offset: i16, ) !void { - const size = @intCast(u16, height); + const size = @as(u16, @intCast(height)); const outer = [_]pixman.Rectangle16{ .{ .x = offset, .y = 0, .width = size, .height = size }, @@ -217,5 +217,5 @@ fn formatDatetime() ![]const u8 { state.config.clockFormat, local, ); - return state.gpa.resize(buf, len).?; + return state.gpa.realloc(buf, len); } diff --git a/src/utils.zig b/src/utils.zig @@ -8,7 +8,7 @@ const unicode = std.unicode; pub fn cast(comptime to: type) fn (*anyopaque) *to { return (struct { pub fn cast(module: *anyopaque) *to { - return @ptrCast(*to, @alignCast(@alignOf(to), module)); + return @ptrCast(@alignCast(module)); } }).cast; } @@ -17,12 +17,10 @@ pub fn toUtf8(gpa: mem.Allocator, bytes: []const u8) ![]u32 { const utf8 = try unicode.Utf8View.init(bytes); var iter = utf8.iterator(); - var runes = try gpa.alloc(u32, bytes.len); - var i: usize = 0; - while (iter.nextCodepoint()) |rune| : (i += 1) { - runes[i] = rune; + var runes = try std.ArrayList(u32).initCapacity(gpa, bytes.len); + while (iter.nextCodepoint()) |rune| { + runes.appendAssumeCapacity(rune); } - runes = gpa.resize(runes, i).?; - return runes; + return runes.toOwnedSlice(); }