9.5 KiB
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:
- Add one
IdleCoordinatorthat owns the staged state and form-factor thresholds. It consumes nativeIdleMonitorevents when verified on the target; the Pixel can retain the hypridle adapter behind that interface. - Add a logind event watcher for this session's
Lockand the manager'sPrepareForSleepsignal. - 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.
- Make
idle,sleep,logout, anduser-switchexplicit inhibitor kinds. Only expose a kind after it owns a real backend.idleis 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:
- Use an explicit per-device assignment when the user set one.
- Select a sufficiently close aspect-ratio variant.
- Crop a derived local variant around
focalPointwhile preserving asafeRegion; never overwrite the original. - 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
- Truth before visuals: logind event ingress, delay inhibitor, and
IdleCoordinatorwith a visible transition log. [done — SessionEvents.qml, delay inhibitor in SessionEvents, IdleCoordinator extended with sleep states] - First lock cards: clock/date, battery, transport-only MPRIS. Add the metadata privacy switch before title/artist/artwork.
- Continuity: timers, ongoing call, navigation, and notification summary cards with per-field redaction.
- Trust: ambient-agent allowlist, lock-time response redaction, then
StepUpAuthand action-family grants. [partially done — StepUpAuth.qml built, minTier wiring and ambient-agent allowlist remain] - 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.