1const std = @import("std");2const log = std.log;34const wl = @import("wayland").client.wl;56const Bar = @import("Bar.zig");7const Input = @This();89const state = &@import("root").state;1011globalName: u32,1213pointer: struct {14 pointer: ?*wl.Pointer,15 x: i32,16 y: i32,17 bar: ?*Bar,18 surface: ?*wl.Surface,19},2021pub fn create(name: u32) !*Input {22 const self = try state.gpa.create(Input);23 const seat = state.wayland.seat.?;2425 self.globalName = name;26 self.pointer.pointer = null;27 self.pointer.bar = null;28 self.pointer.surface = null;2930 seat.setListener(*Input, listener, self);31 return self;32}3334pub fn destroy(self: *Input) void {35 if (self.pointer.pointer) |pointer| {36 pointer.release();37 }38 state.gpa.destroy(self);39}4041fn listener(seat: *wl.Seat, event: wl.Seat.Event, input: *Input) void {42 switch (event) {43 .capabilities => |data| {44 if (input.pointer.pointer) |pointer| {45 pointer.release();46 input.pointer.pointer = null;47 }48 if (data.capabilities.pointer) {49 input.pointer.pointer = seat.getPointer() catch |err| {50 log.err("cannot obtain seat pointer: {s}", .{@errorName(err)});51 return;52 };53 input.pointer.pointer.?.setListener(54 *Input,55 pointerListener,56 input,57 );58 }59 },60 .name => {},61 }62}6364fn pointerListener(65 _: *wl.Pointer,66 event: wl.Pointer.Event,67 input: *Input,68) void {69 switch (event) {70 .enter => |data| {71 input.pointer.x = data.surface_x.toInt();72 input.pointer.y = data.surface_y.toInt();73 const bar = state.wayland.findBar(data.surface);74 input.pointer.bar = bar;75 input.pointer.surface = data.surface;76 },77 .leave => |_| {78 input.pointer.bar = null;79 input.pointer.surface = null;80 },81 .motion => |data| {82 input.pointer.x = data.surface_x.toInt();83 input.pointer.y = data.surface_y.toInt();84 },85 .button => |data| {86 if (data.state != .pressed) return;87 if (input.pointer.bar) |bar| {88 if (!bar.configured) return;8990 const tagsSurface = bar.tags.surface;91 if (input.pointer.surface != tagsSurface) return;9293 const x: u32 = @intCast(input.pointer.x);94 if (x < bar.height * @as(u16, bar.monitor.tags.tags.len)) {95 bar.monitor.tags.handleClick(x) catch |err| {96 log.err("handleClick failed for monitor {}: {s}",97 .{bar.monitor.globalName, @errorName(err)});98 return;99 };100 }101 }102 },103 else => {},104 }105}