ov-selkies/skills/sway/SKILL.md
Sway Wayland compositor running headless inside containers with Mesa GPU drivers. Use when working with Sway, Wayland desktop, or headless compositor setup.
npx skillsauth add overthinkos/overthink-plugins swayInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Property | Value |
|----------|-------|
| Dependencies | dbus |
| Service | sway (supervisord, priority 10) |
| Install files | tasks:, config, sway-wrapper |
| Variable | Value |
|----------|-------|
| WLR_BACKENDS | headless (supervisord env) |
| WLR_HEADLESS_OUTPUTS | 1 |
| WLR_LIBINPUT_NO_DEVICES | 1 |
| XDG_RUNTIME_DIR | /tmp |
| WAYLAND_DISPLAY | wayland-0 |
| EGL_LOG_LEVEL | fatal |
| XKB_DEFAULT_LAYOUT | us |
Keyboard layout defaults to US. Override with env_accepts vars:
| Variable | Default | Purpose |
|----------|---------|---------|
| XKB_DEFAULT_LAYOUT | us | Keyboard layout (us, de, fr, gb, etc.) |
| XKB_DEFAULT_VARIANT | (empty) | Layout variant (dvorak, nodeadkeys, etc.) |
ov config sway-desktop -e XKB_DEFAULT_LAYOUT=de
Sway reads XKB_DEFAULT_LAYOUT natively from the environment — no wrapper change needed. See /ov-selkies:labwc for full XKB var list (MODEL, OPTIONS).
The supervisord [program:sway] environment sets WLR_BACKENDS=headless — headless output only. The libinput backend is not included by default because it requires a libseat session which fails in rootless containers.
sway, fuzzel (RPM)mesa-dri-drivers, mesa-vulkan-drivers (RPM)libglvnd-egl, libglvnd-gles, egl-wayland (RPM)wlr-randr (RPM)# image.yml -- typically not used directly; pulled in via chrome-sway
my-desktop:
layers:
- sway
XWayland is enabled by default (xwayland enable in the base config). The xorg-x11-server-Xwayland package is included in the sway layer. XWayland starts lazily — the Xwayland process only launches when the first X11 client connects (e.g., Steam, Heroic, Qt apps with xcb platform).
X11 tools for interacting with XWayland windows (xdotool, xprop, xwininfo, import) are provided by the /ov-selkies:wl-tools layer.
Supervisord restarts leave old /tmp/sway-ipc.1000.<old-pid>.sock files. If multiple sockets exist, naive discovery (ls /tmp/sway-ipc.*.sock | head -1) picks alphabetically -- which selects the smallest PID (oldest = stale socket), causing ov eval wl sway commands to fail silently.
Fix: sway-wrapper cleans old sockets before starting Sway. Both sway-wrapper and ov eval wl sway (sway.go) use ls -t | head -1 (newest modification time first) when discovering the active socket.
Symptoms of stale socket: ov eval wl sway commands fail, resolution stays at 1280x720 (wlr-randr resize fails), Chrome renders at wrong size.
By default, sway-wrapper auto-detects GPU hardware and uses gles2 on NVIDIA. However, if WLR_RENDERER is pre-set (e.g., by a composing layer), the wrapper skips GPU auto-detection entirely and uses the specified renderer.
sway-desktop-vnc) override to pixman (software rendering) — ensures reliable VNC screenshot capture on NVIDIA headlessgles2 via auto-detection — Chrome gets full GPU accelerationgrim (ov eval wl screenshot) works with both renderersTransitive dependency via chrome-sway and sway-desktop in all desktop images.
/ov-foundation:dbus -- D-Bus session bus dependency/ov-selkies:chrome-sway -- Chrome on Sway (depends on sway)/ov-selkies:sway-desktop -- full desktop composition (VNC)/ov-selkies:wayvnc -- VNC access to Sway display/ov-selkies:waybar -- status bar (depends on sway)/ov-advanced:wl — Wayland desktop automation (screenshot, input, windows, clipboard, AT-SPI2)Use when the user asks about:
WLR_BACKENDS or Wayland environment variables/ov-build:layer — layer authoring reference (layer.yml schema, task verbs, service declarations)/ov-build:eval — declarative testing (eval: block, ov eval image, ov eval live)tools
Use when authoring or modifying a charly PLUGIN — a candy with a `plugin:` block that contributes Providers (verbs/kinds/deploy-targets/steps/builders/commands), its own CUE schema, builtin (compiled-in) or external (out-of-tree git repo). Covers the unified Provider model, the per-plugin CUE-schema contract (single source → Go params for dev + schema-over-Describe RPC for runtime), the SDK, and the loader.
tools
The CUE data-validation / configuration CLI (cue), pinned to v0.16.1. Use when working with the cue candy, installing the cue binary into a box or onto a target:local dev host, or running the offline schema-vendoring pipeline that feeds charly's egress validation.
tools
CUE EGRESS validation — validating (and, where it adds value, generating) the config files charly WRITES to a system BEFORE the bytes hit disk. MUST be invoked before working on charly/egress.go, the vendored schemas under candy/plugin-egress/egress-schemas/vendor/, the ValidateEgress / registerVendoredEgressKind path, the offline `task cue:vendor` pipeline, or adding an egress schema for any written artifact (cloud-init, k8s manifests, traefik routes, runtime config, install ledger, systemd/quadlet units, ssh_config, libvirt XML).
tools
Kubernetes cluster-probe declarative check verb — the `kube:` check verb (nodes, pods, ingress, storage class, addon health, apply/delete, and arbitrary resource GETs) served out-of-process by the candy/plugin-kube plugin (vendored client-go; no external kubectl required).