diff --git a/src/Config.zig b/src/Config.zig index e7820fd..c601605 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -20,6 +20,10 @@ focus_follows_pointer: bool = true, /// Should the pointer warp to the center of newly-focused windows pointer_warp_on_focus_change: bool = true, +// TODO: Implement a color when this is null +/// Path to the wallpaper image +wallpaper_image_path: []const u8 = "", + /// Tag bind entries parsed from config (tag_bind nodes in keybinds block) tag_binds: std.ArrayList(Keybind) = .{}, keybinds: std.ArrayList(Keybind) = .{}, diff --git a/src/Context.zig b/src/Context.zig index 0a11926..9f4b20b 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -27,7 +27,7 @@ buffer_pool: BufferPool = .{}, /// Holds a pixman.Image (and its raw pixels) for the wallpaper /// (same image on all outputs, but scaled separately) -wallpaper_image: *WallpaperImage, +wallpaper_image: ?*WallpaperImage, // WM Configuration config: *Config, @@ -60,6 +60,12 @@ pub fn create(options: Options) !*Context { const context = try utils.allocator.create(Context); errdefer context.destroy(); + // FIXME: TODO: Get this from Config + const wallpaper_image = WallpaperImage.create("FIXME") catch |e| blk: { + log.err("Failed to load wallpaper image from path \"{s}\": {s}", .{ "FIXME", @errorName(e) }); + break :blk null; + }; + context.* = .{ .initialized = false, .wl_compositor = options.wl_compositor, @@ -68,7 +74,7 @@ pub fn create(options: Options) !*Context { .wl_shm = options.wl_shm, .wl_outputs = options.wl_outputs, .zwlr_layer_shell_v1 = options.zwlr_layer_shell_v1, - .wallpaper_image = try WallpaperImage.create("FIXME"), // FIXME: TODO: Get this from Config + .wallpaper_image = wallpaper_image, .wm = try WindowManager.create(context, options.river_window_manager_v1), .xkb_bindings = try XkbBindings.create(context, options.river_xkb_bindings_v1), .config = options.config, @@ -81,7 +87,9 @@ pub fn destroy(context: *Context) void { context.xkb_bindings.destroy(); context.wm.destroy(); - context.wallpaper_image.destroy(); + if (context.wallpaper_image) |wallpaper_image| { + wallpaper_image.destroy(); + } context.buffer_pool.deinit(); utils.allocator.destroy(context); diff --git a/src/Output.zig b/src/Output.zig index 4541d49..52616e6 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -208,6 +208,11 @@ fn wlOutputListener(_: *wl.Output, event: wl.Output.Event, output: *Output) void } fn initWallpaperLayerSurface(output: *Output) !void { + if (output.context.wallpaper_image == null) { + // No wallpaper image, so we don't need any surfaces + return; + } + if (output.wl_surface) |_| { log.warn("Skipping adding a second wallpaper surface to {s}", .{output.name orelse "some output"}); return; @@ -319,16 +324,17 @@ fn renderWallpaper(output: *Output) !void { if (width == 0 or height == 0 or scale == 0) { return; } - const buffer: *Buffer = try context.buffer_pool.nextBuffer(context.wl_shm, width * scale, height * scale); - // Scale our loaded image and then copy it into the Buffer's pixman.Image - const image = context.wallpaper_image.image; + const wallpaper_image = context.wallpaper_image orelse return; + const image = wallpaper_image.image; const image_data = image.getData(); const image_width = image.getWidth(); const image_height = image.getHeight(); const image_stride = image.getStride(); const image_format = image.getFormat(); + const buffer: *Buffer = try context.buffer_pool.nextBuffer(context.wl_shm, width * scale, height * scale); + const pix = pixman.Image.createBitsNoClear(image_format, image_width, image_height, image_data, image_stride); if (pix == null) { log.err("failed to copy the background image for rendering", .{}); diff --git a/src/main.zig b/src/main.zig index 55fcbf2..f373b2e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -105,6 +105,10 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: * globals.wl_shm = registry.bind(ev.name, wl.Shm, 1) catch |e| { fatal("Failed to bind to wl_shm: {any}", .{@errorName(e)}); }; + } else if (mem.orderZ(u8, ev.interface, river.LayerShellV1.interface.name) == .eq) { + globals.river_layer_shell_v1 = registry.bind(ev.name, river.LayerShellV1, 1) catch |e| { + fatal("Failed to bind to river_layer_shell_v1: {any}", .{@errorName(e)}); + }; } else if (mem.orderZ(u8, ev.interface, river.WindowManagerV1.interface.name) == .eq) { globals.river_window_manager_v1 = registry.bind(ev.name, river.WindowManagerV1, 3) catch |e| { fatal("Failed to bind to river_window_manager_v1: {any}", .{@errorName(e)});