labwc
Recipe card from the charly-selkies plugin (Images — the deployable catalog).
labwc – Nested Wayland compositor for Selkies desktop
Section titled “labwc – Nested Wayland compositor for Selkies desktop”Lightweight Wayland compositor (wlroots-based) for use as a nested desktop inside pixelflux’s Wayland capture compositor.
Architecture
Section titled “Architecture”labwc runs as a nested compositor inside pixelflux’s wayland-1 display. It creates its own wayland-0 socket for desktop applications (Chrome, Waybar, foot, thunar). This is the same approach used by the LinuxServer.io Selkies base image.
- labwc connects to
wayland-1(pixelflux) viaWAYLAND_DISPLAY=wayland-1in the labwc-wrapper - labwc creates
wayland-0for its clients - The global env
WAYLAND_DISPLAY=wayland-0ensures apps connect to labwc, not pixelflux
Dependencies
Section titled “Dependencies”dbus
Packages
Section titled “Packages”labwc— Wayland compositorfoot— Terminal emulatorxorg-x11-server-Xwayland— X11 compatibilitythunar— File manager
Environment
Section titled “Environment”| Variable | Value | Purpose |
|---|---|---|
WAYLAND_DISPLAY |
wayland-0 |
labwc’s client socket (global default for apps) |
XDG_RUNTIME_DIR |
/tmp |
Runtime directory |
Keyboard Configuration
Section titled “Keyboard Configuration”labwc-wrapper exports all XKB environment variables with defaults, making keyboard layout configurable at deploy time:
| Variable | Default | Purpose |
|---|---|---|
XKB_DEFAULT_LAYOUT |
us |
Keyboard layout (us, de, fr, gb, es, no, etc.) |
XKB_DEFAULT_VARIANT |
(empty) | Layout variant (dvorak, nodeadkeys, etc.) |
XKB_DEFAULT_MODEL |
pc105 |
Keyboard model (pc105, pc104, chromebook) |
XKB_DEFAULT_OPTIONS |
(empty) | XKB options (compose:ralt, caps:escape) |
XKB_DEFAULT_RULES |
evdev |
XKB rules (always evdev, not configurable) |
All except RULES are declared as env_accept — override via charly config -e:
# German QWERTZ layoutcharly config selkies-desktop -e XKB_DEFAULT_LAYOUT=de
# French AZERTY with no dead keyscharly config selkies-desktop -e XKB_DEFAULT_LAYOUT=fr -e XKB_DEFAULT_VARIANT=nodeadkeysThe compositor and selkies input handler both read XKB_DEFAULT_LAYOUT from the environment, ensuring the scancode map matches the compositor’s layout. See /charly-selkies:selkies for the keyboard input pipeline details.
Service (supervisord)
Section titled “Service (supervisord)”| Service | Priority | Purpose |
|---|---|---|
labwc |
12 | Desktop compositor (after selkies at priority 8) |
Key Files
Section titled “Key Files”labwc-wrapper— Waits for pixelflux’swayland-1socket, exports XKB_DEFAULT_* from env with defaults, then starts labwcrc.xml— labwc configuration: server-side decorations, maximize-all window rule, keyboard shortcuts (Alt+F4 close, Super+E terminal)autostart— Does NOT launch Chrome. Chrome is launched + supervised by the[program:chrome]service in the selkies-core candy (shared by both selkies flavors). CDP: internal 9223, external 9222 via cdp-proxy.
Chrome ownership (selkies-core, not labwc)
Section titled “Chrome ownership (selkies-core, not labwc)”Chrome is owned by a supervised [program:chrome] service declared in the
selkies-core candy (candy/selkies-core/charly.yml service: block) — NOT by the
labwc candy and NOT by labwc’s autostart. Both selkies flavors (labwc via
selkies-desktop, KDE Plasma via selkies-kde-desktop) compose selkies-core and get the
same supervised browser. The per-flavor compositor autostart (labwc’s autostart,
KDE’s kde-selkies-session) does not start Chrome.
The supervised service uses:
restart: always→autorestart=true. The selkies flavors nest the compositor inside pixelflux’swayland-1; a Chrome started during the nested compositor’s startup-race self-exits once (clean exit 0, the window-less browser’s sole window going away on the early color-manager re-init).autorestart=truerelaunches it post-settle, where it stays up indefinitely.autostart=true(default) and self-synchronizing:chrome-wrapperitself polls for thewayland-0client socket (created by the nested compositor), so no per-flavor handoff is needed.start_secs: 5+start_retries: 3: the single startup-race self-exit runs longer thanstart_secs, so it resets the retry budget and never tripsFATAL.priority: 30, envWAYLAND_DISPLAY=wayland-0.
There is no Chrome eventlistener and no PROCESS_STATE_FATAL circuit breaker — relaunch is
handled entirely by restart: always on the supervised service. The chrome candy’s cgroup
resource caps (memory_max/memory_high/memory_swap_max/shm_size) still apply. See
/charly-selkies:selkies-desktop-layer and /charly-infrastructure:supervisord for the
supervised-service pattern, and /charly-selkies:chrome for the resource caps.
sway-browser-vnc is unaffected: it launches Chrome via the chrome-sway candy (not selkies-core), is not pixelflux-nested, and does not hit the startup-race.
Window Rules
Section titled “Window Rules”All windows open maximized (ideal for streaming desktop):
<windowRule identifier="*" serverDecoration="yes"> <action name="Maximize" /></windowRule>Used In Boxes
Section titled “Used In Boxes”/charly-selkies:selkies-labwc(viaselkies-desktopmetalayer)/charly-selkies:selkies-labwc-nvidia(viaselkies-desktopmetalayer)
Related Skills
Section titled “Related Skills”/charly-selkies:selkies— pixelflux streaming engine (provideswayland-1that labwc connects to)/charly-selkies:selkies-desktop-layer— desktop metalayer that composes labwc + chrome + waybar + selkies/charly-selkies:waybar-labwc— status bar configured for labwc/charly-selkies:chrome— Chrome browser (supervised by the selkies-core[program:chrome]service)/charly-check:wl— Wayland automation commands (screenshots, input, window management). On labwc it uses the wlroots backends (wlrctl pointer/toplevel, wlr-randr, wtype, wl-clipboard, pixelflux-screenshot). Those wlroots tools do NOT work on a headless rootless KWin pod (KWin implements none of the wlroots protocols — they hang), so on KWin the compositor-awareplugin-wlroutes window management throughkdotooland fail-fasts the wlroots paths; the KDE flavor’swl-verb-dispatchesprobe passes (compositor: kwin). See/charly-check:wl“Compositor Compatibility”
When to Use This Skill
Section titled “When to Use This Skill”MUST be invoked when the task involves the labwc candy, Wayland compositor configuration in selkies boxes, the labwc-wrapper script, window rules, or the nested compositor architecture (pixelflux → labwc → apps).
Related
Section titled “Related”/charly-image:layer— candy authoring reference (charly.ymlschema, task verbs, service declarations)/charly-check:check— declarative testing (check:block,charly check box,charly check live)