Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/REFERENCE-EXTRACTION.md

9.5 KiB
Raw Blame History

Lock, idle, and wallpaper reference extraction

This is a design extraction, not a dependency list. Souveraine should retain one session authority across desktop, laptop, and phone; form factor changes the chosen layout and cards, never the meaning of lock, idle, or auth.

Migration rule: ii is a temporary compatibility substrate, not a source of new architecture. New behavior belongs in surfaces/quickshell under a Souveraine-owned module or service. Borrowed code is replaced deliberately, with the replacement's contract documented before the borrowed file leaves.

What the active shell has today

The phone lock has a credential keypad, fingerprint attempt, battery state, and guarded power actions. It does not yet have lockscreen media, notifications, timers, weather, calls, agent output policy, a staged idle coordinator, or a real sleep-inhibitor backend. Idle.qml currently controls hypridle because the tested invisible Wayland idle inhibitor is not honoured on the Pixel 3 compositor build.

That is a sound small base. It is not yet a phone-grade lock surface.

Ideas to extract

Source Keep Do not inherit
Sailfish/Lipstick lockscreen A lock screen as layered/pannable content: glance surface, credential surface, and event surface. Wake/display-off are separate from lock. Its device-specific Lipstick and DeviceLock plumbing; source provenance must be audited before copying.
Glacier Home A compact MPRIS card with capability-gated previous/play/next controls; media is loaded only if a player exists. Clock, media, keypad, and notifications are separate components. Its older Nemo/Amber APIs and visual code verbatim unless copyright notices travel with it.
DankMaterialShell Independent idle monitors for dim/DPMS/lock/suspend, explicit re-arming, AC-vs-battery thresholds, and a wake monitor after screen-off. Treating its shell state as authority or blindly importing its settings model.
ii/iNiR MPRIS card mechanics, downloaded artwork, palette adaptation, and image "least busy region" placement. ii already calculates content placement against wallpaper pixels. The current one-file wallpaper assumption and arbitrary widget dimensions.
Ambxst Screen capture at lock, short-lived credential handling, failure lockout feedback, and listening to logind Lock/PrepareForSleep events. Its AGPL code, polling axctl layer, and its separate lockscreen authority. Concepts only.

DankMaterialShell and iNiR are MIT; Glacier carries MIT/BSD notices. Ambxst is AGPL and Vast is GPL. Do not copy from the latter two into this repository without intentionally accepting their licence obligations. Sailfish files in the local research extraction need per-file provenance review before reuse.

One lock surface, composable cards

The lock surface should be a host with slots rather than a new shell for each device:

WlSessionLockSurface
 └─ LockSurfaceHost
     ├─ glance slot       clock · date · battery · weather
     ├─ continuity slot   timer · ongoing call · navigation · media transport
     ├─ event slot        notification summaries / previews
     ├─ credential slot   PIN/password/fingerprint PAM conversation
     └─ ambient-agent slot  explicitly safe question/answer cards

The host chooses a layout profile:

Profile Layout
phone portrait One vertical glance surface; a swipe/press brings up credentials; continuity cards occupy the lower third.
laptop Center credentials with a side or lower card rail; multi-monitor cards remain local to their screen.
desktop Center credentials and a sparse, large-screen card rail; no phone gesture assumptions.

Each card declares a tier and a lock-surface visibility policy. This prevents an attractive card from silently becoming a data leak.

Tier Suitable cards Rule
ambient clock, battery, weather, timer, transport buttons, an ongoing-call indicator no user data beyond the explicitly permitted setting
personal track title/art, notification body, calendar title, agent conversation, call identity hidden until unlock unless the user opts that field into ambient
step-up send/reply/delete/purchase/unlock a physical thing never performed by a card tap alone; needs a recent step-up grant

An ambient agent is not a diluted personal agent. It has a separate tool and memory allowlist, cannot read conversation history or sensors, and its output is labelled ambient. If the lock starts while a personal response streams, the host immediately withdraws it.

Idle is a transition graph, not a timer

The useful DMS extraction is the vocabulary and re-arm discipline. The actual authority remains Wayland idle protocols plus logind:

