Skip to main content

max / alloy_tui

Lockscreen: pull SCTK, pam-sys, tokio, egui_glow into the workspace Step 1 of the implementation pass: the dep tree exists, the workspace builds clean on macOS, and the alloy-lock binary now boots through tokio's current-thread runtime and reports a platform-aware stub status. - Workspace Cargo.toml: tokio (rt + macros + sync + time), smithay-client-toolkit 0.20, pam-sys 0.5 (stable line, matches greetd; the 1.0.0-alpha is dropped on purpose), egui_glow 0.34. - crates/alloy_lockscreen/Cargo.toml: tokio depended on unconditionally; SCTK, pam-sys, egui, egui_glow gated behind cfg(target_os = "linux") so non-Linux builds resolve. alloy_ui is unconditional (egui's a workspace-portable dep for tokens). - main.rs: #[tokio::main(flavor = "current_thread")] entry point that prints version, target, and lock-state placeholder. Exits non-zero on every platform until real wiring lands so it isn't silently considered "working." README: new "Build" section calls out the Linux runtime requirements (libpam, wayland, EGL/Mesa) and the non-Linux behavior. Next step is the first real Wayland code: copy SCTK's examples/session_lock.rs shape into the crate to prove the protocol binding works on fw13.
Co-Authored-By
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-06-26 19:59 UTC
Signed with PGP, not checked
Commit: 4596470526083add7becc2781ed234c45a29cfa2
Parent: dbe69a7
5 files changed, +107 insertions, -12 deletions
M Cargo.lock +52
@@ -34,6 +34,11 @@
34 34 version = "0.0.0"
35 35 dependencies = [
36 36 "alloy_ui",
37 + "egui",
38 + "egui_glow",
39 + "pam-sys",
40 + "smithay-client-toolkit",
41 + "tokio",
37 42 ]
38 43
39 44 [[package]]
@@ -1585,6 +1590,15 @@
1585 1590 "syn",
1586 1591 ]
1587 1592
1593 + [[package]]
1594 + name = "pam-sys"
1595 + version = "0.5.6"
1596 + source = "registry+https://github.com/rust-lang/crates.io-index"
1597 + checksum = "cd4858311a097f01a0006ef7d0cd50bca81ec430c949d7bf95cbefd202282434"
1598 + dependencies = [
1599 + "libc",
1600 + ]
1601 +
1588 1602 [[package]]
1589 1603 name = "parking_lot"
1590 1604 version = "0.12.5"
@@ -1992,12 +2006,14 @@
1992 2006 checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0"
1993 2007 dependencies = [
1994 2008 "bitflags 2.13.0",
2009 + "bytemuck",
1995 2010 "calloop 0.14.4",
1996 2011 "calloop-wayland-source",
1997 2012 "cursor-icon",
1998 2013 "libc",
1999 2014 "log",
2000 2015 "memmap2",
2016 + "pkg-config",
2001 2017 "rustix 1.1.4",
2002 2018 "thiserror 2.0.18",
2003 2019 "wayland-backend",
@@ -2009,6 +2025,7 @@
2009 2025 "wayland-protocols-misc",
2010 2026 "wayland-protocols-wlr",
2011 2027 "wayland-scanner",
2028 + "xkbcommon",
2012 2029 "xkeysym",
2013 2030 ]
2014 2031
@@ -2130,6 +2147,27 @@
2130 2147 "zerovec",
2131 2148 ]
2132 2149
2150 + [[package]]
2151 + name = "tokio"
2152 + version = "1.52.3"
2153 + source = "registry+https://github.com/rust-lang/crates.io-index"
2154 + checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
2155 + dependencies = [
2156 + "pin-project-lite",
2157 + "tokio-macros",
2158 + ]
2159 +
2160 + [[package]]
2161 + name = "tokio-macros"
2162 + version = "2.7.0"
2163 + source = "registry+https://github.com/rust-lang/crates.io-index"
2164 + checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
2165 + dependencies = [
2166 + "proc-macro2",
2167 + "quote",
2168 + "syn",
2169 + ]
2170 +
2133 2171 [[package]]
2134 2172 name = "toml"
2135 2173 version = "0.8.23"
@@ -2797,6 +2835,17 @@
2797 2835 source = "registry+https://github.com/rust-lang/crates.io-index"
2798 2836 checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b"
2799 2837
2838 + [[package]]
2839 + name = "xkbcommon"
2840 + version = "0.8.0"
2841 + source = "registry+https://github.com/rust-lang/crates.io-index"
2842 + checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9"
2843 + dependencies = [
2844 + "libc",
2845 + "memmap2",
2846 + "xkeysym",
2847 + ]
2848 +
2800 2849 [[package]]
2801 2850 name = "xkbcommon-dl"
2802 2851 version = "0.4.2"
@@ -2815,6 +2864,9 @@
2815 2864 version = "0.2.1"
2816 2865 source = "registry+https://github.com/rust-lang/crates.io-index"
2817 2866 checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
2867 + dependencies = [
2868 + "bytemuck",
2869 + ]
2818 2870
2819 2871 [[package]]
2820 2872 name = "xml-rs"
M Cargo.toml +6
@@ -12,9 +12,15 @@
12 12 [workspace.dependencies]
13 13 egui = { version = "0.34", default-features = false, features = ["default_fonts"] }
14 14 eframe = { version = "0.34", default-features = false, features = ["default_fonts", "glow"] }
15 + egui_glow = { version = "0.34", default-features = false }
15 16 toml = "0.8"
16 17 palette = { version = "0.7", default-features = false, features = ["std"] }
17 18
19 + # Lockscreen-specific
20 + tokio = { version = "1", features = ["rt", "macros", "sync", "time"] }
21 + smithay-client-toolkit = "0.20"
22 + pam-sys = "0.5"
23 +
18 24 [profile.release]
19 25 lto = "thin"
20 26 codegen-units = 1
@@ -14,3 +14,14 @@
14 14
15 15 [dependencies]
16 16 alloy_ui = { path = "../alloy_ui" }
17 + tokio = { workspace = true }
18 +
19 + # Linux-only: the lockscreen binds Wayland (ext-session-lock-v1) and
20 + # authenticates against PAM. The crate stays a workspace member on
21 + # non-Linux so alloy_ui dev work isn't blocked, but the binary's real
22 + # functionality is gated behind these.
23 + [target.'cfg(target_os = "linux")'.dependencies]
24 + smithay-client-toolkit = { workspace = true }
25 + pam-sys = { workspace = true }
26 + egui = { workspace = true }
27 + egui_glow = { workspace = true }
@@ -4,7 +4,17 @@
4 4
5 5 ## Status
6 6
7 - Stub. The crate compiles, depends on `alloy_ui`, and prints a placeholder. Wayland and PAM integration land after the open questions below are resolved.
7 + Stub. The crate compiles, depends on `alloy_ui` + the lockscreen stack (SCTK, pam-sys, tokio, egui_glow), and prints a placeholder. All four open questions about scope/architecture are settled — see below. Wayland and PAM wiring land next.
8 +
9 + ## Build
10 +
11 + Linux-only at runtime. The crate is a workspace member on every platform so `alloy_ui` dev work isn't blocked on macOS, but its Wayland and PAM deps (`smithay-client-toolkit`, `pam-sys`, `egui_glow`) are gated behind `cfg(target_os = "linux")`. Building the lockscreen for real needs:
12 +
13 + - `libpam` runtime + headers (`pam-devel` on Fedora).
14 + - Wayland client libraries (`wayland-devel` on Fedora) and an EGL provider (Mesa).
15 + - GL: a working OpenGL ES 2 / GLES3-capable Mesa driver.
16 +
17 + On non-Linux platforms `cargo build` produces a binary that prints the platform-unsupported message and exits non-zero — useful as a sanity check that the workspace still resolves.
8 18
9 19 ## v1 scope
10 20
@@ -1,14 +1,30 @@
1 - //! Alloy lockscreen — placeholder entry point.
1 + //! Alloy lockscreen — entry point.
2 2 //!
3 - //! Real implementation is pending the Wayland protocol-crate decision
4 - //! (`wayrs-client` vs `smithay-client-toolkit` vs raw `wayland-client`) and the
5 - //! PAM integration. See `README.md` for scope, design call-outs, and the open
6 - //! questions blocking implementation.
3 + //! Real implementation is pending. This stub brings the async runtime up so
4 + //! the dep tree is shaken down and the `#[tokio::main]` framing exists for
5 + //! the protocol and PAM code that will land next.
6 + //!
7 + //! See `README.md` for scope, design decisions, and the build/runtime
8 + //! requirements (Linux + Wayland + PAM).
7 9
8 - fn main() {
9 - eprintln!(
10 - "alloy-lock: not yet implemented. \
11 - See crates/alloy_lockscreen/README.md for the scoped v1 plan."
12 - );
13 - std::process::exit(1);
10 + #[tokio::main(flavor = "current_thread")]
11 + async fn main() {
12 + println!("alloy-lock v{}", env!("CARGO_PKG_VERSION"));
13 +
14 + #[cfg(target_os = "linux")]
15 + {
16 + println!("target: linux");
17 + println!("lock state: not acquired (stub — Wayland and PAM wiring pending)");
18 + std::process::exit(1);
19 + }
20 +
21 + #[cfg(not(target_os = "linux"))]
22 + {
23 + println!(
24 + "target: {} (unsupported — lockscreen is Linux-only)",
25 + std::env::consts::OS
26 + );
27 + println!("lock state: n/a");
28 + std::process::exit(1);
29 + }
14 30 }