# Stereo KWin bench root, 2026-10-14

A Debian testing root file system with Sparky Stereo OS's Stereo KWin and the DisplayXR window-geometry publisher, for the kwin phase of the VKMS bench ([tools/vkms-stereo-bench](https://github.com/Sparky-OS/sparky-stereo-os/tree/main/tools/vkms-stereo-bench)), for running KWin headless (`kwin_wayland --virtual`) under bubblewrap, or in a chroot with `kwin_wayland` in a logind session, as DisplayXR ran the 2026-10-13 root on a Samsung Odyssey 3D.
It has no kernel and no boot loader: the bench boots its own kernel, and a chroot uses the host's.
This root replaces the one published on 2026-10-13 (KWin 4:6.7.4-2+stereo3d20), which stays available under `previous/2026-10-13/`.

## Files

| File | What it is |
|---|---|
| `sparky-stereo-kwin-root-20261014.tar.zst` | the root: 793 packages, 571 MB compressed, about 1.8 GB unpacked |
| `sparky-stereo-kwin-root-20261014-sources.tar` | the Debian source packages of everything in it that Sparky Stereo OS builds or changes (17): base-files, ffmpeg-dmo, gl-stereo, kf6-kiconthemes, kf6-kimageformats, kf6-kio, kpipewire, krdp, kscreenlocker, kwin, libkscreen, mesa, plasma-wayland-protocols, qt6-base, stereo-declare, stereo-layer, xwayland |
| `sparky-stereo-kwin-root-20261014.packages` | every package and its version (also inside the root, at `/etc/sparky-stereo-kwin-root.packages`) |
| `SHA256SUMS` | checksums of the three files above |
| `build-kwin-root.sh`, `build-in-container.sh`, `collect-sources.sh` | the recipe this root was built with, the container it ran in, and how the sources were gathered |

Unpack it with `mkdir sparky-root && tar -C sparky-root --exclude='./dev/*' -xf sparky-stereo-kwin-root-20261014.tar.zst` (the guest mounts its own `/dev`).

## What changed

Against the 2026-10-13 root:

