diff --git a/src/Window.zig b/src/Window.zig index 2c4ce3a..bd58c28 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -84,12 +84,12 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, } pub fn manage(window: *Window) void { - // Use server-side decoration (no client-drawn title bars) - // TODO: Probably shouldn't send this for every manage(?) if (!window.initialized) { @branchHint(.unlikely); window.initialized = true; + // TODO: We might want to think about paying attention to the decoration_hint event + // If we do, this would need to move, I think? window.window_v1.useSsd(); window.window_v1.setCapabilities(.{ .fullscreen = true, .maximize = true }); diff --git a/src/WindowManager.zig b/src/WindowManager.zig index fe7b526..dc80c00 100644 --- a/src/WindowManager.zig +++ b/src/WindowManager.zig @@ -6,6 +6,8 @@ const WindowManager = @This(); const PRIMARY_RATIO: f32 = 0.55; +const MIN_RIVER_SEAT_V1_VERSION: u2 = 3; + context: *Context, window_manager_v1: *river.WindowManagerV1, @@ -38,6 +40,7 @@ pub fn create(context: *Context, window_manager_v1: *river.WindowManagerV1) !*Wi } pub fn destroy(wm: *WindowManager) void { + // TODO: Go through lists and destroy everything utils.allocator.destroy(wm); } @@ -200,22 +203,33 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv window_manager_v1.renderFinish(); }, .output => |ev| { - log.debug("3", .{}); + // TODO: Support multi-output var output = utils.allocator.create(Output) catch @panic("out-of-memory; exiting."); output.init(context, ev.id); wm.outputs.append(output); }, .seat => |ev| { - log.debug("4", .{}); + // TODO: Support multi-seat (maybe ?) + const river_seat_v1 = ev.id; + const river_seat_v1_version = river_seat_v1.getVersion(); + if (river_seat_v1_version < MIN_RIVER_SEAT_V1_VERSION) { + @branchHint(.cold); // If we're in here, the program is exiting anyways + utils.versionNotSupported(river.SeatV1, river_seat_v1_version, MIN_RIVER_SEAT_V1_VERSION); + } + var seat = utils.allocator.create(Seat) catch @panic("out-of-memory; exiting."); - seat.init(context, ev.id); + seat.init(context, river_seat_v1); wm.seats.append(seat); }, .window => |ev| { - log.debug("5", .{}); var window = utils.allocator.create(Window) catch @panic("out-of-memory; exiting."); window.init(context, ev.id); - wm.windows.append(window); + + // TODO: Allow appending window instead of prepending + wm.windows.prepend(window); + const seat = wm.seats.first() orelse @panic("Failed to get seat"); + seat.focused = window; + wm.window_count += 1; log.debug("window_count = {d}", .{wm.window_count}); }, diff --git a/src/XkbBindings.zig b/src/XkbBindings.zig index f7992d7..e6e29ff 100644 --- a/src/XkbBindings.zig +++ b/src/XkbBindings.zig @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025-2026 Ben Buhse +// SPDX-FileCopyrightText: 2026 Ben Buhse // // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/main.zig b/src/main.zig index af3b460..540fc2f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -33,9 +33,9 @@ pub fn main() !void { std.posix.exit(1); } - const wl_compositor = globals.wl_compositor orelse interfaceNotAdvertised(wl.Compositor); - const river_window_manager_v1 = globals.river_window_manager_v1 orelse interfaceNotAdvertised(river.WindowManagerV1); - const river_xkb_bindings_v1 = globals.river_xkb_bindings_v1 orelse interfaceNotAdvertised(river.XkbBindingsV1); + const wl_compositor = globals.wl_compositor orelse utils.interfaceNotAdvertised(wl.Compositor); + const river_window_manager_v1 = globals.river_window_manager_v1 orelse utils.interfaceNotAdvertised(river.WindowManagerV1); + const river_xkb_bindings_v1 = globals.river_xkb_bindings_v1 orelse utils.interfaceNotAdvertised(river.XkbBindingsV1); const context = try Context.create( wl_display, @@ -62,7 +62,7 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: * switch (event) { .global => |ev| { if (mem.orderZ(u8, ev.interface, wl.Compositor.interface.name) == .eq) { - if (ev.version < 4) versionNotSupported(wl.Compositor, ev.version, 4); + if (ev.version < 4) utils.versionNotSupported(wl.Compositor, ev.version, 4); globals.wl_compositor = registry.bind(ev.name, wl.Compositor, 4) catch |e| { log.err("Failed to bind to compositor: {any}", .{@errorName(e)}); std.posix.exit(1); @@ -84,17 +84,6 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: * } } -// TODO: Actually use this... -fn interfaceNotAdvertised(comptime WaylandGlobal: type) noreturn { - log.err("{s} not advertised. Exiting", .{WaylandGlobal.interface.name}); - std.posix.exit(1); -} - -fn versionNotSupported(comptime WaylandGlobal: type, have_version: u32, need_version: u32) noreturn { - log.err("The compositor only advertised {s} version {d} but version {d} is required. Exiting", .{ WaylandGlobal.interface.name, have_version, need_version }); - std.posix.exit(1); -} - const std = @import("std"); const mem = std.mem; const process = std.process; diff --git a/src/utils.zig b/src/utils.zig index 48f1d1e..cba5ff2 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -65,5 +65,19 @@ fn parseRgbaHelper(bytes: [4]u8) RiverColor { }; } +/// Report that the given WaylandGlobal wasn't advertised and exit the program +pub fn interfaceNotAdvertised(comptime WaylandGlobal: type) noreturn { + log.err("{s} not advertised. Exiting", .{WaylandGlobal.interface.name}); + std.posix.exit(1); +} + +/// Report that the given WaylandGlobal was advertised but the support version was too low exit the program +pub fn versionNotSupported(comptime WaylandGlobal: type, have_version: u32, need_version: u32) noreturn { + log.err("The compositor only advertised {s} version {d} but version {d} is required. Exiting", .{ WaylandGlobal.interface.name, have_version, need_version }); + std.posix.exit(1); +} + const std = @import("std"); const fmt = std.fmt; + +const log = std.log.scoped(.utils);