#!/usr/bin/env bash # Run a command inside a disposable headless Wayland desktop for capture tests. # # scripts/rig/headless-wayland.sh [args...] # # Starts a private D-Bus session with PipeWire, WirePlumber, headless Sway and # xdg-desktop-portal-wlr (auto-selecting the only output), plus a 60 FPS test # pattern standing in for a game. Everything is torn down when the command exits. # # This rig exercises the PipeWire/portal path on a machine without a display. # It does not replace validation on real hardware (Hyprland, X11, Windows). set -euo pipefail if [[ $# -eq 0 ]]; then echo "usage: $0 [args...]" >&2 exit 2 fi if [[ -z "${CLIPBIN_RIG_INNER:-}" ]]; then exec env CLIPBIN_RIG_INNER=1 dbus-run-session -- "$0" "$@" fi rig_dir="$(mktemp -d "${TMPDIR:-/tmp}/clipbin-rig.XXXXXX")" pids=() cleanup() { for pid in "${pids[@]}"; do kill "${pid}" 2>/dev/null || true; done wait 2>/dev/null || true # The D-Bus-activated document portal mounts a FUSE filesystem here. fusermount3 -u "${XDG_RUNTIME_DIR}/doc" 2>/dev/null || true rm -rf "${rig_dir}" } trap cleanup EXIT export XDG_RUNTIME_DIR="${rig_dir}/runtime" export XDG_CONFIG_HOME="${rig_dir}/config" export XDG_CURRENT_DESKTOP=sway export XDG_SESSION_TYPE=wayland mkdir -p "${XDG_RUNTIME_DIR}" "${XDG_CONFIG_HOME}/xdg-desktop-portal-wlr" "${XDG_CONFIG_HOME}/sway" chmod 700 "${XDG_RUNTIME_DIR}" width="${CLIPBIN_RIG_WIDTH:-1920}" height="${CLIPBIN_RIG_HEIGHT:-1080}" cat > "${XDG_CONFIG_HOME}/sway/config" < "${XDG_CONFIG_HOME}/xdg-desktop-portal-wlr/config" <&2 exit 1 } pipewire > "${rig_dir}/pipewire.log" 2>&1 & pids+=($!) wait_for pipewire '[[ -S "${XDG_RUNTIME_DIR}/pipewire-0" ]]' wireplumber > "${rig_dir}/wireplumber.log" 2>&1 & pids+=($!) pipewire-pulse > "${rig_dir}/pipewire-pulse.log" 2>&1 & pids+=($!) WLR_BACKENDS=headless WLR_LIBINPUT_NO_DEVICES=1 WLR_HEADLESS_OUTPUTS=1 \ sway --config "${XDG_CONFIG_HOME}/sway/config" > "${rig_dir}/sway.log" 2>&1 & pids+=($!) wait_for sway 'compgen -G "${XDG_RUNTIME_DIR}/wayland-*" > /dev/null' WAYLAND_DISPLAY="$(basename "$(compgen -G "${XDG_RUNTIME_DIR}/wayland-*" | grep -v lock | head -1)")" export WAYLAND_DISPLAY SWAYSOCK="$(compgen -G "${XDG_RUNTIME_DIR}/sway-ipc.*" | head -1)" export SWAYSOCK dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_RUNTIME_DIR XDG_CONFIG_HOME SWAYSOCK /usr/lib/xdg-desktop-portal-wlr > "${rig_dir}/xdpw.log" 2>&1 & pids+=($!) /usr/lib/xdg-desktop-portal -r > "${rig_dir}/xdp.log" 2>&1 & pids+=($!) # A moving 60 FPS picture with a tone, standing in for a game. SDL_VIDEODRIVER=wayland ffplay -loglevel error -fs -window_title clipbin-test-game \ -f lavfi "testsrc2=size=${width}x${height}:rate=60,format=yuv420p" \ > "${rig_dir}/game.log" 2>&1 & pids+=($!) sleep 1 echo "rig: ready (WAYLAND_DISPLAY=${WAYLAND_DISPLAY}, logs in ${rig_dir})" >&2 status=0 "$@" || status=$? if [[ -n "${CLIPBIN_RIG_KEEP_LOGS:-}" ]]; then cp -r "${rig_dir}" "${CLIPBIN_RIG_KEEP_LOGS}" fi exit "${status}"