| Package | Before | Now |
|---|---|---|
| KWin (kwin-wayland, libkwin6, kwin-common, kwin-data) | 4:6.7.4-2+stereo3d20 | 4:6.7.4-2+stereo3d21 |
| displayxr-window-geometry-publisher-kwin | 4:6.7.4-2+stereo3d20 | 4:6.7.4-2+stereo3d21 |
| KIO (kio6 and the libkf6kio* libraries) | 6.30.0-1+stereo3d1 | 6.30.0-1+stereo3d2 |
| KIconThemes (libkf6iconthemes6, libkf6iconwidgets6, libkf6iconthemes-data) | Debian's 6.30.0-1 | 6.30.0-1+stereo3d1 |
| KPipeWire (libkpipewire6, libkpipewirerecord6, libkpipewiredmabuf6, libkpipewire-data) | 6.7.4-1+stereo3d1 | 6.7.4-1+stereo3d3 |
| krdp | 6.7.4-1+stereo3d1 | 6.7.4-1+stereo3d2 |
| libkscreenlocker6 | Debian's 6.7.4-1 | 6.7.4-1+stereo3d1 (with libstereoshow1 0.2.0-1) |
| libstereo-layer1, libstereo-layer-dev | 1.1.0-1 | 1.3.0-1 |
| Cursor themes: `oxygencursors` (the edition's Oxygen cursors), `breeze-cursor-theme` (the fallback) | not installed | 0.0.2012-06-kde4.8-8, 4:6.7.4-1; `/etc/xdg/kcminputrc` sets `cursorTheme=oxy-black` |
| PipeWire: `pipewire-bin` (the client configuration, `/usr/share/pipewire/client.conf`), `libpipewire-0.3-modules`, `pipewire`, `wireplumber` | not installed (only libpipewire-0.3-0t64) | 1.6.9-2, 0.5.18-1 |
| The DisplayXR KWin audit kit at `/opt/displayxr-kwin-audit`, its C tools built, with what it needs: `python3-dbus`, `python3-gi`, `python3-numpy`, `python3-pil`, `libdbus-1-dev`, `gstreamer1.0-pipewire`, `gstreamer1.0-tools`, `gstreamer1.0-plugins-base`, `gstreamer1.0-plugins-good` | not installed | see below |
| Mesa, libkscreen, Qt 6 base, Xwayland, plasma-wayland-protocols, the stereo declaration library, FFmpeg (deb-multimedia) | 26.1.6-1+stereo3d10, 4:6.7.4-1+stereo3d7, 6.11.2+dfsg-5+stereo3d5, 2:24.1.13-1+stereo3d1, 1.21.0-1+stereo3d5, 1.1.0-1, 10:9.0.2-dmo1+stereo3d3 | unchanged |

The two things found missing on the first panel run (DisplayXR/displayxr-runtime#1928, 2026-10-14) are the cursor theme, so KWin draws a pointer for a person in front of the panel ("Unable to load any cursor theme" before), and PipeWire's client configuration, so `kwin_screencast` can create its PipeWire context ("Failed to create PipeWire context" before). The daemon and WirePlumber are in the root too, for a session without a PipeWire of its own.

What KWin +stereo3d21 adds over +stereo3d20: a guard on cursor queries while a virtual panel changes replication. The publisher is the one of +stereo3d18.2 (move sync, `buffer_device`, `MoveWindow` landing the buffer). It does not yet carry the fix for the rest case found on the Odyssey (no `WindowsChanged` when `buffer_device` changes as move sync releases its hold): that fix is in review for the next KWin set, and this root is rebuilt from the same recipe when it is published.

## The audit kit

`/opt/displayxr-kwin-audit` is [Sparky-OS/displayxr-kwin-audit](https://github.com/Sparky-OS/displayxr-kwin-audit) (BSL-1.0), the tests behind the KWin tables on DisplayXR/displayxr-runtime#1928: placement against `buffer_device`, `MoveWindow`, drop landings, move sync frame by frame from KWin's screen cast, and the hand-drag rest case; its `README.md` says what each measures and how it is read, and `docs/chroot.md` how to run it against a KWin in a chroot with a logind session.
Its C tools are built in `/opt/displayxr-kwin-audit/build`; from inside the root, `AUDIT_BIN=/opt/displayxr-kwin-audit/build`.
It needs KWin started with `KWIN_SCREENSHOT_NO_PERMISSION_CHECKS=1` and `KWIN_WAYLAND_NO_PERMISSION_CHECKS=1` in its environment, so KWin's screenshots and fake input answer the kit's clients.

## How it was built

`build-kwin-root.sh` (mmdebstrap 1.5.7, unshare mode) in a throwaway container from `debian@sha256:9e1caa3238f2e4eee5b28c781ec712798d5d1192a6206d9e0bc7ee2861717a00` (debian:testing for amd64, pinned by digest), on 2026-10-14 at 04:58 UTC: Debian testing from deb.debian.org as of that time, the edition's packages from its repository pinned at 1001, and deb-multimedia forky.
`build-in-container.sh` ran mmdebstrap as the container's root with `CAP_SYS_ADMIN` added, the one capability its mount namespace needs inside Docker (no `--privileged`); the kit went in with mmdebstrap's `sync-in` from a clean export of its git head (`/opt/displayxr-kwin-audit/.commit`), and `tools/build.sh` ran inside the chroot.
The apt source for the edition inside the root is the build's local `copy:///repo` line, which exists only during the build: replace it before running apt in the root.

## Checked on it

Stereo KWin from this root (the same packages, the kit copied in afterwards) ran headless at 200 % and 125 % under bubblewrap, with the publisher answering (capabilities 27), the runtime main and `cube_handle_vk_linux` (displayxr-common v2.32.0) on sim_display interlaced.
With the kit, at both scales: placement 18 of 18 `buffer_device` = painted (the old conversion right in 6 of 18 at 200 % and 9 of 18 at 125 %), `MoveWindow` 8 of 8, drop landings 6 of 6, move sync 0 frames painted off their woven origin while held; the hand-drag rest case fails on 2 of 5 drags at 200 % and 1 of 5 at 125 %, which is the Odyssey finding, fixed in the next KWin set.
Inside the root, the kit's tools build with the root's own gcc, its Python modules import, and GStreamer finds `pipewiresrc`, `videocrop` and `pngenc`.
The numbers are on [DisplayXR/displayxr-runtime#1928](https://github.com/DisplayXR/displayxr-runtime/issues/1928).
