mirror of github.com/Breadway/breadlock
Find a file
Breadway bffa521f47
All checks were successful
Mirror to GitHub / mirror (push) Successful in 1s
Build and publish package / package (push) Successful in 2m43s
Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal)
Pulls the fix for panels turning brown/off-hue when pywal extracts a light
or muddy background from the wallpaper — background/surface now stay BOS's
fixed dark constants regardless of what the wallpaper looks like.
2026-07-03 22:51:20 +08:00
.forgejo/workflows CI: add Forgejo package build + GitHub mirror workflows 2026-07-03 13:44:53 +08:00
breadgreet Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal) 2026-07-03 22:51:20 +08:00
breadlock Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal) 2026-07-03 22:51:20 +08:00
breadlock-ui Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal) 2026-07-03 22:51:20 +08:00
packaging Initial commit 2026-07-03 13:37:31 +08:00
.gitignore Initial commit 2026-07-03 13:37:31 +08:00
bakery.toml Initial commit 2026-07-03 13:37:31 +08:00
breadgreet.example.toml Initial commit 2026-07-03 13:37:31 +08:00
breadlock.example.toml Initial commit 2026-07-03 13:37:31 +08:00
Cargo.lock Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal) 2026-07-03 22:51:20 +08:00
Cargo.toml Bump bread-theme to v0.2.10 (fixed dark background/surface, accent-only pywal) 2026-07-03 22:51:20 +08:00
LICENSE Initial commit 2026-07-03 13:37:31 +08:00
README.md Initial commit 2026-07-03 13:37:31 +08:00

breadlock

Session locker and graphical greetd greeter for Hyprland on Wayland — the bread-ecosystem replacement for hyprlock and the TUI greeter (tuigreet) BOS currently ships.

Two binaries, one workspace:

  • breadlock — locks the already running Hyprland session via ext-session-lock-v1. Drop-in for hyprlock.
  • breadgreet — a graphical greeter that speaks greetd's own IPC protocol (the same architecture as gtkgreet/regreet). greetd keeps owning PAM auth, VT switching, and session launching; breadgreet only draws the login UI and relays the conversation. This is a deliberate choice over reimplementing a display manager from scratch — greetd is already installed and battle-tested.

Both use bread-theme for palette loading, matching the rest of the bread* ecosystem (breadbar, breadbox, bos-settings).

Architecture

breadlock/
├── breadlock-ui/   shared: bread-theme wrapper, TOML config, .desktop parsing,
│                    software-rendering primitives (tiny-skia + cosmic-text,
│                    behind the "paint" feature — only breadlock needs them)
├── breadlock/       the locker (SCTK + PAM)
└── breadgreet/      the greeter (GTK4 + relm4 + greetd_ipc)

breadlock

  • Protocol: ext-session-lock-v1 via smithay-client-toolkit — GTK has no session-lock support, so this is a raw Wayland client, not a layer-shell surface like breadbar.
  • Rendering: fully software — tiny-skia composites each frame (background, rounded password pill, clock, status line) into a wl_shm buffer; cosmic-text shapes and rasterizes text (loads "Varela Round" by family name). No EGL/GL.
  • Background: a solid palette color or a static PNG (cover-fit). Live blur-of-desktop (hyprlock-style) is a v2 follow-up — it needs a wlr-screencopy capture (libwayshot is the right crate when this gets picked up); background.blur = true is accepted today but just logs a warning.
  • Auth: pam-client2 against the breadlock PAM service (packaging/pam.d/breadlock, installed to /etc/pam.d/breadlock by the package). Runs on its own OS thread — libpam's conversation callback is blocking FFI — and reports back through a calloop::channel registered on the render loop.

breadgreet

  • Protocol: greetd_ipc (greetd's own crate) over the Unix socket at $GREETD_SOCK: CreateSession → answer each AuthMessage via PostAuthMessageResponseStartSession hands the resolved session command to greetd, which execs it and owns the VT switch away.
  • UI: GTK4 + relm4, matching breadbar's stack — without gtk4-layer-shell. greetd hosts the greeter under a single-client kiosk compositor (cage -s), which already fullscreens its one client, so layer-shell's multi-surface/anchor semantics don't apply. Confirmed against ReGreet's real dependency list, which has no layer-shell dependency either.
  • Sessions: scans /usr/share/wayland-sessions and /usr/share/xsessions for .desktop entries and auto-selects the configured default (or the only one found). BOS ships one session today, so there's no picker UI in v1 — a natural v2 addition if that changes.

Config

Copy breadlock.example.toml to ~/.config/breadlock/breadlock.toml and breadgreet.example.toml to /etc/greetd/breadgreet.toml (or ~/.config/breadgreet/breadgreet.toml for local testing under a normal session — breadgreet checks the system path first since it typically runs as the dedicated greeter user). Every field is optional; both binaries run with sensible defaults and no config at all.

Building

cargo build --release --bin breadlock --bin breadgreet
cargo test --workspace

Requires GTK4 (≥ 4.12), libxkbcommon, and PAM development headers. On Arch:

sudo pacman -S gtk4 wayland libxkbcommon pam rust cargo

breadlock-auth-check is a third, dev-only binary in the breadlock package (see Verification below) — not installed by the package, build it explicitly with cargo build --bin breadlock-auth-check if you need it.

Packaging

packaging/arch/PKGBUILD builds and installs both binaries plus /etc/pam.d/breadlock. bakery.toml is the bread-ecosystem package index entry.

Not included, by design: this repo does not touch /etc/greetd/config.toml, install a lock keybind, or wire up hypridle. Once packaged, wiring BOS to actually use these binaries means:

# /etc/greetd/config.toml — replace the current tuigreet line
[default_session]
command = "cage -s -- breadgreet"
# hyprland.conf
bind = SUPER, L, exec, breadlock

That's a separate, later BOS task — deliberately kept out of this change so the existing tuigreet login path stays untouched and available as a fallback while these binaries are tested.

Verification (why this is safe to test without a lockout risk)

  1. PAM logic in isolation first: cargo run --bin breadlock-auth-check exercises the exact PAM flow breadlock uses, against a typed password, with no Wayland surface at all. A bad /etc/pam.d/breadlock just prints an error here — it can never lock a session.
  2. Locker rendering/lock lifecycle nested, never against the live session: run breadlock inside a nested Hyprland instance or under cage -- breadlock. ext-session-lock-v1 only ever affects the compositor instance the client is connected to (scoped to $WAYLAND_DISPLAY), so a nested lock can never lock the real outer session. Verify the full type-password → PAM check → unlock cycle there, including the wrong-password path, before ever binding a real keybind.
  3. If testing against a live session: keep a second TTY or SSH session open the whole time. Killing the breadlock process is not a safe unlock path — per the protocol, an abnormally-terminated lock client is expected to leave the compositor still locked. The real recovery path is "kill it, then use the second session to restart Hyprland or switch VT."
  4. breadgreet: cargo test -p breadgreet runs the greetd_ipc framing/state-machine tests against a mock Unix-socket server — no real greetd or PAM involved. Manual testing against a real greetd should happen on a disposable VT, leaving the existing tuigreet config on VT1 untouched as a fallback.

License

MIT