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;89const render = @import("render.zig");10const Loop = @This();1112const state = &@import("root").state;1314sfd: posix.fd_t,1516pub 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);2122 _ = linux.sigprocmask(linux.SIG.BLOCK, &mask, null);23 const sfd = linux.signalfd(-1, &mask, linux.SFD.NONBLOCK);2425 return Loop{ .sfd = @intCast(sfd) };26}2728pub fn run(self: *Loop) !void {29 const wayland = &state.wayland;3031 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 };4849 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 }5758 _ = posix.poll(&fds, -1) catch |err| {59 log.err("poll failed: {s}", .{@errorName(err)});60 return;61 };6263 for (fds) |fd| {64 if (fd.revents & posix.POLL.HUP != 0 or fd.revents & posix.POLL.ERR != 0) {65 return;66 }67 }6869 // signals70 if (fds[0].revents & posix.POLL.IN != 0) {71 return;72 }7374 // wayland75 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 }8384 // status input85 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();9495 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 };99100 bar.text.surface.commit();101 bar.background.surface.commit();102 }103 }104 }105 }106}