1const std = @import("std");
2const log = std.log;
3const mem = std.mem;
4const posix = std.posix;
5const linux = std.os.linux;
6const io = std.io;
7const fs = std.fs;
8
9const render = @import("render.zig");
10const Loop = @This();
11
12const state = &@import("root").state;
13
14sfd: posix.fd_t,
15
16pub fn init() !Loop {
17 var mask = linux.sigemptyset();
18 linux.sigaddset(&mask, linux.SIG.INT);
19 linux.sigaddset(&mask, linux.SIG.TERM);
20 linux.sigaddset(&mask, linux.SIG.QUIT);
21
22 _ = linux.sigprocmask(linux.SIG.BLOCK, &mask, null);
23 const sfd = linux.signalfd(-1, &mask, linux.SFD.NONBLOCK);
24
25 return Loop{ .sfd = @intCast(sfd) };
26}
27
28pub fn run(self: *Loop) !void {
29 const wayland = &state.wayland;
30
31 var fds = [_]posix.pollfd{
32 .{
33 .fd = self.sfd,
34 .events = posix.POLL.IN,
35 .revents = undefined,
36 },
37 .{
38 .fd = wayland.fd,
39 .events = posix.POLL.IN,
40 .revents = undefined,
41 },
42 .{
43 .fd = posix.STDIN_FILENO,
44 .events = posix.POLL.IN,
45 .revents = undefined,
46 },
47 };
48
49 var readbuffer: [1024]u8 = undefined;
50 var reader = fs.File.stdin().reader(&readbuffer);
51 while (true) {
52 while (true) {
53 const ret = wayland.display.dispatchPending();
54 _ = wayland.display.flush();
55 if (ret == .SUCCESS) break;
56 }
57
58 _ = posix.poll(&fds, -1) catch |err| {
59 log.err("poll failed: {s}", .{@errorName(err)});
60 return;
61 };
62
63 for (fds) |fd| {
64 if (fd.revents & posix.POLL.HUP != 0 or fd.revents & posix.POLL.ERR != 0) {
65 return;
66 }
67 }
68
69 // signals
70 if (fds[0].revents & posix.POLL.IN != 0) {
71 return;
72 }
73
74 // wayland
75 if (fds[1].revents & posix.POLL.IN != 0) {
76 const errno = wayland.display.dispatch();
77 if (errno != .SUCCESS) return;
78 }
79 if (fds[1].revents & posix.POLL.OUT != 0) {
80 const errno = wayland.display.flush();
81 if (errno != .SUCCESS) return;
82 }
83
84 // status input
85 if (fds[2].revents & posix.POLL.IN != 0) {
86 if (state.wayland.river_seat) |seat| {
87 if (seat.focusedBar()) |bar| {
88 seat.status_text.reset();
89 // zig-wayland still uses std.io.DeprecatedWriter.
90 var tmp_buffer: [1024]u8 = undefined;
91 var adapter_writer = seat.status_text.writer().adaptToNewApi(&tmp_buffer);
92 _ = try reader.interface.streamDelimiter(&adapter_writer.new_interface, '\n');
93 try adapter_writer.new_interface.flush();
94
95 render.renderText(bar, seat.status_text.getWritten()) catch |err| {
96 log.err("renderText failed for monitor {}: {s}", .{ bar.monitor.globalName, @errorName(err) });
97 continue;
98 };
99
100 bar.text.surface.commit();
101 bar.background.surface.commit();
102 }
103 }
104 }
105 }
106}