Switch TagOverlay to use river_shell_surface_v1
This follows the same patterns that Wallpaper and Bar did and makes TagOverlay use the same manage/render cycle as the rest of the WM. We also switched to just use a poll timer like river-tag-overlay instead of using the timerfd. I realized that the Zig stdlib doesn't actually support timerfds for FreeBSD right now and I don't feel like adding them.
This commit is contained in:
parent
8b8efe2186
commit
3150d1a842
12 changed files with 143 additions and 335 deletions
65
src/main.zig
65
src/main.zig
|
|
@ -12,7 +12,6 @@ const Globals = struct {
|
|||
|
||||
wl_compositor: ?*wl.Compositor = null,
|
||||
wl_shm: ?*wl.Shm = null,
|
||||
|
||||
zwlr_layer_shell_v1: ?*zwlr.LayerShellV1 = null,
|
||||
};
|
||||
|
||||
|
|
@ -102,9 +101,8 @@ fn run(wl_display: *wl.Display, context: *Context) !void {
|
|||
|
||||
const poll_wayland = 0;
|
||||
const poll_sig = 1;
|
||||
const poll_tag_overlay_timer = 2;
|
||||
|
||||
var pollfds: [3]posix.pollfd = undefined;
|
||||
var pollfds: [2]posix.pollfd = undefined;
|
||||
|
||||
pollfds[poll_wayland] = .{
|
||||
.fd = wl_display.getFd(),
|
||||
|
|
@ -116,12 +114,6 @@ fn run(wl_display: *wl.Display, context: *Context) !void {
|
|||
.events = posix.POLL.IN,
|
||||
.revents = 0,
|
||||
};
|
||||
pollfds[poll_tag_overlay_timer] = .{
|
||||
// poll ignores negative fds
|
||||
.fd = context.tag_overlay_timer_fd orelse -1,
|
||||
.events = posix.POLL.IN,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
while (true) {
|
||||
const flush_errno = wl_display.flush();
|
||||
|
|
@ -136,18 +128,38 @@ fn run(wl_display: *wl.Display, context: *Context) !void {
|
|||
pollfds[poll_wayland].events = posix.POLL.IN;
|
||||
}
|
||||
|
||||
// Get the number of milliseconds to the top of the next second
|
||||
const time_ns = std.time.nanoTimestamp();
|
||||
const ns_per_sec = std.time.ns_per_s;
|
||||
const remainder_ns = @mod(time_ns, ns_per_sec);
|
||||
const timeout: i32 = @intCast(@divFloor(ns_per_sec - remainder_ns, std.time.ns_per_ms));
|
||||
// Compute poll timeout: minimum of clock update and tag overlay expiry
|
||||
var timeout: i32 = blk: {
|
||||
// Milliseconds until the top of the next second (for clock updates)
|
||||
const time_ns = time.nanoTimestamp();
|
||||
const remainder_ns = @mod(time_ns, time.ns_per_s);
|
||||
break :blk @intCast(@divFloor(time.ns_per_s - remainder_ns, time.ns_per_ms));
|
||||
};
|
||||
|
||||
// Check for expired tag overlays and find the soonest expiry
|
||||
const now = time.Instant.now() catch
|
||||
fatal("System does not support a monotonic or steady clock", .{});
|
||||
{
|
||||
var it = context.wm.outputs.iterator(.forward);
|
||||
while (it.next()) |output| {
|
||||
const tag_overlay = output.tag_overlay orelse continue;
|
||||
const last_shown = tag_overlay.last_shown orelse continue;
|
||||
const elapsed_ns = now.since(last_shown);
|
||||
const timeout_ns: u64 = @as(u64, tag_overlay.options.timeout) * time.ns_per_ms;
|
||||
if (elapsed_ns >= timeout_ns) {
|
||||
output.tag_overlay.?.deinitSurfaces();
|
||||
} else {
|
||||
const remaining_ms: i32 = @intCast((timeout_ns - elapsed_ns) / time.ns_per_ms);
|
||||
timeout = @min(timeout, remaining_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const poll_rc = posix.poll(&pollfds, timeout) catch |err| {
|
||||
fatal("Failed to poll {s}", .{@errorName(err)});
|
||||
};
|
||||
if (poll_rc == 0) {
|
||||
// If poll returns 0, it timed out, meaning we hit the top of the next second
|
||||
// and need to update the clock.
|
||||
// Update the clock
|
||||
var it = context.wm.outputs.iterator(.forward);
|
||||
while (it.next()) |output| {
|
||||
if (output.bar) |*bar| {
|
||||
|
|
@ -168,8 +180,6 @@ fn run(wl_display: *wl.Display, context: *Context) !void {
|
|||
@branchHint(.cold);
|
||||
fatal("Wayland display dispatch failed", .{});
|
||||
}
|
||||
// Re-sync in case a config reload created or destroyed the timerfd
|
||||
pollfds[poll_tag_overlay_timer].fd = context.tag_overlay_timer_fd orelse -1;
|
||||
}
|
||||
|
||||
if (pollfds[poll_sig].revents & posix.POLL.HUP != 0) {
|
||||
|
|
@ -181,24 +191,6 @@ fn run(wl_display: *wl.Display, context: *Context) !void {
|
|||
log.info("Exiting beansprout", .{});
|
||||
break;
|
||||
}
|
||||
|
||||
if (pollfds[poll_tag_overlay_timer].revents & posix.POLL.HUP != 0) {
|
||||
@branchHint(.cold);
|
||||
fatal("Tag overlay timer fd hung up", .{});
|
||||
}
|
||||
if (pollfds[poll_tag_overlay_timer].revents & posix.POLL.IN != 0) {
|
||||
// Read to consume the timer event
|
||||
var buf: [8]u8 = undefined;
|
||||
_ = posix.read(context.tag_overlay_timer_fd.?, &buf) catch {};
|
||||
|
||||
// Hide all tag overlays by destroying their surfaces
|
||||
var it = context.wm.outputs.iterator(.forward);
|
||||
while (it.next()) |output| {
|
||||
if (output.tag_overlay) |*tag_overlay| {
|
||||
tag_overlay.deinitSurfaces();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,6 +330,7 @@ const mem = std.mem;
|
|||
const os = std.os;
|
||||
const posix = std.posix;
|
||||
const process = std.process;
|
||||
const time = std.time;
|
||||
|
||||
const wayland = @import("wayland");
|
||||
const river = wayland.client.river;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue