# Themed-desktop capture harness (item 28 slice c) — boots the full # desktop headlessly (software-GL Hyprland) at 1920x1080 and QMP-dumps # two screenshots into $out: desktop.png and menu.png (rofi root open). # Maintainer tool, NOT a checks.* gate (a full-desktop VM is far too # heavy for CI). Impure: THEME env picks the theme slug. # THEME= nix build --impure -f tools/theme-shot.nix --no-link --print-out-paths # Known gap: the wallpaper does not paint — nomarchy-theme-sync resolves # state from ~/.nomarchy at runtime, absent in the guest; seed it # (cp the flake to ~nomarchy/.nomarchy in testScript) if the wallpaper # matters to the shot. Bar + menus render fully. let flake = builtins.getFlake ("git+file://" + toString ../.); inherit (flake.inputs) nixpkgs home-manager; pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ flake.overlays.default ]; config.allowUnfree = true; }; slug = let s = builtins.getEnv "THEME"; in if s == "" then "tokyo-night" else s; in pkgs.testers.runNixOSTest { name = "theme-shot-${slug}"; node.pkgsReadOnly = false; # nomarchy sets nixpkgs.config node.specialArgs = { username = "nomarchy"; }; nodes.machine = { pkgs, lib, ... }: { imports = [ flake.nixosModules.nomarchy home-manager.nixosModules.home-manager ]; virtualisation.memorySize = 4096; virtualisation.cores = 4; # Software GL for Hyprland (GLES/aquamarine) without a host GPU. hardware.graphics.enable = true; environment.variables.LIBGL_ALWAYS_SOFTWARE = "1"; boot.initrd.availableKernelModules = [ "virtio_gpu" ]; virtualisation.qemu.options = [ "-vga none" "-device virtio-gpu-pci,xres=1920,yres=1080" ]; users.users.nomarchy = { isNormalUser = true; password = "test"; extraGroups = [ "wheel" "video" ]; }; nomarchy.system.stateFile = flake + "/themes/${slug}.json"; services.greetd.settings.initial_session = { command = "start-hyprland"; user = "nomarchy"; }; home-manager.useGlobalPkgs = true; # HM must see the overlay'd node pkgs home-manager.users.nomarchy = { imports = [ flake.homeModules.nomarchy ]; nomarchy.stateFile = flake + "/themes/${slug}.json"; nomarchy.idle.enable = false; # no lock/dpms during the shot }; }; testScript = '' machine.wait_for_unit("multi-user.target") machine.wait_for_file("/run/user/1000/hypr", 180) machine.sleep(12) # Paint the wallpaper explicitly (awww timing was flaky in the spike). machine.execute("su - nomarchy -c 'XDG_RUNTIME_DIR=/run/user/1000 nomarchy-theme-sync wallpaper' >/dev/null 2>&1") machine.sleep(18) machine.screenshot("desktop") # Open the root menu for the polish review. hy = "su - nomarchy -c 'XDG_RUNTIME_DIR=/run/user/1000 HYPRLAND_INSTANCE_SIGNATURE=$(ls /run/user/1000/hypr | head -1) hyprctl dispatch exec" machine.execute(hy + " nomarchy-menu' >/dev/null 2>&1") machine.sleep(8) machine.screenshot("menu") ''; }