729572fe
Simplify applyToplevelStates signature and expand test coverage
a73x 2026-04-16 10:56
Takes []const u32 directly instead of bytes + bytesAsSlice round-trip; both callers already had u32 slices. Adds a test for multi-state arrays that include .activated alongside .suspended, and for arrays that only contain .activated (should leave suspended unset). Follow-up to aba5051 per code-quality review.
diff --git a/src/wayland.zig b/src/wayland.zig index 4b2680e..b77f540 100644 --- a/src/wayland.zig +++ b/src/wayland.zig @@ -1078,11 +1078,7 @@ fn surfaceListener(_: *wl.Surface, event: wl.Surface.Event, window: *Window) voi } } fn applyToplevelStates(state: *SurfaceState, state_bytes: []const u8) void { // xdg_toplevel.configure delivers the state array as a wl_array of u32. // Re-interpret to u32 slice and scan for `.suspended`. const u32_count = state_bytes.len / @sizeOf(u32); const states = std.mem.bytesAsSlice(u32, state_bytes[0 .. u32_count * @sizeOf(u32)]); fn applyToplevelStates(state: *SurfaceState, states: []const u32) void { var suspended = false; for (states) |raw| { if (raw == @intFromEnum(xdg.Toplevel.State.suspended)) { @@ -1098,7 +1094,7 @@ fn xdgToplevelListener(_: *xdg.Toplevel, event: xdg.Toplevel.Event, window: *Win .configure => |cfg| { if (cfg.width > 0) window.width = @intCast(cfg.width); if (cfg.height > 0) window.height = @intCast(cfg.height); applyToplevelStates(&window.state, std.mem.sliceAsBytes(cfg.states.slice(u32))); applyToplevelStates(&window.state, cfg.states.slice(u32)); }, .close => window.should_close = true, .configure_bounds => {}, @@ -1285,12 +1281,35 @@ test "SurfaceState.suspended toggles from xdg_toplevel.configure.states" { // Helper function under test — applies xdg_toplevel state array to SurfaceState. const states_suspended = [_]u32{@intFromEnum(xdg.Toplevel.State.suspended)}; applyToplevelStates(&state, std.mem.sliceAsBytes(&states_suspended)); applyToplevelStates(&state, &states_suspended); try std.testing.expect(state.suspended); try std.testing.expect(!state.visible()); const states_none = [_]u32{}; applyToplevelStates(&state, std.mem.sliceAsBytes(&states_none)); applyToplevelStates(&state, &states_none); try std.testing.expect(!state.suspended); try std.testing.expect(state.visible()); } test "SurfaceState.suspended stays false when states contain activated without suspended" { var tracker = ScaleTracker.init(std.testing.allocator); defer tracker.deinit(); try tracker.addOutput(1); try tracker.enterOutput(1); var state = SurfaceState{ .tracker = &tracker, .configured = true }; const states_activated = [_]u32{@intFromEnum(xdg.Toplevel.State.activated)}; applyToplevelStates(&state, &states_activated); try std.testing.expect(!state.suspended); try std.testing.expect(state.visible()); // Multi-state array containing suspended along with others still flips the flag. const states_multi = [_]u32{ @intFromEnum(xdg.Toplevel.State.activated), @intFromEnum(xdg.Toplevel.State.suspended), }; applyToplevelStates(&state, &states_multi); try std.testing.expect(state.suspended); try std.testing.expect(!state.visible()); }