Watch
1
0
Fork
You've already forked souveraine
0
souveraine/surfaces/quickshell/HOW-IT-WORKS.md

3.6 KiB

How the phone shell works

Three surfaces: bar (top), dock (bottom, above pill), pill (bottom edge). Edit here → ./deploy.sh --phone → restart. Deployed via symlink; live edits = git-tracked.

Pill (pill/shell.qml) — the always-on gesture bar

  • Always visible. WlrLayer.Overlay + ExclusionMode.Ignore + margins.bottom:0. Survives fullscreen, dock, OSK. Never lower the layer.
  • Must sit ABOVE the dock in z-order (both on Overlay; later-created wins). Restart pill LAST, or it gets buried and stops taking touch.
  • Gestures (MouseArea — pointer handlers don't get touch here):
    • double-tap → toggles the active app's named fullscreen mode (whole display, no border/gaps). Routes via dock IPC fullscreen(), which targets Hyprland.activeToplevel.address — NOT hyprctl on "active window" (the tap focuses the shell).
    • swipe updock IPC swipeUp (reveals the dock above the pill).
    • swipe downdock IPC swipeDown (dismiss).
  • No keyboard on the pill. OSK = 3-finger hyprgrass swipe only.

Dock (modules/ii/dock/Dock.qml)

  • On WlrLayer.Overlay so the pill 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 pill-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 a 32px pill strip at the bottom visually and in its layer-shell input mask, so the dock cannot intercept pill touches.
  • Bar height is content-driven: the window sizes itself to the button row (64px buttons) + row margin + pill strip; 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 pill uses this.
  • maximized = keeps the normal workspace layout margins.