max / alloy
- Co-Authored-By
- Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 file changed,
+15 insertions,
-1 deletion
| @@ -45,9 +45,23 @@ | |||
| 45 | 45 | - The focus ring is `border-strong`, never accent. Failed-auth state may *temporarily* color the status text in `accent-error`, per the accent-on-text rule in [TOKENS.md](../../docs/TOKENS.md#accent-on-surface-text-rule). The password field's border does **not** flip to accent. | |
| 46 | 46 | - The lockscreen runs at `surface` tier. The password field sits on `surface-raised`. No popovers, no overlays — there is nowhere for an overlay to go on a lockscreen. | |
| 47 | 47 | ||
| 48 | + | ## Architecture | |
| 49 | + | ||
| 50 | + | The lockscreen does **not** use `eframe`. eframe drives Wayland through winit, which opens its own `wl_display` connection — that connection can't share state with whatever owns the session lock, and the session lock has to be owned by the same client that owns the surfaces it draws into. So alloy_lockscreen owns its Wayland connection directly via `smithay-client-toolkit` and drives egui via `egui_glow` on raw GL contexts (one per output). | |
| 51 | + | ||
| 52 | + | Practically: a small render loop pulls Wayland events from SCTK's `calloop` source, feeds keyboard/pointer events into an `egui::Context`, runs the egui pass, and submits the painted output through `egui_glow` to the GL context bound to each `ExtSessionLockSurfaceV1`. The alloy_ui crate is consumed exactly as in the showcase example — `apply_alloy_visuals` + primitives — only the host loop differs. | |
| 53 | + | ||
| 54 | + | ## Stack picks | |
| 55 | + | ||
| 56 | + | | Layer | Pick | Why | | |
| 57 | + | |---|---|---| | |
| 58 | + | | Wayland client | **`smithay-client-toolkit`** | First-class `session_lock` module encodes ext-session-lock-v1's lifecycle (must wait for `locked`, must `unlock` before drop) as types. Upstream `examples/session_lock.rs` is a working starting point. Multi-maintainer Smithay org vs wayrs's single maintainer. Dep-tree premium (~20 crates over wayrs) doesn't matter for a compile-once binary. | | |
| 59 | + | | egui rendering | **`egui` + `egui_glow`** (not `eframe`) | We need to own the Wayland connection, which means we can't use winit (which eframe wraps). egui_glow lets us submit egui paint to GL contexts we manage. | | |
| 60 | + | | GL context | **`glutin`** (or `glow` directly if SCTK exposes EGL helpers) | Decision deferred until first protocol code lands; pick after seeing what SCTK gives us for EGL surface creation. | | |
| 61 | + | ||
| 48 | 62 | ## Open questions blocking implementation | |
| 49 | 63 | ||
| 50 | - | 1. **Wayland protocol crate.** `wayrs-client` (lighter, async-ergonomic, smaller dep tree, newer), `smithay-client-toolkit` (canonical, larger, more battle-tested), or raw `wayland-client` (control, more code). Decision criterion: what gives us a clean ext-session-lock-v1 binding with the smallest stable dep surface. To be resolved before any Wayland code lands. | |
| 64 | + | 1. ~~**Wayland protocol crate.**~~ Resolved: smithay-client-toolkit. See above. | |
| 51 | 65 | 2. **PAM crate.** `pam` (canonical bindings, may be stale), `pam-client` (newer, more ergonomic), or vendoring a thin FFI ourselves. PAM is a small enough API surface that vendoring is reasonable if no current crate is well-maintained. | |
| 52 | 66 | 3. **Process model.** Single-process binding all outputs, or one process per output. Single-process is simpler and matches how swaylock works; one-process-per-output gets us isolation if PAM blocks. Default: single-process. | |
| 53 | 67 | 4. **Recovery path.** If the lockscreen process crashes while holding the session lock, the compositor stays locked and the user is stranded. ext-session-lock-v1 has explicit semantics for this; document the chosen recovery path (compositor-side fallback, watchdog, intentional crash-to-greeter) before shipping. |