Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/HOW-IT-WORKS.md

3.6 KiB

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.