active ─idle timeout→ dimmed ─timeout→ lock-requested
                                      │
                     WlSessionLock.secure
                                      ↓
                                lock-secure ─timeout→ display-off
                                      │                     │
PrepareForSleep(true) ─────────────────────────────────────┘
                                      ↓
                                suspending → asleep → waking → active

Input can cancel dimming and display-off before lock. It cannot cancel an already secure lock; credentials do that. Every transition has an event source and an observable result. screenLocked is the request; screenLockSecure is the compositor acknowledgement.

The implementation sequence is:

  1. Add one IdleCoordinator that owns the staged state and form-factor thresholds. It consumes native IdleMonitor events when verified on the target; the Pixel can retain the hypridle adapter behind that interface.
  2. Add a logind event watcher for this session's Lock and the manager's PrepareForSleep signal.
  3. Hold a delay-mode sleep inhibitor while the shell is running. Release it only after the Wayland lock is secure; re-acquire it on wake. Measure the actual logind delay budget on the Pixel 3.
  4. Make idle, sleep, logout, and user-switch explicit inhibitor kinds. Only expose a kind after it owns a real backend. idle is the sole implemented kind today.

Wallpaper should be an asset, not a path

The current background path gives every output the same image and asks crop to solve incompatible aspect ratios. A downloaded landscape image consequently loses its subject on the phone. Preserve originals, but track a portable asset record:

id, originalPath, origin, licence, palette,
focalPoint(x,y), safeRegions[],
variants: { landscape, portrait, square },
previewPath, generatedAt

Selection order for a screen is:

  1. Use an explicit per-device assignment when the user set one.
  2. Select a sufficiently close aspect-ratio variant.
  3. Crop a derived local variant around focalPoint while preserving a safeRegion; never overwrite the original.
  4. Fall back to a blurred/palette background with the image contained, rather than crop the only meaningful part away.

ii's existing least-busy-region analysis is useful twice: place a clock/card where it does not cover the subject, and propose an initial safe region. However, it must run against the actual output crop and card dimensions, not a fixed 300×300 desktop widget. A manual focal-point editor is the escape hatch; an analyser may propose, never silently decide.

For the lock surface, prefer a frozen screencopy or an already-derived local variant over downloading or decoding a remote wallpaper at lock time. Locking must remain instant and work offline.

Proposed Souveraine map

modules/common/functions/Session.qml        lifecycle verbs + IPC projection
services/SessionEvents.qml                  logind Lock / PrepareForSleep ingress
services/IdleCoordinator.qml                transition graph + target adapters
services/LockContentPolicy.qml              card tier / field visibility decisions
modules/ii/lock/LockSurfaceHost.qml         shared card host
modules/ii/lock/cards/                      Clock · Media · Notifications · Continuity · AmbientAgent
services/StepUpAuth.qml                     independent PamContext + expiring grants
services/WallpaperAssets.qml                asset records, variants, safe regions

None of these are separate session managers. They are consumers of the single session lifecycle and its state projection.

Build order

  1. Truth before visuals: logind event ingress, delay inhibitor, and IdleCoordinator with a visible transition log. [done — SessionEvents.qml, delay inhibitor in SessionEvents, IdleCoordinator extended with sleep states]
  2. First lock cards: clock/date, battery, transport-only MPRIS. Add the metadata privacy switch before title/artist/artwork.
  3. Continuity: timers, ongoing call, navigation, and notification summary cards with per-field redaction.
  4. Trust: ambient-agent allowlist, lock-time response redaction, then StepUpAuth and action-family grants. [partially done — StepUpAuth.qml built, minTier wiring and ambient-agent allowlist remain]
  5. Wallpaper assets: per-device assignments, focal-point editor, derived portrait/landscape variants, and crop-aware card placement.

The first useful vertical slice is therefore not a huge lockscreen redesign: one shared LockSurfaceHost, a transport-only media card, a real staged idle state projection, and a wallpaper asset descriptor. It proves the architecture on both shapes without committing personal data to the lock surface.