Something went wrong. Try again.
An example of how to hack DVUI and layer shell protocol together.
Something went wrong. Try again.
3.7 kB · 95 lines
Zig
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596const Self = @This();
const std = @import("std");
const wayland = @import("wayland").client;const c = @import("backend").c;
layer_shell: ?*wayland.zwlr.LayerShellV1 = null,layer_surface: ?*wayland.zwlr.LayerSurfaceV1 = null,compositor: ?*wayland.wl.Compositor = null,window: *c.SDL_Window = undefined,layer_shell_configured: bool = false,should_close: bool = false,
pub fn init(sdl_window: *c.SDL_Window, size: struct { w: u32, h: u32 }, alloc: std.mem.Allocator) !*Self { const self = try alloc.create(Self); self.* = .{ .window = sdl_window };
const wl_display: *wayland.wl.Display = @ptrCast(c.SDL_GetPointerProperty(c.SDL_GetWindowProperties(self.window), c.SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, null)); const wl_surface_nullable: ?*wayland.wl.Surface = @ptrCast(c.SDL_GetPointerProperty(c.SDL_GetWindowProperties(self.window), c.SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, null));
if (wl_surface_nullable == null) { return error.WlSurfaceNull; } const wl_surface = wl_surface_nullable.?;
const wl_queue = try wayland.wl.Display.createQueue(wl_display); const wl_registry = try wayland.wl.Display.getRegistry(wl_display); wayland.wl.Proxy.setQueue(@ptrCast(wl_registry), wl_queue);
wl_registry.setListener(*Self, registryListener, self);
if (wl_display.roundtripQueue(wl_queue) != .SUCCESS) return error.RoundtripFailed;
self.layer_surface = try self.layer_shell.?.getLayerSurface(wl_surface, null, .top, "ray");
if (self.layer_surface) |ls| { ls.setSize(size.w, size.h); ls.setKeyboardInteractivity(.on_demand); ls.setListener(*Self, layerSurfaceListener, self); } else { return error.NoZwlrLayerShellV1Support; }
std.log.info("committing...", .{});
wl_surface.commit();
while (!self.layer_shell_configured) { if (wl_display.dispatchQueue(wl_queue) != .SUCCESS) return error.RoundtripFailed; }
return self;}
pub fn deinit(self: *Self, alloc: std.mem.Allocator) void { if (self.layer_shell) |ls| ls.destroy(); if (self.layer_surface) |ls| ls.destroy(); alloc.destroy(self);}
fn registryListener(registry: *wayland.wl.Registry, event: wayland.wl.Registry.Event, context: *Self) void { const log = std.log.scoped(.wlRegistryListener);
switch (event) { .global => |global| { log.info("received interface {s} v{d}", .{ global.interface, global.version }); if (std.mem.orderZ(u8, global.interface, wayland.wl.Compositor.interface.name) == .eq) { const version = @min(global.version, 6); context.compositor = registry.bind(global.name, wayland.wl.Compositor, version) catch return; } else if (std.mem.orderZ(u8, global.interface, wayland.zwlr.LayerShellV1.interface.name) == .eq) { const version = @min(global.version, 5); context.layer_shell = registry.bind(global.name, wayland.zwlr.LayerShellV1, version) catch return; } }, .global_remove => {}, }}
fn layerSurfaceListener(layer_surface: *wayland.zwlr.LayerSurfaceV1, event: wayland.zwlr.LayerSurfaceV1.Event, context: *Self) void { const log = std.log.scoped(.wlLayerSurfaceListener); log.info("received layer shell event", .{});
switch (event) { .closed => { context.should_close = true; }, .configure => |configure| { log.info("received layer shell configure event", .{}); layer_surface.ackConfigure(configure.serial); context.layer_shell_configured = true; _ = c.SDL_SetWindowSize(context.window, @intCast(configure.width), @intCast(configure.height)); }, }}