Watch
1
0
Fork
You've already forked SouveraineOS
0

tasks: settle viewtop scene composition + selection design; cross-link

TASK-43 gains the §Scene composition design settled 2026-07-30: the
texture/content wall, pose (geometry, the agent's) and expose (legibility,
gate-veiled) as authority-split verbs, the selection surface as a scene element
not a layer surface, and the primary-selection/data-control source now wired
(234a631) with its owed refinements named.

TASK-18: the selection chip's Hyprland surface layer is terminal (the tap bug
is layer-shell); its backends are portable. TASK-30: viewtop's wire table is one
of its surfaces, grown by pose/expose. TASK-17: the OSK z-order this task fought
is structurally enforced under viewtop.
This commit is contained in:
Fimeg 2026-07-30 11:36:50 -04:00
commit d4ea575404
4 changed files with 112 additions and 4 deletions

View file

@ -86,4 +86,7 @@ makes the mic key's state obvious.
[[whisper-stt-server]] (the STT backend), TASK-15 (dictation is a network
fetcher the idle coordinator must wake for), the stevia patches are
upstream candidates (Hyprland compat especially).
upstream candidates (Hyprland compat especially). Under viewtop the OSK's
z-order is structurally enforced by the compositor (`ad2b6cb`, TASK-43) — a
layer derived from the surface's furniture role, not a layerrule — so the
layer-collision class this task fought in quickshell does not arise there.

View file

@ -33,7 +33,10 @@ selection's bounding rectangle — Android does this at the toolkit layer
(ActionMode/FloatingToolbar), Apple in-app. So "tap on the highlighted text" is
not directly detectable; we know *what* is selected, never *where*. Hence the
chip near the touch point. True selection-rect anchoring is the one thing viewtop
would buy.
would buy — but only for *first-party* surfaces, where we own both ends and can
carry geometry through `wire`. Third-party opaque textures stay
pointer-hint-anchored: the texture/content wall is the Wayland contract itself,
not a gap viewtop closes. See TASK-43 §Scene composition.
**Still broken (Casey, on device 2026-07-29): the chip is not tappable or
dismissable.** It appears, and it correctly follows a new selection, but neither
@ -48,6 +51,15 @@ selection stuff".
Not yet wired: both agent actions (need the side-shoot / primary-conversation
seams in `Ai.qml`) and all three reference lookups. They render with the reason
they cannot act rather than dead-tapping.
**The selection surface is being rebuilt for viewtop (TASK-43 §Scene
composition).** There it is a scene element Annie composes, not a
`WlrLayer.Overlay` client — so the tap / z-order bug above is Hyprland-terminal;
do not spend a third attempt on it. The selection *backends* (`Speech.speak`
Read Aloud, the `Ai.qml` side-shoot / primary-conversation seams, the reference
lookups) are surface-agnostic; finish those, they carry straight across to
viewtop.
**Repo:** `~/Projects/souveraine` `surfaces/quickshell` (shell surface),
plus per-action backends noted below.

View file

