Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/tasks/31-radial-dial.md

4.4 KiB

TASK 31 — The radial dial

Status: component and invocation live 2026-07-28 — geometry, haptic detents, gesture routing table, and a squeeze that opens it through sessiond. Left: the contents. DialHost.qml:75 still holds a hand-written entries list; it must come from the verb tables (TASK-30), which is the whole argument below. Size: one session for the contents. Repo: ~/Projects/souveraine (surfaces/quickshell).

Goal

A radial dial of options, summoned by a gesture, reachable by thumb without looking. The phone's fastest path from "I want a thing" to the thing.

The idea worth getting right first

The dial and the agent's verb table are the same vocabulary. One rendered for a thumb, one for a composer. A dial whose entries are a hand-written list is a third place device capabilities are enumerated — after the verb table and the manifests — and it will drift from both within a month.

So the dial's contents come from the surfaces' describe (TASK-30): each entry is a verb that mutates, is permitted in the current state, and has somewhere to say what it does. A verb the agent cannot reach should not appear on the dial either, and vice versa. That is the check that keeps them one system.

This also settles what happens on a refused entry: the dial shows the refusal's code as its disabled reason (refused_by_state → "not while locked"), because the surface already had to say so.

Priority order — the component before the contents

TASK-18 learned this the hard way and wrote it down: "the stevia keyboard shipped glitchy because the surface work was rushed." A dial whose actions are stubs is fine. A janky dial is not.

  1. The component. Geometry, anchor, open/close animation, thumb reach, what happens when it opens near a screen edge, how it dismisses. Built from Souveraine-owned AGPL primitives — this is a first user of the primitive set souveraine-lock-primitives (archive/from-substrate) specifies, and a good reason to build them, since a dial needs shapes and ripples that ii's widgets would otherwise supply.
  2. Invocation. Squeeze is the natural one (TASK-13) and is not the only one — long-press and an edge gesture want to reach it too. Every path registers through the gesture/keyboard routing system, never a hardcoded binding (INTERFACE-ARCHITECTURE §4).
  3. Contents. From the verb tables, per above.

Constraints inherited, not invented

  • Layer and state. The dial declares its layer and lets shell state gate it (FIRST-CLASS-APPS §4). It must not paint over a locked screen, fight the OSK, or survive an overview.
  • Lock and tier. Ambient entries may appear on the lock surface; personal ones and any mutation gate on screenLockSecure plus a fresh grant (FIRST-CLASS-APPS §5). A dial is exactly the shape of thing that leaks by being convenient.
  • Update management. It ships as part of the shell surfaces, which are not packaged today — they live in $HOME and arrive by rsync. TASK-25 names this; the dial does not get an exception, and "how does this reach a device" is part of its acceptance, not an afterthought.

Acceptance

  • Opens under the thumb from any app, at any screen edge, without clipping.
  • Dismisses by the same gesture, by tapping away, and by pressing back.
  • Entries are derived from a surface's verb table, not a list in the QML.
  • A disabled entry says why, in the words the refusal already used.
  • Does not appear over a locked screen with anything personal on it.
  • Reaches a device by a mechanism that survives the next update.

Visual references (recon 2026-08-11)

  • ay-hooshan/circular-menu — a ring of Qt Quick Shapes wedges with a center cutout, elastic open animation, per-wedge icon color and click. No screenshots upstream — unproven visuals, treat as geometry reference only, not a look to copy. ~664 lines.
  • nextsigner/timelineview — Qt 5.14 "Zooland": concentric-circle chart rendering (bodies/houses/signs/aspect arcs) plus a ZmMoveTime motion dial. The concentric ring composition and arc math are the sample; the astrology content is not.

Connects to

TASK-13 (squeeze — the first invocation), TASK-30 (the vocabulary), TASK-18 (selection menu — the other summoned surface; they should not become two frameworks), FIRST-CLASS-APPS.md, INTERFACE-ARCHITECTURE.md §4, souveraine-lock-primitives.md (the owned widget set this needs).