const std = @import("std"); const mem = std.mem; const posix = std.posix; const wayland = @import("wayland"); const wl = wayland.client.wl; const zwlr = wayland.client.zwlr; const layer_shell = zwlr.common.zwlr.layer_shell_v1; const Context = struct { shm: ?*wl.Shm = null, shell: *zwlr.LayerShellV1 = undefined, surface: *wl.Surface = undefined, layer_surface: *zwlr.LayerSurfaceV1 = undefined, buffer: ?*wl.Buffer = null, compositor: *wl.Compositor = undefined, blk: []u32 = undefined, width: i32 = 0, height: i32 = 0, }; pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const display = try wl.Display.connect(null); defer display.disconnect(); const registry = try display.getRegistry(); defer registry.destroy(); var context = Context{}; registry.setListener(*Context, registryListener, &context); if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed; context.surface = try context.compositor.createSurface(); defer context.surface.destroy(); context.layer_surface = try context.shell.getLayerSurface(context.surface, null, .top, "zayneko"); defer context.layer_surface.destroy(); context.layer_surface.setExclusiveZone(20); context.layer_surface.setAnchor(.{ .top = true, .bottom = false, .left = true, .right = true, }); context.layer_surface.setSize(0, 20); context.layer_surface.setListener(*Context, layerSurfaceListener, &context); context.surface.commit(); if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed; std.debug.print("{}\n", .{context.blk.len}); for (context.blk) |*a| // a.* = if (i < 2000) 0 else 0xFFFFFFFF; a.* = 0xFFFFFFFF; context.surface.attach(context.buffer, 0, 0); context.surface.damageBuffer(0, 0, context.width, context.height); context.surface.commit(); _ = display.flush(); if (display.dispatchPending() != .SUCCESS) return error.DispatchFailed; std.time.sleep(4000000000); } fn registryListener( registry: *wl.Registry, event: wl.Registry.Event, context: *Context, ) void { switch (event) { .global => |global| { if (mem.orderZ(u8, global.interface, wl.Shm.interface.name) == .eq) { context.shm = registry.bind(global.name, wl.Shm, 1) catch return; } else if (mem.orderZ(u8, global.interface, zwlr.LayerShellV1.interface.name) == .eq) { context.shell = registry.bind(global.name, zwlr.LayerShellV1, 4) catch return; } else if (mem.orderZ(u8, global.interface, wl.Compositor.interface.name) == .eq) { context.compositor = registry.bind(global.name, wl.Compositor, 5) catch return; } }, .global_remove => {}, } } fn layerSurfaceListener( surface: *zwlr.LayerSurfaceV1, event: zwlr.LayerSurfaceV1.Event, context: *Context, ) void { switch (event) { .configure => |configure| { surface.ackConfigure(configure.serial); context.buffer = blk: { const width: i32 = @intCast((configure.width)); const height: i32 = @intCast((configure.height)); context.width = width; context.height = height; const stride: i32 = width * 4; const size: i32 = stride * height; const sizeu = configure.width * configure.height * 4; const fd = posix.memfd_create("zayneko", 0) catch return; posix.ftruncate(fd, sizeu) catch return; const tmp align(@alignOf(u32)) = posix.mmap(null, sizeu, posix.PROT.READ | posix.PROT.WRITE, .{ .TYPE = .SHARED }, fd, 0) catch return; context.blk = mem.bytesAsSlice(u32, tmp); const pool = context.shm.?.createPool(fd, size) catch return; defer pool.destroy(); break :blk pool.createBuffer(0, width, height, stride, .argb8888) catch null; }; context.surface.attach(context.buffer, 0, 0); context.surface.commit(); }, .closed => {}, } }