Watch
1
0
Fork
You've already forked SouveraineOS
0

SouveraineOS umbrella: docs, dumps, handoffs, cross-repo STATE

This commit is contained in:
Fimeg 2026-07-16 08:59:26 -04:00
commit dc4fd14bbd
13 changed files with 2360 additions and 0 deletions

View file

@ -0,0 +1,182 @@
# Phone shell — interface architecture
The phone has four primary interfaces the user actually touches: the **pill**,
the **dock**, the **keyboard**, and **touch/gesture**. This doc names what each
one is *meant to be*, what it is *today*, and the single seam where a hardcode
should become a small framework so the surface can grow without rewrites.
Principle: **clean beats feature-rich.** Each surface has one job and one place
its behaviour is tuned. A new feature should be a new entry in an existing
table, not a new hardcoded branch. Where a value is tuned in more than one
place today, that is the bug — not the value.
Truth hierarchy: this doc describes intent; `HOW-IT-WORKS.md` describes the
current wiring; the code is the reality. When they disagree, fix the code or
fix the doc in the same change — never leave a third story.
---
## 1. Pill — the always-on gesture bar
**Meant to be:** the one surface that is *always* reachable, on any app, in any
state. A thin, dumb input strip at the bottom edge that recognises a small
fixed vocabulary of gestures and forwards them — it owns no app state and makes
no decisions beyond "which gesture was this."
**Today (`pill/shell.qml`):** `WlrLayer.Overlay`, `ExclusionMode.Ignore`,
`margins.bottom:0`. Gesture arbitration is one MouseArea (double-tap, swipe up,
swipe down) → `dock` IPC. This part is clean and well-reasoned.
**The seam / the bug:** the pill's z-order guarantee is *documented but not
enforced*. `pill/shell.qml:23-27` sets namespace `quickshell:pill` and points
at "the `order` layerrule in hyprland.lua" — **that layerrule does not exist**
(hyprland.lua only has a commented-out generic `^my-overlay$` example). So
after an `ii` restart the pill can be buried under the dock and stop taking
touch — the exact failure the comment says is solved. Fix: add the real
`order` layerrule for `quickshell:pill`, or drop the promise from the code and
docs. Do not add more pill gestures until stacking is enforced — an always-on
surface that silently dies is worse than a plain one.
**Growth rule:** new pill gestures are new cases in the one MouseArea, each
forwarding to a *named* IPC target — never doing app logic inline.
---
## 2. Dock — the app switcher and stack surface
**Meant to be:** the surface that shows and switches running/pinned apps and
lets the user group them into stacks. It owns app-presentation state; it does
not own gesture recognition (the pill and hyprgrass feed it via IPC).
**Today:** interaction layer (`Dock.qml`, `DockAppButton.qml`, `DockStack.qml`)
is strong — drag-to-combine, fan-out arc, visibility state machine
(`computeDockState`). The weak layer is **state/config**:
- Stacks are a hand-parsed string `"stackId|appId,appId"` (`TaskbarApps.qml:25`).
A `|` or `,` in a name corrupts it silently; parsed/encoded in ~6 places.
→ move to **one JSON blob per entry** (array-of-strings the adapter tolerates,
but each string is JSON): kills the delimiter-corruption class, keeps the
adapter happy. This is the agreed direction.
- Stack ids are count-based (`nextStackName` = `"Stack " + (count+1)`,
`:87`) → collide after a delete, and `id` is the lookup key. Two stacks can
share an id and cross-contaminate members. → stable uid, display name
separate from id.
- Combining into a new stack suppresses the target's standalone pin at *render*
time (`apps` getter) but never removes it from `pinnedApps` in config
(`:99-108`) → the pin lingers; unstack works by luck. → remove-on-combine so
config matches what's shown.
- Tap-cycle `lastFocused` index (`DockAppButton :196`) is never reconciled when
windows open/close and is also written by hover (`:180`) → tapping can focus
the wrong window. → clamp/reconcile against the live toplevel model.
- Magic numbers live in the components: `pillStripHeight 32` (`Dock.qml:161`),
dwell `500` (twice: `DockAppButton:133`, `DockStack:116`), double-tap `350`,
arc geometry (`DockStack:33-36`). → lift into `Config.options.dock` next to
the `height`/`monochromeIcons`/`hoverRegionHeight` that already live there.
- `reorderStackMember` (`TaskbarApps:113`) is dead — superseded by
`setStackOrder`. → remove, or wire the menu reorder it was meant for.
**The seam:** `Config.options.dock` already exists — the framework anchor is
already there. "More structure" here means *finishing* that namespace (all
tuning knobs + a real stack schema under it), not inventing a new one.
**Growth rule:** dock feel/config knobs go under `Config.options.dock`; stack
members are structured entries, not delimited strings. Rename + ungroup are
table-stakes and should exist before any fancier stack feature.
---
## 3. Keyboard (OSK) — squeekboard
**Meant to be:** an on-screen keyboard that appears on text focus and can be
summoned by one deliberate gesture, driven through **one** IPC target so its
visibility and any focus-grab shield always move together.
**Today:** squeekboard, launched from `hyprland.lua`, auto-shows via
input-method-v2, toggled by 3-finger swipe-up routed through ii's `osk` IPC.
The *routing* is right (single `osk` target).
**The seam / the drift:** the comments and the retained
`quickshell-ii-patches/OnScreenKeyboard.qml` still describe **wvkbd**
(retired 2026-07-10) and its focus-grab shield — the `osk` IPC now drives
squeekboard, but the code comments and the history-only patch file still tell
the wvkbd story. Same doc-vs-reality drift as the pill layerrule. → update the
comments to squeekboard reality; confirm whether `OnScreenKeyboard.qml`'s
GlobalStates.oskOpen plumbing is still the thing `osk toggle` hits, or vestigial.
**Growth rule:** one `osk` IPC target owns show/hide; layout/theme is
squeekboard config, addressable later from souveraine-settings. No second path
to toggle the keyboard.
---
## 4. Touch / gesture — the input spine
**Meant to be:** one routing layer that maps a physical touch gesture to a
named interface action. Today this is the messiest surface because it is spread
across four dispatch styles.
**Today (`hyprland.lua`):**
- `hl.gesture{fingers=3,horizontal}` → workspace (Hyprland-native)
- `hl.plugin.hyprgrass.bind{...}` → close / terminal / edge-swipes →
`qs -c ii ipc call <target>`
- the pill's own MouseArea → `dock` IPC
- `touchdevice.output = "DSI-1"` binds touch to the panel for rotation
Two input sources (pill swipe-up, hyprgrass edge-swipe-up) both drive the dock;
no single arbiter. Gesture → action bindings are inline `exec_cmd` strings
scattered through the file.
**The seam:** this is the memory note "don't hardcode bindings blindly; need a
routing system to avoid overlap." The clean form is **one gesture table**
edge/finger/direction → named IPC target — read top-to-bottom so overlaps are
visible in one place. Every binding already ends in a `qs ... ipc call <target>`;
the framework is just making that table explicit and single-sourced instead of
sprinkled through `hyprland.lua`.
**Growth rule:** a new gesture is a new row in the gesture table pointing at a
named IPC target. Two rows may not target the same action from different edges
without being adjacent in the table (so overlap is obvious).
---
## Cross-cutting: the one recurring defect
Three of four surfaces have the **same** flaw — *a documented guarantee the
code doesn't enforce*: the pill layerrule (doc says pinned, code doesn't pin),
the keyboard (comments say wvkbd, code runs squeekboard), the dock stack pin
(render says suppressed, config says still pinned). Cleaning these up is mostly
making the code match its own stated contract, then giving each surface exactly
one place it's tuned.
## Status (2026-07-13)
1. ~~Pill layerrule~~ DONE — `pill-above-dock` rule added to hyprland.lua
(`order = 1` on `^quickshell:pill$`). VERIFY ON GLASS: `order`
passthrough in the Lua layer_rule wrapper is untested on this build.
2. ~~Gesture table~~ DONE — hyprgrass binds are one `touch_gestures` table
in hyprland.lua; the two other gesture sources (hl.gesture workspace
swipe, the pill's MouseArea) are listed in its header so overlap stays
visible in one read.
3. ~~Dock state layer~~ DONE — JSON-per-entry stacks (legacy pipe entries
still parse, rewritten on next write), minted `stack-N` ids that never
reuse after delete, name separate from id (+ `renameStack()`, no UI
yet), pin actually removed from config on combine, tap-cycle starts
from the truly focused window, dead `reorderStackMember` removed,
`dragDwellMs`/`pillStripHeight` lifted into `Config.options.dock`.
4. ~~Keyboard~~ DONE — hyprland.lua comments tell the squeekboard story;
`OnScreenKeyboard.qml` (the "osk" IPC owner) moved into this surface +
deploy manifest. Remaining hand-deployed patches (BarContent, Network,
QuickSliders, switchwall.sh) noted in overlays/QUICKSHELL-MOVED.md.
## Open decision — two-stage swipe-up was removed, not lost by accident?
Souveraine commit `6e21c50` ("resume agent conversations from server")
reworked the dock state machine: the Peek state, `dockRevealPulse`, and the
two-stage swipeUp (reveal → escalate to overview) all went away in favor of
a flat reveal/hide contract — under a commit title that says nothing about
the dock. Pixel3Arch CLAUDE.md still records two-stage as SHIPPED
(2026-07-11). The replacement comment is articulate, so this reads as a
deliberate redesign, but it needs Casey's confirmation: keep the flat
contract (overview = the dock's apps button), or restore the escalation.
Comments in hyprland.lua/HOW-IT-WORKS now describe the flat behavior that
actually runs.