From 8a97277f206db5ddbe6b287de19f5c6169693600 Mon Sep 17 00:00:00 2001 From: iris Date: Sun, 31 May 2026 22:19:26 +0200 Subject: [PATCH] fix(#540): pin weston socket + inject WAYLAND_DISPLAY globally Services started by systemd in a gui-enabled container didn't have WAYLAND_DISPLAY set, so Wayland clients couldn't find the compositor. libwayland would fall back to a headless display or error out, leaving apps running invisibly while the VNC session showed a blank weston desktop (the double-screen problem). Fix in weston-vnc.nix: - Pass --socket=wayland-0 to weston so the socket name is deterministic (weston normally picks any free wayland-N name). - Set WAYLAND_DISPLAY=wayland-0 and XDG_RUNTIME_DIR=/run/user/0 as global environment.variables gated on hyperhive.gui.enable, so every service in the container inherits them automatically. - Update gui.json to include wayland_display for tooling that reads it. Update docs/gotchas.md with the rationale and pointer to #540. --- docs/gotchas.md | 14 ++++++++++++-- nix/templates/weston-vnc.nix | 29 +++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/gotchas.md b/docs/gotchas.md index 8fa69869..22c2a766 100644 --- a/docs/gotchas.md +++ b/docs/gotchas.md @@ -264,9 +264,19 @@ connects to the compositor at `127.0.0.1:`. `[15900, 16799]`. Mirrors the agent web-UI port pattern from `docs/gotchas.md::Web UI ports collide on hash` — same FNV-1a constant, different range. The compositor's startup script writes - `/etc/hyperhive/gui.json = {"vnc_port":N,"auth":"none"}` so the - harness reads the port at runtime; no nix-side / harness-side hash + `/etc/hyperhive/gui.json = {"vnc_port":N,"auth":"none","wayland_display":"wayland-0"}` + so the harness reads the port at runtime; no nix-side / harness-side hash duplication. +- **Fixed Wayland socket name (`--socket=wayland-0`)**: weston is + launched with `--socket=wayland-0` so the socket path is + deterministic. `harness-base.nix` exports `WAYLAND_DISPLAY=wayland-0` + and `XDG_RUNTIME_DIR=/run/user/0` as global system environment + variables (gated on `hyperhive.gui.enable`) so every systemd service + in the container inherits them. Without this, services starting + Wayland clients could not find the compositor — libwayland falls + back to a headless display or errors out, the app "works" on a + second invisible display, and the VNC session shows a blank weston + desktop (#540 double-screen). - **VNC bind address**: weston's VNC backend has no CLI bind-address flag (unlike the RDP backend's `--address`), so the listener binds `0.0.0.0`. The harness relay only connects via diff --git a/nix/templates/weston-vnc.nix b/nix/templates/weston-vnc.nix index 11f90308..1102ef1d 100644 --- a/nix/templates/weston-vnc.nix +++ b/nix/templates/weston-vnc.nix @@ -78,9 +78,11 @@ done VNC_PORT=$((15900 + hash % 900)) - # Marker file the harness reads at startup. + # Marker file the harness reads at startup. Also records the + # fixed Wayland socket name (`wayland-0`) so other tooling can + # read it without inspecting the env-var injection below. ${pkgs.coreutils}/bin/mkdir -p /etc/hyperhive - ${pkgs.coreutils}/bin/printf '{"vnc_port":%d,"auth":"none"}\n' \ + ${pkgs.coreutils}/bin/printf '{"vnc_port":%d,"auth":"none","wayland_display":"wayland-0"}\n' \ "$VNC_PORT" > /etc/hyperhive/gui.json || true # --disable-transport-layer-security: skips the VeNCrypt TLS @@ -90,11 +92,21 @@ WESTON_INI=$(${pkgs.coreutils}/bin/mktemp /tmp/weston-XXXXXX.ini) ${pkgs.coreutils}/bin/printf '[core]\nidle-time=0\n\n[vnc]\nauth-method=none\n' > "$WESTON_INI" + # --socket=wayland-0: pin the compositor's Wayland socket name + # to `wayland-0` (weston default is to pick any free name such + # as `wayland-1`). Pinning lets the WAYLAND_DISPLAY=wayland-0 + # global env injection below (see environment.variables) take + # effect unconditionally — any Wayland client launched by any + # systemd service in this container automatically connects to + # this compositor instead of failing or starting a second + # isolated display. Closes #540 (double-screen: VNC shows blank + # weston desktop while services render on a different seat). exec ${pkgs.weston}/bin/weston \ --config="$WESTON_INI" \ --backend=vnc-backend.so \ --renderer=pixman \ --port="$VNC_PORT" \ + --socket=wayland-0 \ --disable-transport-layer-security ''; Restart = "on-failure"; @@ -102,6 +114,19 @@ }; }; + # Expose the compositor's socket to every process in the container + # so Wayland clients started by any systemd service (e.g. bitburner + # launched via a `systemd.services.*` declaration in agent.nix) can + # find the compositor without per-service wiring. Without these vars + # a service starting a Wayland client would either fail to connect + # (libwayland falls back to creating a headless display) or open a + # second compositor entirely — both cause the VNC session to show a + # blank desktop while apps appear to "work" elsewhere (#540). + environment.variables = { + WAYLAND_DISPLAY = "wayland-0"; + XDG_RUNTIME_DIR = "/run/user/0"; + }; + # weston on the agent's interactive PATH so claude can run Wayland # clients / weston-info against the compositor. environment.systemPackages = [ pkgs.weston ];