Fix Output.prevWindow/nextWindow

Before, they were ignoring tags, so you could cycle to windows on
other tags instead of only the same tag.
This commit is contained in:
Ben Buhse 2026-02-08 15:49:05 -06:00
commit 54421ef8f5
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4

View file

@ -87,20 +87,35 @@ pub fn destroy(output: *Output) void {
utils.allocator.destroy(output); utils.allocator.destroy(output);
} }
/// Get the next window in the list, wrapping to first if at end /// Get the next window in the list that shares at least one tag
/// with the output, wrapping to first if at end.
pub fn nextWindow(output: *Output, current: *Window) ?*Window { pub fn nextWindow(output: *Output, current: *Window) ?*Window {
const next_link = current.link.next orelse return output.windows.first(); var link = current.link.next orelse unreachable;
// If we've reached the sentinel (head's link), wrap to first // Walk forward, wrapping at sentinel, until we find a visible window or return to current
if (next_link == &output.windows.link) return output.windows.first(); while (true) {
return @fieldParentPtr("link", next_link); // If this is the sentinel, wrap to the beginning
if (link == &output.windows.link) {
link = link.next orelse unreachable;
}
const window: *Window = @fieldParentPtr("link", link);
if (window.tags & output.tags != 0 or window == current) return window;
link = link.next orelse unreachable;
}
} }
/// Get the previous window in the list, wrapping to last if at beginning /// Get the previous window in the list that shares at least one tag
/// with the output, wrapping to the last if at beginning
pub fn prevWindow(output: *Output, current: *Window) ?*Window { pub fn prevWindow(output: *Output, current: *Window) ?*Window {
const prev_link = current.link.prev orelse return output.windows.last(); var link = current.link.prev orelse unreachable;
// If we've reached the sentinel (head's link), wrap to last while (true) {
if (prev_link == &output.windows.link) return output.windows.last(); // If this is the sentinel, wrap to the end
return @fieldParentPtr("link", prev_link); if (link == &output.windows.link) {
link = link.prev orelse unreachable;
}
const window: *Window = @fieldParentPtr("link", link);
if (window.tags & output.tags != 0 or window == current) return window;
link = link.prev orelse unreachable;
}
} }
// Used for the river_output_v1 interface // Used for the river_output_v1 interface