stevee

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

commit 8d44f6f186610dc93b9fd6396c3020d5e0fa44fc
parent 9dcaffc942929d1bd318ed6a1da8eb274261f5f8
Author: Andrea Feletto <andrea@andreafeletto.com>
Date:   Sun, 18 Dec 2022 15:50:23 +0100

remove globals abstraction and make them optional

Diffstat:
Msrc/Bar.zig | 32++++++++++++++++++--------------
Msrc/Tags.zig | 14++++++--------
Msrc/Wayland.zig | 113++++++++++++++++++++++++++-----------------------------------------------------
Msrc/Widget.zig | 10++++------
Msrc/render.zig | 14++++++--------
Msrc/utils.zig | 5-----
6 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/src/Bar.zig b/src/Bar.zig @@ -15,7 +15,7 @@ const state = &@import("root").state; monitor: *Monitor, -layerSurface: *zwlr.LayerSurfaceV1, +layer_surface: *zwlr.LayerSurfaceV1, background: struct { surface: *wl.Surface, viewport: *wp.Viewport, @@ -31,18 +31,22 @@ width: u16, height: u16, pub fn create(monitor: *Monitor) !*Bar { - const globals = &state.wayland.globals; - const self = try state.gpa.create(Bar); self.monitor = monitor; self.configured = false; - self.background.surface = try globals.compositor.createSurface(); - self.background.viewport = try globals.viewporter.getViewport(self.background.surface); - try self.background.buffer.resize(globals.shm, 1, 1); - if (self.background.buffer.data) |data| data[0] = 0xff000000 else unreachable; + const compositor = state.wayland.compositor.?; + const viewporter = state.wayland.viewporter.?; + const shm = state.wayland.shm.?; + const layer_shell = state.wayland.layer_shell.?; + + self.background.surface = try compositor.createSurface(); + self.background.viewport = try viewporter.getViewport(self.background.surface); + + try self.background.buffer.resize(shm, 1, 1); + self.background.buffer.data.?[0] = 0xff000000; - self.layerSurface = try globals.layerShell.getLayerSurface( + self.layer_surface = try layer_shell.getLayerSurface( self.background.surface, monitor.output, .top, @@ -54,13 +58,13 @@ pub fn create(monitor: *Monitor) !*Bar { self.modules = try Widget.init(self.background.surface); // setup layer surface - self.layerSurface.setSize(0, state.config.height); - self.layerSurface.setAnchor( + self.layer_surface.setSize(0, state.config.height); + self.layer_surface.setAnchor( .{ .top = true, .left = true, .right = true, .bottom = false }, ); - self.layerSurface.setExclusiveZone(state.config.height); - self.layerSurface.setMargin(0, 0, 0, 0); - self.layerSurface.setListener(*Bar, layerSurfaceListener, self); + self.layer_surface.setExclusiveZone(state.config.height); + self.layer_surface.setMargin(0, 0, 0, 0); + self.layer_surface.setListener(*Bar, layerSurfaceListener, self); self.tags.surface.commit(); self.clock.surface.commit(); @@ -74,7 +78,7 @@ pub fn destroy(self: *Bar) void { self.monitor.bar = null; self.background.surface.destroy(); - self.layerSurface.destroy(); + self.layer_surface.destroy(); self.background.buffer.deinit(); self.tags.deinit(); diff --git a/src/Tags.zig b/src/Tags.zig @@ -10,7 +10,7 @@ const Tags = @This(); const state = &@import("root").state; monitor: *Monitor, -outputStatus: *zriver.OutputStatusV1, +output_status: *zriver.OutputStatusV1, tags: [9]Tag, pub const Tag = struct { @@ -21,22 +21,20 @@ pub const Tag = struct { pub fn create(monitor: *Monitor) !*Tags { const self = try state.gpa.create(Tags); - const globals = &state.wayland.globals; + const manager = state.wayland.status_manager.?; self.monitor = monitor; - self.outputStatus = try globals.statusManager.getRiverOutputStatus( - monitor.output, - ); + self.output_status = try manager.getRiverOutputStatus(monitor.output); for (self.tags) |*tag, i| { tag.label = '1' + @intCast(u8, i); } - self.outputStatus.setListener(*Tags, outputStatusListener, self); + self.output_status.setListener(*Tags, outputStatusListener, self); return self; } pub fn destroy(self: *Tags) void { - self.outputStatus.destroy(); + self.output_status.destroy(); state.gpa.destroy(self); } @@ -74,7 +72,7 @@ fn outputStatusListener( } pub fn handleClick(self: *Tags, x: u32, input: *Input) !void { - const control = state.wayland.globals.control; + const control = state.wayland.control.?; if (self.monitor.bar) |bar| { const index = x / bar.height; diff --git a/src/Wayland.zig b/src/Wayland.zig @@ -23,21 +23,16 @@ const state = &@import("root").state; display: *wl.Display, fd: os.fd_t, +compositor: ?*wl.Compositor = null, +subcompositor: ?*wl.Subcompositor = null, +shm: ?*wl.Shm = null, +viewporter: ?*wp.Viewporter = null, +layer_shell: ?*zwlr.LayerShellV1 = null, +status_manager: ?*zriver.StatusManagerV1 = null, +control: ?*zriver.ControlV1 = null, + monitors: ArrayList(*Monitor), inputs: ArrayList(*Input), -globals: Globals, -globalsMask: GlobalsMask, - -const Globals = struct { - compositor: *wl.Compositor, - subcompositor: *wl.Subcompositor, - shm: *wl.Shm, - viewporter: *wp.Viewporter, - layerShell: *zwlr.LayerShellV1, - statusManager: *zriver.StatusManagerV1, - control: *zriver.ControlV1, -}; -const GlobalsMask = utils.Mask(Globals); pub fn init() !Wayland { const display = try wl.Display.connect(null); @@ -48,8 +43,6 @@ pub fn init() !Wayland { .fd = wfd, .monitors = ArrayList(*Monitor).init(state.gpa), .inputs = ArrayList(*Input).init(state.gpa), - .globals = undefined, - .globalsMask = mem.zeroes(GlobalsMask), }; } @@ -60,11 +53,14 @@ pub fn deinit(self: *Wayland) void { self.monitors.deinit(); self.inputs.deinit(); - inline for (@typeInfo(Globals).Struct.fields) |field, i| { - if (self.globalsMask[i]) { - @field(self.globals, field.name).destroy(); - } - } + if (self.compositor) |global| global.destroy(); + if (self.subcompositor) |global| global.destroy(); + if (self.shm) |global| global.destroy(); + if (self.viewporter) |global| global.destroy(); + if (self.layer_shell) |global| global.destroy(); + if (self.status_manager) |global| global.destroy(); + if (self.control) |global| global.destroy(); + self.display.disconnect(); } @@ -75,9 +71,6 @@ pub fn registerGlobals(self: *Wayland) !void { registry.setListener(*Wayland, registryListener, self); const errno = self.display.roundtrip(); if (errno != .SUCCESS) return error.RoundtripFailed; - for (self.globalsMask) |is_registered| if (!is_registered) { - return error.GlobalNotAdvertized; - }; } pub fn findBar(self: *Wayland, wlSurface: ?*wl.Surface) ?*Bar { @@ -101,77 +94,45 @@ pub fn findBar(self: *Wayland, wlSurface: ?*wl.Surface) ?*Bar { fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Wayland) void { switch (event) { .global => |g| { - self.bindGlobal(registry, g.name, g.interface, g.version) catch |err| switch (err) { - error.OutOfMemory => { - log.err("out of memory", .{}); - return; - }, - }; + self.bindGlobal(registry, g.name, g.interface) catch unreachable; }, .global_remove => |g| { - for (self.monitors.items) |monitor, i| if (monitor.globalName == g.name) { - monitor.destroy(); - _ = self.monitors.swapRemove(i); - break; - }; - for (self.inputs.items) |input, i| if (input.globalName == g.name) { - input.destroy(); - _ = self.inputs.swapRemove(i); - break; - }; + for (self.monitors.items) |monitor, i| { + if (monitor.globalName == g.name) { + self.monitors.swapRemove(i).destroy(); + break; + } + } + for (self.inputs.items) |input, i| { + if (input.globalName == g.name) { + self.inputs.swapRemove(i).destroy(); + break; + } + } }, } } -fn bindGlobal(self: *Wayland, registry: *wl.Registry, name: u32, iface: [*:0]const u8, version: u32) !void { +fn bindGlobal(self: *Wayland, registry: *wl.Registry, name: u32, iface: [*:0]const u8) !void { if (strcmp(iface, wl.Compositor.getInterface().name) == 0) { - if (version < 4) { - log.err("wl_compositor version 4 is required", .{}); - return; - } - const global = try registry.bind(name, wl.Compositor, 4); - self.setGlobal(global); + self.compositor = try registry.bind(name, wl.Compositor, 4); } else if (strcmp(iface, wl.Subcompositor.getInterface().name) == 0) { - const global = try registry.bind(name, wl.Subcompositor, 1); - self.setGlobal(global); + self.subcompositor = try registry.bind(name, wl.Subcompositor, 1); } else if (strcmp(iface, wl.Shm.getInterface().name) == 0) { - const global = try registry.bind(name, wl.Shm, 1); - self.setGlobal(global); + self.shm = try registry.bind(name, wl.Shm, 1); } else if (strcmp(iface, wp.Viewporter.getInterface().name) == 0) { - const global = try registry.bind(name, wp.Viewporter, 1); - self.setGlobal(global); + self.viewporter = try registry.bind(name, wp.Viewporter, 1); } else if (strcmp(iface, zwlr.LayerShellV1.getInterface().name) == 0) { - const global = try registry.bind(name, zwlr.LayerShellV1, 1); - self.setGlobal(global); + self.layer_shell = try registry.bind(name, zwlr.LayerShellV1, 1); } else if (strcmp(iface, zriver.StatusManagerV1.getInterface().name) == 0) { - const global = try registry.bind(name, zriver.StatusManagerV1, 1); - self.setGlobal(global); + self.status_manager = try registry.bind(name, zriver.StatusManagerV1, 1); } else if (strcmp(iface, zriver.ControlV1.getInterface().name) == 0) { - const global = try registry.bind(name, zriver.ControlV1, 1); - self.setGlobal(global); + self.control = try registry.bind(name, zriver.ControlV1, 1); } else if (strcmp(iface, wl.Output.getInterface().name) == 0) { - if (version < 3) { - log.err("wl_output version 3 is required", .{}); - return; - } const monitor = try Monitor.create(registry, name); try self.monitors.append(monitor); } else if (strcmp(iface, wl.Seat.getInterface().name) == 0) { - if (version < 5) { - log.err("wl_seat version 5 is required", .{}); - return; - } const input = try Input.create(registry, name); try self.inputs.append(input); } } - -fn setGlobal(self: *Wayland, global: anytype) void { - inline for (meta.fields(Globals)) |field, i| { - if (field.field_type == @TypeOf(global)) { - @field(self.globals, field.name) = global; - self.globalsMask[i] = true; - break; - } - } -} diff --git a/src/Widget.zig b/src/Widget.zig @@ -13,13 +13,11 @@ subsurface: *wl.Subsurface, buffers: [2]Buffer, pub fn init(background: *wl.Surface) !Widget { - const globals = &state.wayland.globals; + const compositor = state.wayland.compositor.?; + const subcompositor = state.wayland.subcompositor.?; - const surface = try globals.compositor.createSurface(); - const subsurface = try globals.subcompositor.getSubsurface( - surface, - background, - ); + const surface = try compositor.createSurface(); + const subsurface = try subcompositor.getSubsurface(surface, background); return Widget{ .surface = surface, diff --git a/src/render.zig b/src/render.zig @@ -22,13 +22,11 @@ pub fn renderTags(bar: *Bar) !void { const surface = bar.tags.surface; const tags = bar.monitor.tags.tags; + const buffers = &bar.tags.buffers; + const shm = state.wayland.shm.?; + const width = bar.height * 9; - const buffer = try Buffer.nextBuffer( - &bar.tags.buffers, - state.wayland.globals.shm, - width, - bar.height, - ); + const buffer = try Buffer.nextBuffer(buffers, shm, width, bar.height); if (buffer.buffer == null) return; buffer.busy = true; @@ -44,7 +42,7 @@ pub fn renderTags(bar: *Bar) !void { pub fn renderClock(bar: *Bar) !void { const surface = bar.clock.surface; - const shm = state.wayland.globals.shm; + const shm = state.wayland.shm.?; // utf8 datetime const str = try formatDatetime(); @@ -99,7 +97,7 @@ pub fn renderClock(bar: *Bar) !void { pub fn renderModules(bar: *Bar) !void { const surface = bar.modules.surface; - const shm = state.wayland.globals.shm; + const shm = state.wayland.shm.?; // compose string var string = std.ArrayList(u8).init(state.gpa); diff --git a/src/utils.zig b/src/utils.zig @@ -13,11 +13,6 @@ pub fn cast(comptime to: type) fn (*anyopaque) *to { }).cast; } -pub fn Mask(comptime container: type) type { - const len = meta.fields(container).len; - return [len]bool; -} - pub fn toUtf8(gpa: mem.Allocator, bytes: []const u8) ![]u32 { const utf8 = try unicode.Utf8View.init(bytes); var iter = utf8.iterator();