diff options
| author | srdusr <[email protected]> | 2024-10-30 23:52:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-10-30 23:52:00 +0200 |
| commit | 9748bca006cd2498c4c0f2730d8789c667bda52b (patch) | |
| tree | f917af35cd32f9745c940253f2400ab0b92f0b0a /crates/core/src | |
| parent | 3509cf6127185d9fed5a63ceca18a003213a20d7 (diff) | |
| download | srdwm-9748bca006cd2498c4c0f2730d8789c667bda52b.tar.gz srdwm-9748bca006cd2498c4c0f2730d8789c667bda52b.zip | |
Add srdwm's own native session-lock screen (blur, PAM auth)
A real ext-session-lock-v1 implementation drawn by the compositor
itself, not a hand-off to an external locker process: a live-blurred
background, PAM authentication on a background thread, and its own
config surface (lock_config.rs) rather than hardcoded appearance.
Diffstat (limited to 'crates/core/src')
| -rw-r--r-- | crates/core/src/lock_config.rs | 54 | ||||
| -rw-r--r-- | crates/core/src/manager/lock.rs | 51 |
2 files changed, 105 insertions, 0 deletions
diff --git a/crates/core/src/lock_config.rs b/crates/core/src/lock_config.rs new file mode 100644 index 0000000..7edeeb5 --- /dev/null +++ b/crates/core/src/lock_config.rs @@ -0,0 +1,54 @@ +//! Configuration for srdwm's own session-lock UI +//! (`crates/wayland/src/native_lock.rs` does the actual rendering/input; +//! this is just the live-configurable knobs, same split `ThemeConfig` +//! already has between itself and the decoration-rendering code that +//! reads it). +//! +//! Not folded into `ThemeConfig` itself: that struct is `Copy` (read by +//! value on every decoration redraw), and a couple of these fields +//! (`fail_message`) need to be `String`/heap-allocated, which would force +//! every `ThemeConfig` copy to become a clone instead - cheap enough +//! given how rarely lock config is actually read (once per lock, not once +//! per frame), but no reason to pay that cost on every titlebar repaint +//! too. + +/// Read from `theme.lock.*` in `crates/srdwm/src/main.rs`, and (like +/// `ThemeConfig`) live-settable via `srd set` - see `crates/platform/src/ +/// ipc.rs`'s `lock_*` keys. +#[derive(Debug, Clone, PartialEq)] +pub struct LockConfig { + pub box_bg: (u8, u8, u8), + pub box_border: (u8, u8, u8), + pub text_color: (u8, u8, u8), + pub error_color: (u8, u8, u8), + pub corner_radius: u32, + /// Box-blur radius applied to the captured pre-lock screen content, in + /// pixels - see `native_lock.rs`'s `box_blur` for why this is a box + /// blur, not a true Gaussian one. `0` disables blurring entirely + /// (just the captured content, unmodified) rather than being clamped + /// up to some minimum - a legitimate configuration for a low-power + /// device, not a mistake to guard against. + pub blur_radius: u32, + /// Drawn once per character typed, never the character itself. + pub dot_char: char, + pub show_caps_lock: bool, + pub show_failed_attempts: bool, + pub fail_message: String, +} + +impl Default for LockConfig { + fn default() -> Self { + Self { + box_bg: (0x2e, 0x34, 0x40), // Nord dark, matches ThemeConfig::titlebar_bg + box_border: (0x88, 0xc0, 0xd0), // Nord blue, matches ThemeConfig::default_border_color + text_color: (0xec, 0xef, 0xf4), // Nord light + error_color: (0xbf, 0x61, 0x6a), // Nord red, matches the theme's own `error` colour + corner_radius: 10, + blur_radius: 20, + dot_char: '\u{25cf}', // "●" + show_caps_lock: true, + show_failed_attempts: true, + fail_message: "Wrong password".to_string(), + } + } +} diff --git a/crates/core/src/manager/lock.rs b/crates/core/src/manager/lock.rs new file mode 100644 index 0000000..07735c6 --- /dev/null +++ b/crates/core/src/manager/lock.rs @@ -0,0 +1,51 @@ +//! Requesting srdwm's own session lock. Split out of the original single +//! `manager.rs` - see `super` (`mod.rs`) for `WindowManager`'s field +//! definitions; everything here is plain `impl WindowManager` methods. + +use super::*; + +impl WindowManager { + /// Queues a request for the backend to enter its own lock UI - the + /// only caller today is the IPC `"lock"` dispatch, the compositor- + /// agnostic side of `srd dispatch lock`. Core cannot lock the screen + /// itself (that's real rendering/input-routing, backend-owned); see + /// `lock_requested`'s own doc comment for why this has to cross the + /// core/backend boundary as a queued request rather than a direct call. + /// + /// Idempotent by construction (a plain `bool`, not a counter): asking + /// to lock twice before the backend's next poll drains it is exactly + /// as locked as asking once. + pub fn request_lock(&mut self) { + self.lock_requested = true; + } + + /// Takes the current lock request, if any, leaving none pending. The + /// backend calls this once per poll, same as `drain_output_position_ + /// requests`. + pub fn drain_lock_request(&mut self) -> bool { + std::mem::take(&mut self.lock_requested) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn drain_lock_request_is_true_once_then_false() { + let mut wm = WindowManager::new(); + assert!(!wm.drain_lock_request(), "nothing requested yet"); + wm.request_lock(); + assert!(wm.drain_lock_request(), "must report the pending request"); + assert!(!wm.drain_lock_request(), "must not report the same request twice"); + } + + #[test] + fn requesting_lock_twice_before_a_drain_is_still_just_one_pending_request() { + let mut wm = WindowManager::new(); + wm.request_lock(); + wm.request_lock(); + assert!(wm.drain_lock_request()); + assert!(!wm.drain_lock_request()); + } +} |