a73x

729572fe

Simplify applyToplevelStates signature and expand test coverage

a73x   2026-04-16 10:56

Commit message
Simplify applyToplevelStates signature and expand test coverage

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.

src/wayland.zig
Old New
@@ -1078,11 +1078,7 @@ fn surfaceListener(_: *wl.Surface, event: wl.Surface.Event, window: *Window) voi
1078 } 1078 }
1079 } 1079 }
1080 1080
1081 fn applyToplevelStates(state: *SurfaceState, state_bytes: []const u8) void { 1081 fn applyToplevelStates(state: *SurfaceState, states: []const u32) void {
1082 // xdg_toplevel.configure delivers the state array as a wl_array of u32.
1083 // Re-interpret to u32 slice and scan for `.suspended`.
1084 const u32_count = state_bytes.len / @sizeOf(u32);
1085 const states = std.mem.bytesAsSlice(u32, state_bytes[0 .. u32_count * @sizeOf(u32)]);
1086 var suspended = false; 1082 var suspended = false;
1087 for (states) |raw| { 1083 for (states) |raw| {
1088 if (raw == @intFromEnum(xdg.Toplevel.State.suspended)) { 1084 if (raw == @intFromEnum(xdg.Toplevel.State.suspended)) {
@@ -1098,7 +1094,7 @@ fn xdgToplevelListener(_: *xdg.Toplevel, event: xdg.Toplevel.Event, window: *Win
1098 .configure => |cfg| { 1094 .configure => |cfg| {
1099 if (cfg.width > 0) window.width = @intCast(cfg.width); 1095 if (cfg.width > 0) window.width = @intCast(cfg.width);
1100 if (cfg.height > 0) window.height = @intCast(cfg.height); 1096 if (cfg.height > 0) window.height = @intCast(cfg.height);
1101 applyToplevelStates(&window.state, std.mem.sliceAsBytes(cfg.states.slice(u32))); 1097 applyToplevelStates(&window.state, cfg.states.slice(u32));
1102 }, 1098 },
1103 .close => window.should_close = true, 1099 .close => window.should_close = true,
1104 .configure_bounds => {}, 1100 .configure_bounds => {},
@@ -1285,12 +1281,35 @@ test "SurfaceState.suspended toggles from xdg_toplevel.configure.states" {
1285 1281
1286 // Helper function under test — applies xdg_toplevel state array to SurfaceState. 1282 // Helper function under test — applies xdg_toplevel state array to SurfaceState.
1287 const states_suspended = [_]u32{@intFromEnum(xdg.Toplevel.State.suspended)}; 1283 const states_suspended = [_]u32{@intFromEnum(xdg.Toplevel.State.suspended)};
1288 applyToplevelStates(&state, std.mem.sliceAsBytes(&states_suspended)); 1284 applyToplevelStates(&state, &states_suspended);
1289 try std.testing.expect(state.suspended); 1285 try std.testing.expect(state.suspended);
1290 try std.testing.expect(!state.visible()); 1286 try std.testing.expect(!state.visible());
1291 1287
1292 const states_none = [_]u32{}; 1288 const states_none = [_]u32{};
1293 applyToplevelStates(&state, std.mem.sliceAsBytes(&states_none)); 1289 applyToplevelStates(&state, &states_none);
1294 try std.testing.expect(!state.suspended); 1290 try std.testing.expect(!state.suspended);
1295 try std.testing.expect(state.visible()); 1291 try std.testing.expect(state.visible());
1296 } 1292 }
1293
1294 test "SurfaceState.suspended stays false when states contain activated without suspended" {
1295 var tracker = ScaleTracker.init(std.testing.allocator);
1296 defer tracker.deinit();
1297 try tracker.addOutput(1);
1298 try tracker.enterOutput(1);
1299
1300 var state = SurfaceState{ .tracker = &tracker, .configured = true };
1301
1302 const states_activated = [_]u32{@intFromEnum(xdg.Toplevel.State.activated)};
1303 applyToplevelStates(&state, &states_activated);
1304 try std.testing.expect(!state.suspended);
1305 try std.testing.expect(state.visible());
1306
1307 // Multi-state array containing suspended along with others still flips the flag.
1308 const states_multi = [_]u32{
1309 @intFromEnum(xdg.Toplevel.State.activated),
1310 @intFromEnum(xdg.Toplevel.State.suspended),
1311 };
1312 applyToplevelStates(&state, &states_multi);
1313 try std.testing.expect(state.suspended);
1314 try std.testing.expect(!state.visible());
1315 }