@ -69,4 +69,7 @@ discovered**. Decide it when the first real chain exists, not before.
`SESSION-AUTHORITY-DOCTRINE` §13 (the mandate), `SHELL-ECOSYSTEM.md`
(manifests + guarded methods), `FIRST-CLASS-APPS.md` §6/§7 (legibility and
agency are two of the nine), `SETTINGS-AUTHORITY.md`, TASK-31 (the dial is the
human rendering of the same vocabulary).
human rendering of the same vocabulary). `souveraine-viewtop` `wire/verbs.rs`
is the compositor's table under this mandate (TASK-43); it gained `pose`
(geometry, the agent's) and `expose` (legibility, gate-veiled) for scene
composition on 2026-07-30 (`61cf90a`).

View file

@ -61,6 +61,93 @@ fmt-clean, so CI had never been able to pass; it can now.**
series; retarget the x86_64 manifest. This is the long pole.
4. **External texture → GBM atlas**, then the Dart shell.
## Scene composition & the selection surface — settled 2026-07-30
Doctrine §13 set the goal: client windows become textures the agent addresses,
not rectangles a window manager owns. This settles what that costs in `wire`,
and where the wall sits. Built for Annie and the substrate before the user — so
the verbs optimize for her control and fit the table grammar (`describe`-driven,
refusal-typed, test-enforced), not for a human picking from a menu.
### The wall: texture-level vs content-level
A surface arrives as a `TextureId` — a GPU buffer the shell paints. Annie can
transform the *whole* of it (it is hers to compose); she cannot reach *inside*
it. Selection rectangles, caret positions, handle geometry all live in opaque
client pixels, and no Wayland protocol exposes them to the compositor. viewtop
keeps this wall on purpose: it is the contract that lets Firefox, GTK, Qt run
unmodified.
- **Whole-texture ops reach every app, including Firefox:** `pose`, `place`,
`expose`. This is the ambient merge.
- **Content-level reach does not, for opaque clients.** Selection-handle
geometry inside a third-party surface is unknowable. True rect-anchoring is
available only for *first-party* surfaces, where we own both ends and can
carry geometry through `wire`.
### Two new verbs, split by who owns them
The 60/40 decides where each property lives, and therefore which table it is in.
**`pose`** — geometry is Annie's (the 60). Rotation, scale, anchor: how the
texture is painted. One atomic verb, struct-extensible (`skew`, `pivot`,
`parallax` later, without new verbs or new tests). The compositor reads it for
**inverse input-mapping** — the real cost of "spin and twirl" is not the paint
but mapping a touch on a rotated surface back into client coordinates. Refused
only when remap is impossible (mid predictive-back drag, exempt surfaces).
```json
{"intent":"pose","id":1,"rotation":30.0,"scale":0.9,"anchor":{"x":0.5,"y":0.5}}
```
**`expose`** — legibility straddles the line. Annie requests a level; the gate
may clamp it down (`veil`) per the surface's `Sensitivity` and device state
(`Observed`, `Locked`). She never unilaterally de-obscures a `Credential`
surface — that is a step-up, the 40. Levels climb `obscured → dimmed → ambient →
clear`; policy is a floor the aesthetic composes on top of in the render.
```json
{"intent":"expose","id":1,"level":"ambient"}
```
`place` stays as-is (translate + size, input geometry). `place` + `pose` are the
geometry family; the compositor composes both for hit-testing. The ambient merge
is a **chain**`{pose, expose}` applied atomically by the shell's render —
which is the unit Annie already plans in, so atomicity is expressed in the
existing grammar, not invented.
### The selection surface is a scene element, not a layer surface
On Hyprland the selection chip is a `WlrLayer.Overlay` client fighting z-order —
the entire tap / `ExclusionMode` / `keyboardFocus` bug class (TASK-17,
TASK-18's broken state) is a layer-shell artifact. On viewtop the selection
surface is another node in the one Flutter scene Annie composes. No layer shell,
no z-order war. The bug dissolves by construction.
### Selection source: primary-selection + data-control — wired 2026-07-30
The shell needs "what is selected." viewtop now serves `zwp_primary_selection_v1`
and `zwlr_data_control_manager_v1` (the latter created against the
primary-selection state, so a data-control client observes primary selections
without focus) — the combination `wl-paste --primary --watch` relies on
(`234a631`). Geometry stays unavailable for opaque clients (the wall), so
third-party anchoring remains pointer-hint-based, while first-party surfaces can
carry true rects.
Owed at this boundary: `ext_data_control` (the standardized successor; its
same-named `DataControlState` collides with wlr's, so it is its own pass), and a
disclosure gate that withholds selection content while locked and narrows
observation to the shell/agent client. `data_device_state` is wired the same
plain way today, so the gate is owed across the whole frontend, not just here.
### What is portable from the Hyprland chip, what is terminal
The selection *backends* are surface-agnostic and worth finishing now:
`Speech.speak` for Read Aloud, the `Ai.qml` side-shoot / primary-conversation
seams (TASK-18 §2), the reference lookups. The Hyprland *surface* layer (the
`WlrLayer.Overlay` chip, its anchoring, its z-order) is terminal — do not polish
it. See TASK-18.
## Owed, named rather than hidden
- `StepUp::from_authority` has no caller: sessiond has **no step-up verb**, so
@ -84,4 +171,7 @@ fmt-clean, so CI had never been able to pass; it can now.**
`VIEWTOP-AND-DENIAL.md` (what is liftable), TASK-02/03 (the lock surfaces and
the boot timeline it must not regress), TASK-30 (the intent table is one of the
surfaces that owed one), TASK-31/37 (the dial and back share the table),
TASK-41 (attestation), TASK-25/27 (viewtop is not packaged), doctrine §4/§13.
TASK-18 (the selection surface is a scene element here, not a Hyprland layer
surface; its backends are portable), TASK-17 (the OSK z-order precedent the
selection surface inherits), TASK-41 (attestation), TASK-25/27 (viewtop is not
packaged), doctrine §4/§13.