docs(display-management): Stage 5 host + web build complete — only on-glass validation + residuals left

Mark the web arrangement table done and narrow "remaining Stage 5" to validation
(2 clients on a GPU box, not the dev VM) plus the two documented residuals (wlroots
exclusive, Mutter APPLY_TEMPORARY revert). No further host/web build work in Stage 5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-05 13:33:05 +00:00
parent a7ff1cf312
commit fa45608628
+23 -14
View File
@@ -6,10 +6,12 @@
> `exclusive`/`primary` (KWin name-filter + first-slot-wins; Mutter `set_first_in_group`), **per-group > `exclusive`/`primary` (KWin name-filter + first-slot-wins; Mutter `set_first_in_group`), **per-group
> topology restore** (KWin restore floats through the group, runs on the last member's teardown), the > topology restore** (KWin restore floats through the group, runs on the last member's teardown), the
> **layout engine** (`vdisplay/layout.rs`, auto-row + manual) + registry-driven `apply_position`, and the > **layout engine** (`vdisplay/layout.rs`, auto-row + manual) + registry-driven `apply_position`, and the
> `PUT /display/layout` endpoint with group/position/index in `/display/state`. **Remaining Stage 5:** the > `PUT /display/layout` endpoint with group/position/index in `/display/state`, and the **web console
> web console arrangement table + on-glass validation (2 clients on a GPU box) + a couple of documented > arrangement table** (x/y editor → `PUT /display/layout`). **Remaining Stage 5 = validation + residuals
> residuals (wlroots `exclusive`, Mutter `APPLY_TEMPORARY` revert). See the **Status — handoff** block > only** (no more build work): on-glass validation (2 clients on a GPU box, not the dev VM) + two
> under §11 for the per-stage state and the key decisions (notably the Windows `reject` default). > documented residuals (wlroots `exclusive`, Mutter `APPLY_TEMPORARY` revert). See the **Status —
> handoff** block under §11 for the per-stage state and the key decisions (notably the Windows `reject`
> default).
> This doc designs a **policy layer on top of the > This doc designs a **policy layer on top of the
> existing per-compositor `VirtualDisplay` backends** — user-configurable lifecycle (keep-alive > existing per-compositor `VirtualDisplay` backends** — user-configurable lifecycle (keep-alive
> after disconnect), topology (primary / exclusive), conflict handling (what happens when a second > after disconnect), topology (primary / exclusive), conflict handling (what happens when a second
@@ -685,9 +687,10 @@ GNOME/Mutter, RTX 5070 Ti), **`.116`** (Bazzite KDE/KWin, AMD — build via a `f
(`position_for_new` over the whole group; skips the origin so the single-display path is unchanged), the (`position_for_new` over the whole group; skips the origin so the single-display path is unchanged), the
`PUT /api/v1/display/layout` endpoint (`EffectivePolicy::with_manual_layout`), and `/display/state` now `PUT /api/v1/display/layout` endpoint (`EffectivePolicy::with_manual_layout`), and `/display/state` now
carrying `group`/`display_index`/`position`/`identity_slot`/`topology`. The registry keys the arrangement carrying `group`/`display_index`/`position`/`identity_slot`/`topology`. The registry keys the arrangement
on per-client identity via `VirtualDisplay::last_identity_slot` (KWin). **Remaining:** the web arrangement on per-client identity via `VirtualDisplay::last_identity_slot` (KWin). The **web arrangement table**
table + on-glass validation + the documented residuals (wlroots `exclusive`, Mutter `APPLY_TEMPORARY` (`DisplayCard.tsx` `DisplayArrangement`, en+de) is also done. **Remaining = validation + residuals only:**
revert) — see the Stage 5 entry below. on-glass validation + the documented residuals (wlroots `exclusive`, Mutter `APPLY_TEMPORARY` revert) —
see the Stage 5 entry below.
**Decisions / deltas from this plan as written — read before continuing:** **Decisions / deltas from this plan as written — read before continuing:**
- **Windows admission default is `reject`, NOT `join`** (supersedes the Stage-4 line below). Two - **Windows admission default is `reject`, NOT `join`** (supersedes the Stage-4 line below). Two
@@ -793,16 +796,22 @@ Stage-5 group-aware exclusive.
(no shared desktop), so `registry::group_key` makes each gamescope display its OWN group — never (no shared desktop), so `registry::group_key` makes each gamescope display its OWN group — never
auto-rowed against, topology-grouped with, or restore-grouped with another gamescope. Unit-tested. auto-rowed against, topology-grouped with, or restore-grouped with another gamescope. Unit-tested.
(§6B single-output "decline extras" is Stage 6.) (§6B single-output "decline extras" is Stage 6.)
**TODO (still Stage 5):** - **Console arrangement table (web)** [DONE ✓]: a `DisplayArrangement` x/y editor in the `Virtual
- **Console arrangement table (web)** — an x/y editor in the `Virtual displays` card reading displays` card (`web/src/sections/Host/DisplayCard.tsx`) — for a ≥2-display group it renders an x/y
`/display/state` and writing `PUT /display/layout` (x/y table first; drag mini-map is the stretch). table over the live displays that carry an identity slot, seeded from `/display/state`, and Save
The host API + persistence are done; this is the remaining web-only piece. writes `PUT /display/layout` (switches the host to a manual layout, applied next connect). en+de
i18n; the stale `display_pending_note` copy refreshed. tsc + vite build green. (Drag mini-map is a
later stretch.)
**Remaining Stage 5 — validation + deferred residuals only (no more host/web build work):**
- **On-glass validation** (needs a GPU box + 2 clients — NOT the GPU-less dev VM): two clients
(probe + GTK) on the headless KDE box forming a 2-output desktop; drag a window across; disconnect
one → its slot lingers per policy, the sibling is unaffected, and the physical is restored only after
BOTH drop (the per-group restore). Plus the concurrent-Mutter case on a GNOME box.
- **wlroots group-aware exclusive** stays deferred: wlroots `exclusive` is not implemented at all (needs - **wlroots group-aware exclusive** stays deferred: wlroots `exclusive` is not implemented at all (needs
a Sway box), so there is no topology to make group-aware yet. §6A multi-view on wlroots already works a Sway box), so there is no topology to make group-aware yet. §6A multi-view on wlroots already works
(independent `HEADLESS-N` outputs). (independent `HEADLESS-N` outputs).
*Validate (all on-glass, needs a GPU box + 2 clients — not the dev VM):* two clients (probe + GTK) on - **Mutter `APPLY_TEMPORARY` disconnect-revert** (§7): when the FIRST Mutter session leaves under a live
the headless KDE box forming a 2-output desktop; drag a window across; disconnect one → its slot lingers sibling, Mutter reverts the topology — a full fix needs a group-owned `DisplayConfig` connection.
per policy, sibling unaffected, restore only after both drop.
- **Stage 6 — §6B protocol + Linux host + GTK client.** `VIDEO_CAP_MULTI_DISPLAY`, control- - **Stage 6 — §6B protocol + Linux host + GTK client.** `VIDEO_CAP_MULTI_DISPLAY`, control-
stream Add/Remove/DisplayAdded, per-flow nonce-salt derivation, per-display pipelines on stream Add/Remove/DisplayAdded, per-flow nonce-salt derivation, per-display pipelines on
KWin/wlroots, input display-index routing, C ABI additions, GTK client multi-window KWin/wlroots, input display-index routing, C ABI additions, GTK client multi-window