Tags.zig (2496B)
1 const std = @import("std"); 2 3 const zriver = @import("wayland").client.zriver; 4 5 const Monitor = @import("Monitor.zig"); 6 const render = @import("render.zig"); 7 const Input = @import("Input.zig"); 8 const Tags = @This(); 9 10 const state = &@import("root").state; 11 12 monitor: *Monitor, 13 output_status: *zriver.OutputStatusV1, 14 tags: [5]Tag, 15 16 pub const Tag = struct { 17 label: u8, 18 focused: bool = false, 19 occupied: bool = false, 20 }; 21 22 pub fn create(monitor: *Monitor) !*Tags { 23 const self = try state.gpa.create(Tags); 24 const manager = state.wayland.status_manager.?; 25 26 self.monitor = monitor; 27 self.output_status = try manager.getRiverOutputStatus(monitor.output); 28 for (&self.tags, 0..) |*tag, i| { 29 tag.label = '1' + @as(u8, @intCast(i)); 30 } 31 32 self.output_status.setListener(*Tags, outputStatusListener, self); 33 return self; 34 } 35 36 pub fn destroy(self: *Tags) void { 37 self.output_status.destroy(); 38 state.gpa.destroy(self); 39 } 40 41 fn outputStatusListener( 42 _: *zriver.OutputStatusV1, 43 event: zriver.OutputStatusV1.Event, 44 tags: *Tags, 45 ) void { 46 switch (event) { 47 .focused_tags => |data| { 48 for (&tags.tags, 0..) |*tag, i| { 49 const mask = @as(u32, 1) << @as(u5, @intCast(i)); 50 tag.focused = data.tags & mask != 0; 51 } 52 }, 53 .view_tags => |data| { 54 for (&tags.tags) |*tag| { 55 tag.occupied = false; 56 } 57 for (data.tags.slice(u32)) |view| { 58 for (&tags.tags, 0..) |*tag, i| { 59 const mask = @as(u32, 1) << @as(u5, @intCast(i)); 60 if (view & mask != 0) tag.occupied = true; 61 } 62 } 63 }, 64 } 65 if (tags.monitor.bar) |bar| { 66 if (bar.configured) { 67 render.renderTags(bar) catch return; 68 bar.tags.surface.commit(); 69 bar.background.surface.commit(); 70 } 71 } 72 } 73 74 pub fn handleClick(self: *Tags, x: u32, input: *Input) !void { 75 const control = state.wayland.control.?; 76 77 if (self.monitor.bar) |bar| { 78 const index = x / bar.height; 79 const payload = try std.fmt.allocPrintZ( 80 state.gpa, 81 "{d}", 82 .{@as(u32, 1) << @as(u5, @intCast(index))}, 83 ); 84 defer state.gpa.free(payload); 85 86 control.addArgument("set-focused-tags"); 87 control.addArgument(payload); 88 const callback = try control.runCommand(input.seat); 89 _ = callback; 90 } 91 }