55 lines
3.6 KiB
Markdown
55 lines
3.6 KiB
Markdown
# How the phone shell works
|
|
|
|
Three surfaces: **bar** (top), **dock** (bottom, above the navigation rail),
|
|
and Souveraine's integrated **navigation rail** (bottom edge).
|
|
Edit here → `./deploy.sh --phone` → restart. Deployed via symlink; live edits = git-tracked.
|
|
|
|
## Navigation rail (`modules/souveraine/navigation/SystemGestureRail.qml`)
|
|
|
|
- **Always visible.** `WlrLayer.Overlay` + `ExclusionMode.Ignore` + `margins.bottom:0`. Survives fullscreen, dock, OSK. Never lower the layer.
|
|
- **Owned by Souveraine.** It is loaded by `SouveraineFamily` on phone mode;
|
|
there is no second Quickshell configuration, external IPC hop, or Hyprland
|
|
layer rule to keep in sync.
|
|
- Gestures (MouseArea — pointer handlers don't get touch here):
|
|
- **double-tap** → toggles the active app's named `fullscreen` mode (whole
|
|
display, no border/gaps). Targets `Hyprland.activeToplevel.address` — not
|
|
hyprctl's focus (the tap focuses the shell).
|
|
- **swipe up** → reveals the dock.
|
|
- **swipe down** → dismisses the dock.
|
|
- **No keyboard on the rail.** OSK = 3-finger hyprgrass swipe only.
|
|
|
|
## Dock (`modules/ii/dock/Dock.qml`)
|
|
|
|
- **On `WlrLayer.Overlay`** so the navigation rail can reveal it over fullscreen apps.
|
|
- **Hidden = layer unmounted** (`visible:false`), not just tucked — else it paints over fullscreen.
|
|
- **Visibility** (`computeDockState`, first match wins):
|
|
1. fullscreen app on focused monitor → **Hidden** (unless rail-revealed)
|
|
2. pinned → **Pinned** (only state that reserves exclusive zone)
|
|
3. preview-hover → **Shown**
|
|
4. empty desktop / no focused app → **Shown**
|
|
5. else (normal app focused) → **Hidden**
|
|
- **Reserves the navigation rail height** at the bottom visually *and in its
|
|
layer-shell input mask*, so the dock cannot intercept rail touches.
|
|
- **Bar height is content-driven**: the window sizes itself to the button row (64px buttons) + row margin + rail height; `Config.options.dock.height` is only a floor. Don't tune the config height to "fix" icon clipping.
|
|
- **App list width is capped** to the screen (`DockApps.maxWidth`); past that the icon row scrolls horizontally by touch (flick is only enabled when overflowing, so drag-to-combine keeps working when everything fits).
|
|
- **DockStack renders with the same content block as DockAppButton** (icon + half-reserved dot strip, centered as one unit). Keep them structurally identical or they drift apart on the bar.
|
|
- Depends on **`GlobalStates.dockRevealed`** — lives in the surface tree (`GlobalStates.qml`, stock ii + patch) and the deploy manifest. If ii updates its GlobalStates, re-diff and re-apply the patch.
|
|
|
|
## souveraine-settings (planned, not built)
|
|
|
|
A future settings app for the phone shell. Planned sections:
|
|
|
|
- **Dock** — pinned apps, height floor, monochrome icons, ignored-app regexes (today: hand-edited in `~/.config/illogical-impulse/config.json`).
|
|
- **Stacks** — create/rename/reorder app stacks and their members (today: `dock.stacks` strings in config.json, or drag-to-combine on the dock).
|
|
|
|
The dock already reserves its entry points: the long-press menu's "App settings…"
|
|
and the `dockSettings` IPC target (`openApp(appId)` / `open()`) in `Dock.qml`.
|
|
Both are STUBS — they log and pulse the dock, nothing opens. That's deliberate:
|
|
the IPC name stays stable so the settings app can take it over without touching
|
|
the dock.
|
|
|
|
## Fullscreen API (Hyprland 0.55, Lua dispatch)
|
|
|
|
- Dispatch: `hl.dsp.window.fullscreen({ window="address:0x…", mode="fullscreen", action="toggle" })`.
|
|
- **`fullscreen`** = whole display, no borders or gaps. ← the navigation rail uses this.
|
|
- **`maximized`** = keeps the normal workspace layout margins.
|