commit 6bdc9ba0da891c11d9c73d551b6fb3784a558bd7
parent d751f48a9c677a9cba7f22bdad469d527d11df56
Author: Andrea Feletto <andrea@andreafeletto.com>
Date: Thu, 28 Apr 2022 22:11:30 +0200
split wayland.zig
Diffstat:
7 files changed, 341 insertions(+), 336 deletions(-)
diff --git a/src/Bar.zig b/src/Bar.zig
@@ -5,7 +5,7 @@ const wl = @import("wayland").client.wl;
const zwlr = @import("wayland").client.zwlr;
const Buffer = @import("Buffer.zig");
-const Monitor = @import("wayland.zig").Monitor;
+const Monitor = @import("Monitor.zig");
const render = @import("render.zig");
const State = @import("main.zig").State;
const Bar = @This();
diff --git a/src/Input.zig b/src/Input.zig
@@ -0,0 +1,98 @@
+const wl = @import("wayland").client.wl;
+
+const State = @import("main.zig").State;
+const Bar = @import("Bar.zig");
+const Input = @This();
+
+state: *State,
+seat: *wl.Seat,
+globalName: u32,
+
+pointer: struct {
+ pointer: ?*wl.Pointer,
+ x: i32,
+ y: i32,
+ bar: ?*Bar,
+ surface: ?*wl.Surface,
+},
+
+pub fn create(state: *State, registry: *wl.Registry, name: u32) !*Input {
+ const self = try state.gpa.create(Input);
+ self.state = state;
+ self.seat = try registry.bind(name, wl.Seat, 3);
+ self.globalName = name;
+
+ self.pointer.pointer = null;
+ self.pointer.bar = null;
+ self.pointer.surface = null;
+
+ self.seat.setListener(*Input, listener, self);
+ return self;
+}
+
+pub fn destroy(self: *Input) void {
+ if (self.pointer.pointer) |pointer| {
+ pointer.release();
+ }
+ self.seat.release();
+ self.state.gpa.destroy(self);
+}
+
+fn listener(seat: *wl.Seat, event: wl.Seat.Event, input: *Input) void {
+ switch (event) {
+ .capabilities => |data| {
+ if (input.pointer.pointer) |pointer| {
+ pointer.release();
+ input.pointer.pointer = null;
+ }
+ if (data.capabilities.pointer) {
+ input.pointer.pointer = seat.getPointer() catch return;
+ input.pointer.pointer.?.setListener(
+ *Input,
+ pointerListener,
+ input,
+ );
+ }
+ },
+ .name => {},
+ }
+}
+
+fn pointerListener(
+ _: *wl.Pointer,
+ event: wl.Pointer.Event,
+ input: *Input,
+) void {
+ switch (event) {
+ .enter => |data| {
+ input.pointer.x = data.surface_x.toInt();
+ input.pointer.y = data.surface_y.toInt();
+ const bar = input.state.wayland.findBar(data.surface);
+ input.pointer.bar = bar;
+ input.pointer.surface = data.surface;
+ },
+ .leave => |_| {
+ input.pointer.bar = null;
+ input.pointer.surface = null;
+ },
+ .motion => |data| {
+ input.pointer.x = data.surface_x.toInt();
+ input.pointer.y = data.surface_y.toInt();
+ },
+ .button => |data| {
+ if (data.state != .pressed) return;
+ if (input.pointer.bar) |bar| {
+ if (!bar.configured) return;
+
+ const tagsSurface = bar.tags.surface;
+ if (input.pointer.surface != tagsSurface) return;
+
+ const x = @intCast(u32, input.pointer.x);
+ if (x < bar.height * 9) {
+ bar.monitor.tags.handleClick(x, input) catch return;
+ }
+ }
+ },
+ else => {},
+ }
+}
diff --git a/src/Monitor.zig b/src/Monitor.zig
@@ -0,0 +1,53 @@
+const wl = @import("wayland").client.wl;
+
+const State = @import("main.zig").State;
+const Bar = @import("Bar.zig");
+const Tags = @import("Tags.zig");
+const Monitor = @This();
+
+state: *State,
+output: *wl.Output,
+globalName: u32,
+scale: i32,
+
+bar: ?*Bar,
+tags: *Tags,
+
+pub fn create(state: *State, registry: *wl.Registry, name: u32) !*Monitor {
+ const self = try state.gpa.create(Monitor);
+ self.state = state;
+ self.output = try registry.bind(name, wl.Output, 3);
+ self.globalName = name;
+ self.scale = 1;
+
+ self.bar = null;
+ self.tags = try Tags.create(state, self);
+
+ self.output.setListener(*Monitor, listener, self);
+ return self;
+}
+
+pub fn destroy(self: *Monitor) void {
+ if (self.bar) |bar| {
+ bar.destroy();
+ }
+ self.tags.destroy();
+ self.state.gpa.destroy(self);
+}
+
+fn listener(_: *wl.Output, event: wl.Output.Event, monitor: *Monitor) void {
+ switch (event) {
+ .scale => |scale| {
+ monitor.scale = scale.factor;
+ },
+ .geometry => {},
+ .mode => {},
+ .name => {},
+ .description => {},
+ .done => {
+ if (monitor.bar) |_| {} else {
+ monitor.bar = Bar.create(monitor) catch return;
+ }
+ },
+ }
+}
diff --git a/src/Tags.zig b/src/Tags.zig
@@ -2,9 +2,9 @@ const std = @import("std");
const zriver = @import("wayland").client.zriver;
-const Monitor = @import("wayland.zig").Monitor;
+const Monitor = @import("Monitor.zig");
const render = @import("render.zig");
-const Input = @import("wayland.zig").Input;
+const Input = @import("Input.zig");
const State = @import("main.zig").State;
const Tags = @This();
diff --git a/src/Wayland.zig b/src/Wayland.zig
@@ -0,0 +1,186 @@
+const std = @import("std");
+const mem = std.mem;
+const meta = std.meta;
+const os = std.os;
+const strcmp = std.cstr.cmp;
+const ArrayList = std.ArrayList;
+
+const wl = @import("wayland").client.wl;
+const zwlr = @import("wayland").client.zwlr;
+const zriver = @import("wayland").client.zriver;
+
+const Bar = @import("Bar.zig");
+const Event = @import("Loop.zig").Event;
+const Input = @import("Input.zig");
+const Monitor = @import("Monitor.zig");
+const State = @import("main.zig").State;
+const utils = @import("utils.zig");
+const Wayland = @This();
+
+state: *State,
+display: *wl.Display,
+registry: *wl.Registry,
+
+monitors: ArrayList(*Monitor),
+inputs: ArrayList(*Input),
+globals: Globals,
+globalsMask: GlobalsMask,
+
+const Globals = struct {
+ compositor: *wl.Compositor,
+ subcompositor: *wl.Subcompositor,
+ shm: *wl.Shm,
+ layerShell: *zwlr.LayerShellV1,
+ statusManager: *zriver.StatusManagerV1,
+ control: *zriver.ControlV1,
+};
+const GlobalsMask = utils.Mask(Globals);
+
+pub fn init(state: *State) !Wayland {
+ const display = try wl.Display.connect(null);
+
+ return Wayland{
+ .state = state,
+ .display = display,
+ .registry = try display.getRegistry(),
+ .monitors = ArrayList(*Monitor).init(state.gpa),
+ .inputs = ArrayList(*Input).init(state.gpa),
+ .globals = undefined,
+ .globalsMask = mem.zeroes(GlobalsMask),
+ };
+}
+
+pub fn deinit(self: *Wayland) void {
+ for (self.monitors.items) |monitor| monitor.destroy();
+ for (self.inputs.items) |input| input.destroy();
+
+ self.monitors.deinit();
+ self.inputs.deinit();
+}
+
+pub fn registerGlobals(self: *Wayland) !void {
+ self.registry.setListener(*State, registryListener, self.state);
+ _ = try self.display.roundtrip();
+
+ for (self.globalsMask) |is_registered| {
+ if (!is_registered) return error.UnsupportedGlobal;
+ }
+}
+
+pub fn getEvent(self: *Wayland) !Event {
+ const fd = self.display.getFd();
+
+ return Event{
+ .fd = .{
+ .fd = @intCast(os.fd_t, fd),
+ .events = os.POLL.IN,
+ .revents = undefined,
+ },
+ .data = @ptrCast(*anyopaque, self),
+ .callbackIn = dispatch,
+ .callbackOut = flush,
+ };
+}
+
+fn dispatch(self_opaque: *anyopaque) error{Terminate}!void {
+ const self = utils.cast(Wayland)(self_opaque);
+ _ = self.display.dispatch() catch return;
+}
+
+fn flush(self_opaque: *anyopaque) error{Terminate}!void {
+ const self = utils.cast(Wayland)(self_opaque);
+ _ = self.display.flush() catch return;
+}
+
+fn registryListener(
+ registry: *wl.Registry,
+ event: wl.Registry.Event,
+ state: *State,
+) void {
+ const self = &state.wayland;
+
+ switch (event) {
+ .global => |g| {
+ self.bindGlobal(registry, g.interface, g.name) catch return;
+ },
+ .global_remove => |data| {
+ for (self.monitors.items) |monitor, i| {
+ if (monitor.globalName == data.name) {
+ monitor.destroy();
+ _ = self.monitors.swapRemove(i);
+ break;
+ }
+ }
+ for (self.inputs.items) |input, i| {
+ if (input.globalName == data.name) {
+ input.destroy();
+ _ = self.inputs.swapRemove(i);
+ break;
+ }
+ }
+ },
+ }
+}
+
+fn bindGlobal(
+ self: *Wayland,
+ registry: *wl.Registry,
+ iface: [*:0]const u8,
+ name: u32,
+) !void {
+ if (strcmp(iface, wl.Compositor.getInterface().name) == 0) {
+ const global = try registry.bind(name, wl.Compositor, 4);
+ self.setGlobal(global);
+ } else if (strcmp(iface, wl.Subcompositor.getInterface().name) == 0) {
+ const global = try registry.bind(name, wl.Subcompositor, 1);
+ self.setGlobal(global);
+ } else if (strcmp(iface, wl.Shm.getInterface().name) == 0) {
+ const global = try registry.bind(name, wl.Shm, 1);
+ self.setGlobal(global);
+ } else if (strcmp(iface, zwlr.LayerShellV1.getInterface().name) == 0) {
+ const global = try registry.bind(name, zwlr.LayerShellV1, 1);
+ self.setGlobal(global);
+ } else if (
+ strcmp(iface, zriver.StatusManagerV1.getInterface().name) == 0
+ ) {
+ const global = try registry.bind(name, zriver.StatusManagerV1, 1);
+ self.setGlobal(global);
+ } else if (strcmp(iface, zriver.ControlV1.getInterface().name) == 0) {
+ const global = try registry.bind(name, zriver.ControlV1, 1);
+ self.setGlobal(global);
+ } else if (strcmp(iface, wl.Output.getInterface().name) == 0) {
+ const monitor = try Monitor.create(self.state, registry, name);
+ try self.monitors.append(monitor);
+ } else if (strcmp(iface, wl.Seat.getInterface().name) == 0) {
+ const input = try Input.create(self.state, registry, name);
+ try self.inputs.append(input);
+ }
+}
+
+pub 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;
+ }
+ }
+}
+
+pub fn findBar(self: *Wayland, wlSurface: ?*wl.Surface) ?*Bar {
+ if (wlSurface == null) {
+ return null;
+ }
+ for (self.monitors.items) |monitor| {
+ if (monitor.bar) |bar| {
+ if (bar.background.surface == wlSurface or
+ bar.tags.surface == wlSurface or
+ bar.clock.surface == wlSurface or
+ bar.modules.surface == wlSurface)
+ {
+ return bar;
+ }
+ }
+ }
+ return null;
+}
diff --git a/src/main.zig b/src/main.zig
@@ -10,7 +10,7 @@ const fcft = @import("fcft");
const Config = @import("Config.zig");
const Loop = @import("Loop.zig");
const Modules = @import("Modules.zig");
-const Wayland = @import("wayland.zig").Wayland;
+const Wayland = @import("Wayland.zig");
pub const State = struct {
gpa: mem.Allocator,
diff --git a/src/wayland.zig b/src/wayland.zig
@@ -1,332 +0,0 @@
-const std = @import("std");
-const mem = std.mem;
-const meta = std.meta;
-const os = std.os;
-const strcmp = std.cstr.cmp;
-const ArrayList = std.ArrayList;
-
-const wl = @import("wayland").client.wl;
-const zwlr = @import("wayland").client.zwlr;
-const zriver = @import("wayland").client.zriver;
-
-const Buffer = @import("Buffer.zig");
-const Event = @import("Loop.zig").Event;
-const render = @import("render.zig");
-const State = @import("main.zig").State;
-const Bar = @import("Bar.zig");
-const Tags = @import("Tags.zig");
-const utils = @import("utils.zig");
-
-pub const Wayland = struct {
- state: *State,
- display: *wl.Display,
- registry: *wl.Registry,
-
- monitors: ArrayList(*Monitor),
- inputs: ArrayList(*Input),
- globals: Globals,
- globalsMask: GlobalsMask,
-
- const Globals = struct {
- compositor: *wl.Compositor,
- subcompositor: *wl.Subcompositor,
- shm: *wl.Shm,
- layerShell: *zwlr.LayerShellV1,
- statusManager: *zriver.StatusManagerV1,
- control: *zriver.ControlV1,
- };
- const GlobalsMask = utils.Mask(Globals);
-
- pub fn init(state: *State) !Wayland {
- const display = try wl.Display.connect(null);
-
- return Wayland{
- .state = state,
- .display = display,
- .registry = try display.getRegistry(),
- .monitors = ArrayList(*Monitor).init(state.gpa),
- .inputs = ArrayList(*Input).init(state.gpa),
- .globals = undefined,
- .globalsMask = mem.zeroes(GlobalsMask),
- };
- }
-
- pub fn deinit(self: *Wayland) void {
- for (self.monitors.items) |monitor| monitor.destroy();
- for (self.inputs.items) |input| input.destroy();
-
- self.monitors.deinit();
- self.inputs.deinit();
- }
-
- pub fn registerGlobals(self: *Wayland) !void {
- self.registry.setListener(*State, registryListener, self.state);
- _ = try self.display.roundtrip();
-
- for (self.globalsMask) |is_registered| {
- if (!is_registered) return error.UnsupportedGlobal;
- }
- }
-
- pub fn getEvent(self: *Wayland) !Event {
- const fd = self.display.getFd();
-
- return Event{
- .fd = .{
- .fd = @intCast(os.fd_t, fd),
- .events = os.POLL.IN,
- .revents = undefined,
- },
- .data = @ptrCast(*anyopaque, self),
- .callbackIn = dispatch,
- .callbackOut = flush,
- };
- }
-
- fn dispatch(self_opaque: *anyopaque) error{Terminate}!void {
- const self = utils.cast(Wayland)(self_opaque);
- _ = self.display.dispatch() catch return;
- }
-
- fn flush(self_opaque: *anyopaque) error{Terminate}!void {
- const self = utils.cast(Wayland)(self_opaque);
- _ = self.display.flush() catch return;
- }
-
- fn registryListener(
- registry: *wl.Registry,
- event: wl.Registry.Event,
- state: *State,
- ) void {
- const self = &state.wayland;
-
- switch (event) {
- .global => |g| {
- self.bindGlobal(registry, g.interface, g.name) catch return;
- },
- .global_remove => |data| {
- for (self.monitors.items) |monitor, i| {
- if (monitor.globalName == data.name) {
- monitor.destroy();
- _ = self.monitors.swapRemove(i);
- break;
- }
- }
- for (self.inputs.items) |input, i| {
- if (input.globalName == data.name) {
- input.destroy();
- _ = self.inputs.swapRemove(i);
- break;
- }
- }
- },
- }
- }
-
- fn bindGlobal(
- self: *Wayland,
- registry: *wl.Registry,
- iface: [*:0]const u8,
- name: u32,
- ) !void {
- if (strcmp(iface, wl.Compositor.getInterface().name) == 0) {
- const global = try registry.bind(name, wl.Compositor, 4);
- self.setGlobal(global);
- } else if (strcmp(iface, wl.Subcompositor.getInterface().name) == 0) {
- const global = try registry.bind(name, wl.Subcompositor, 1);
- self.setGlobal(global);
- } else if (strcmp(iface, wl.Shm.getInterface().name) == 0) {
- const global = try registry.bind(name, wl.Shm, 1);
- self.setGlobal(global);
- } else if (strcmp(iface, zwlr.LayerShellV1.getInterface().name) == 0) {
- const global = try registry.bind(name, zwlr.LayerShellV1, 1);
- self.setGlobal(global);
- } else if (
- strcmp(iface, zriver.StatusManagerV1.getInterface().name) == 0
- ) {
- const global = try registry.bind(name, zriver.StatusManagerV1, 1);
- self.setGlobal(global);
- } else if (strcmp(iface, zriver.ControlV1.getInterface().name) == 0) {
- const global = try registry.bind(name, zriver.ControlV1, 1);
- self.setGlobal(global);
- } else if (strcmp(iface, wl.Output.getInterface().name) == 0) {
- const monitor = try Monitor.create(self.state, registry, name);
- try self.monitors.append(monitor);
- } else if (strcmp(iface, wl.Seat.getInterface().name) == 0) {
- const input = try Input.create(self.state, registry, name);
- try self.inputs.append(input);
- }
- }
-
- pub 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;
- }
- }
- }
-
- pub fn findBar(self: *Wayland, wlSurface: ?*wl.Surface) ?*Bar {
- if (wlSurface == null) {
- return null;
- }
- for (self.monitors.items) |monitor| {
- if (monitor.bar) |bar| {
- if (bar.background.surface == wlSurface or
- bar.tags.surface == wlSurface or
- bar.clock.surface == wlSurface or
- bar.modules.surface == wlSurface)
- {
- return bar;
- }
- }
- }
- return null;
- }
-};
-
-pub const Monitor = struct {
- state: *State,
- output: *wl.Output,
- globalName: u32,
- scale: i32,
-
- bar: ?*Bar,
- tags: *Tags,
-
- pub fn create(state: *State, registry: *wl.Registry, name: u32) !*Monitor {
- const self = try state.gpa.create(Monitor);
- self.state = state;
- self.output = try registry.bind(name, wl.Output, 3);
- self.globalName = name;
- self.scale = 1;
-
- self.bar = null;
- self.tags = try Tags.create(state, self);
-
- self.output.setListener(*Monitor, listener, self);
- return self;
- }
-
- pub fn destroy(self: *Monitor) void {
- if (self.bar) |bar| {
- bar.destroy();
- }
- self.tags.destroy();
- self.state.gpa.destroy(self);
- }
-
- fn listener(_: *wl.Output, event: wl.Output.Event, monitor: *Monitor) void {
- switch (event) {
- .scale => |scale| {
- monitor.scale = scale.factor;
- },
- .geometry => {},
- .mode => {},
- .name => {},
- .description => {},
- .done => {
- if (monitor.bar) |_| {} else {
- monitor.bar = Bar.create(monitor) catch return;
- }
- },
- }
- }
-};
-
-pub const Input = struct {
- state: *State,
- seat: *wl.Seat,
- globalName: u32,
-
- pointer: struct {
- pointer: ?*wl.Pointer,
- x: i32,
- y: i32,
- bar: ?*Bar,
- surface: ?*wl.Surface,
- },
-
- pub fn create(state: *State, registry: *wl.Registry, name: u32) !*Input {
- const self = try state.gpa.create(Input);
- self.state = state;
- self.seat = try registry.bind(name, wl.Seat, 3);
- self.globalName = name;
-
- self.pointer.pointer = null;
- self.pointer.bar = null;
- self.pointer.surface = null;
-
- self.seat.setListener(*Input, listener, self);
- return self;
- }
-
- pub fn destroy(self: *Input) void {
- if (self.pointer.pointer) |pointer| {
- pointer.release();
- }
- self.seat.release();
- self.state.gpa.destroy(self);
- }
-
- fn listener(seat: *wl.Seat, event: wl.Seat.Event, input: *Input) void {
- switch (event) {
- .capabilities => |data| {
- if (input.pointer.pointer) |pointer| {
- pointer.release();
- input.pointer.pointer = null;
- }
- if (data.capabilities.pointer) {
- input.pointer.pointer = seat.getPointer() catch return;
- input.pointer.pointer.?.setListener(
- *Input,
- pointerListener,
- input,
- );
- }
- },
- .name => {},
- }
- }
-
- fn pointerListener(
- _: *wl.Pointer,
- event: wl.Pointer.Event,
- input: *Input,
- ) void {
- switch (event) {
- .enter => |data| {
- input.pointer.x = data.surface_x.toInt();
- input.pointer.y = data.surface_y.toInt();
- const bar = input.state.wayland.findBar(data.surface);
- input.pointer.bar = bar;
- input.pointer.surface = data.surface;
- },
- .leave => |_| {
- input.pointer.bar = null;
- input.pointer.surface = null;
- },
- .motion => |data| {
- input.pointer.x = data.surface_x.toInt();
- input.pointer.y = data.surface_y.toInt();
- },
- .button => |data| {
- if (data.state != .pressed) return;
- if (input.pointer.bar) |bar| {
- if (!bar.configured) return;
-
- const tagsSurface = bar.tags.surface;
- if (input.pointer.surface != tagsSurface) return;
-
- const x = @intCast(u32, input.pointer.x);
- if (x < bar.height * 9) {
- bar.monitor.tags.handleClick(x, input) catch return;
- }
- }
- },
- else => {},
- }
- }
-};