- Implement Wayland pointer handling for interactive media buttons.
- Add pure-Rust SVG loading via resvg.
- Refactor status indicators for consistent icon and layout handling.
When monitors are powered off (e.g. via niri power-off-monitors or
physical power switches), niri destroys and re-advertises the Wayland
outputs as they come back. Previously all three OutputHandler callbacks
were no-ops, causing two bugs:
- new_output: no lock surface was created for outputs that appeared
after the initial lock, so the slowest monitor to wake up would show
the compositor's red fallback instead of the lock screen.
- output_destroyed: stale LockedSurface, SessionLockSurface, output,
and captured_background entries accumulated for gone outputs.
Fix new_output to create a lock surface (and register it with the lock
manager) whenever a new output appears while the session is locked.
Fix output_destroyed to remove the corresponding entries from
lock_surfaces, lock_manager.surfaces, outputs, and
captured_backgrounds, keeping all parallel vecs in sync. Add
LockManager::remove_surface_by_output to support this, returning the
removal index so lock_surfaces can be updated with the same index.
The all-monitors-off scenario (all outputs destroyed simultaneously)
is handled naturally: the vecs are emptied and repopulated as each
monitor fires new_output on wake.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ext-session-lock-v1 protocol does not guarantee a `finished` event
after the client calls `unlock_and_destroy` — that event is only sent
when the compositor independently terminates the lock. Waiting for it
caused rustlock to hang forever on niri (and any spec-compliant
compositor).
The previous attempt to fix this by setting exit=true immediately broke
unlocking because the while loop stopped calling event_loop.dispatch,
leaving the unlock_and_destroy bytes unflushed in the client-side
Wayland send buffer and never reaching the compositor.
Store the Connection in WaylandLock and explicitly call conn.flush()
after session_lock.unlock(), ensuring the unlock request is sent before
we exit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The users crate (RUSTSEC-2025-0040) has an unfixable vulnerability.
Replace it with the maintained whoami crate for getting the current
username. Also remove metrics.yml workflow as it provided no value.
- Add caps lock ring color change when caps lock is enabled (matching swaylock-effects)
- Add configurable caps lock colors: ring, text, key highlight, backspace highlight
- Add show_caps_lock_text config option (enabled by default)
- Add keyboard layout display with show_keyboard_layout option (disabled by default)
- Change keyboard_layout from u32 to String for proper display
- Add rust-cache to CI and dbus-1-dev dependency
- Add new system.rs module for system monitoring via D-Bus:
- Battery status (UPower)
- Media player controls and metadata (MPRIS)
- WiFi/Bluetooth status (NetworkManager)
- Keyboard layout tracking
- Add media key support (XF86 Play/Pause/Next/Prev)
- Add function keys F1-F3 for Suspend/Reboot/PowerOff
- Replace deprecated timer.rs with async system management
- Add GitHub Actions CI/CD workflows (CI + Release)
- Update dependencies and add optional networking feature
- Add pending_screenshots counter to WaylandLock
- Set pending_screenshots = output_count in locked() if screenshots enabled
- Timer skips rendering while pending_screenshots > 0
- Decrement pending_screenshots on Ready or Failed events
- When all screenshots done, timer starts rendering
- This ensures screenshots capture the desktop, not the lock UI
Fixes grey screenshot issue caused by capturing lock surface itself.
Matches swaylock-effects behavior: wait for screenshots before initial render.
- Timer callback: log each tick and commit status
- LockedSurface::update(): log background presence, fade alpha, feedback states
- Renderer::render(): log background drawing and fade alpha
- Ready event: log background set confirmation
These logs will help diagnose why screenshots are not displaying.
The conversion functions were producing big-endian ARGB (A,R,G,B) but
Cairo's ARGB32 on little-endian systems expects B,G,R,A byte order.
This caused screenshots to appear completely corrupted (likely black or
solid color).
Fixed both convert_xbgr8888_to_argb32 and convert_xrgb8888_to_argb32:
- Xbgr8888: source [R,G,B,X] -> dest [B,G,R,A=255]
- Xrgb8888: source [B,G,R,X] -> dest [B,G,R,A=255]
Added detailed comments explaining memory layouts and conversion logic
to prevent future regressions.
This should make screenshots display correctly.
- Fixed brace mismatch and duplicate code in screenshot.rs
- Increased SHM pool size to 256MB for high-res displays
- Corrected wlr-screencopy protocol usage: send copy request in Buffer event
- Fixed background handling: set_background now updates LockedSurface.background
- Removed dummy background creation; screenshots set when ready
- Added format conversion for Xbgr8888 and Xrgb8888 to ARGB32
- Proper Y-inversion handling based on flags
The lock screen now displays captured screenshots as background.
Screenshots are taken immediately after lock, before UI is shown.
Matches swaylock-effects behavior: lock appears first, then screenshot
applies when ready (no blocking).
Fixes: black/red screen issues, screenshot not displaying.