Implement wallpaper rendering with multi-output support

This actually renders a wallpaper for each output using the newly added
Buffer and BufferPool for shared-memory surfaces and creates a
wlr-layer-shell surface per output. Right now, each wallpaper
shares the same wallpaper (though scaled to each).

wl_output globals get added to a HashMap that is used by Output when it
gets an output event.

Fix null-safety in WindowManager when no seats/outputs exist and route
Window dimensions through pending_manage.
This commit is contained in:
Ben Buhse 2026-02-07 17:27:24 -06:00
commit e186a2d017
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4
9 changed files with 568 additions and 35 deletions

View file

@ -179,9 +179,11 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv
const output = Output.create(context, ev.id) catch @panic("Out of memory");
wm.outputs.append(output);
// If there was already a seat, but no outputs, set this new output as focused
const seat = wm.seats.first() orelse return;
if (seat.focused_output == null and seat.pending_manage.output == null) {
seat.pending_manage.output = .{ .output = output };
const first_seat = wm.seats.first();
if (first_seat) |seat| {
if (seat.focused_output == null and seat.pending_manage.output == null) {
seat.pending_manage.output = .{ .output = output };
}
}
// If there are orphan windows, send them to the new output
@ -210,7 +212,9 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv
wm.seats.append(seat);
// If there was already an output, but no seats, set the first output as focused
seat.pending_manage.output = .{ .output = wm.outputs.first() orelse return };
if (wm.outputs.first()) |output| {
seat.pending_manage.output = .{ .output = output };
}
},
.window => |ev| {
// TODO: Support multiple seats