A modern Wayland idle manager that knows when to step back.
Keep your session in perfect balance—automatically preventing idle when it matters, allowing it when it doesn't.
Features • Installation • Quick Start • Architecture • CLI Usage • Compositor Support • Contributing
Stasis is not a simple timer-based screen locker.
It is a context-aware, event-driven idle manager built around explicit state and decisions.
- 🧠 Smart idle detection with sequential, configurable timeouts
- 🎵 Media-aware idle handling
- Optional audio-based detection
- Differentiates active, paused, and muted streams
- 🚫 Application-specific inhibitors
- Prevent idle when selected apps are running
- Regex-based matching supported
- ⏸️ Wayland idle inhibitor support
- Honors compositor and application inhibitors
- 🛌 Laptop-aware power handling
- Optional D-Bus integration for lid events, suspend/resume, and session inhibit traffic
- ⚙️ Flexible action plans
- Startup steps, sequential steps, instant actions, resume hooks
- 🔁 Manual idle inhibition
- Toggle idle on/off via CLI or status bars (Waybar-friendly)
- 📝 Clean configuration
- Uses the expressive RUNE configuration language
- ⚡ Live reload
- Reload configuration without restarting the daemon
- 📜 Structured logging
- Powered by eventline for journaling and traceable logs
Stasis is built around a deterministic, event-driven state machine.
There are no hidden timers, background polling loops, or implicit behavior.
External signals
↓
Event (pure data)
↓
Manager (decision logic)
↓
State (authoritative)
↓
Actions (declarative)
↓
Services (side effects)
Design principles:
- State is authoritative
- Events are pure data
- Managers decide, services act
- Side effects are isolated
- Data flows strictly forward
yay -S stasis
yay -S stasis-git
nix build 'github:saltnpepper97/stasis#stasis'
swaylock PAM configuration
If you use swaylock as your screen locker on NixOS, you must add the following to your NixOS configuration or swaylock will lock the screen but never accept your password to unlock it:
security.pam.services.swaylock = {};Dependencies:
- rust / cargo (build)
- wayland (runtime)
- dbus (runtime, strongly recommended; required for full feature set)
- used for session inhibit handling (
enable_dbus_inhibit) - used for portal/browser inhibit traffic
- used for lid events and suspend/resume integration
- used for session inhibit handling (
- pulseaudio or pipewire-pulse (runtime, recommended for media/call detection via
pactl) - libnotify (optional, desktop notifications)
Build & install:
git clone https://github.com/saltnpepper97/stasis
cd stasis
cargo build --release --locked
sudo install -Dm755 target/release/stasis /usr/local/bin/stasis
Warning
Screen lockers must not be configured to daemonize.
Stasis tracks lock state by waiting for the screen locker process to exit. If your locker is set to daemonize (e.g. swaylock -f / daemonize = true, or a similar option in other lockers), it will detach from stasis immediately and stasis will interpret this as the screen already being unlocked — causing it to loop back to the first step of your plan.
You can confirm this is the issue with stasis dump — if the resume step fires almost immediately after lock, your locker is daemonizing.
Option 1 — Don't daemonize (simplest): Remove daemonize = true or the -f flag from your screen locker config.
Option 2 — Use enable_loginctl mode: Enable stasis's loginctl mode so it tracks lock state via logind signals instead of process lifetime, then use a wrapper script:
#!/usr/bin/env bash
loginctl lock-session
swaylock -fImportant
D-Bus session startup is required for full D-Bus features.
If you want enable_dbus_inhibit and other session-bus driven behavior to work reliably, start your compositor within a real D-Bus session (for example niri-session, dbus-run-session, or your compositor/distribution's recommended session launcher).
If the compositor is not running in a proper session, inhibit monitoring may not activate.
Start the daemon:
stasis
Full quick start guide, configuration examples, and documentation:
https://saltnpepper97.github.io/stasis-site/
Stasis supports inhibit messages from session D-Bus, including:
org.freedesktop.ScreenSaverInhibit/UnInhibitorg.gnome.SessionManagerInhibit/Uninhibitorg.freedesktop.portal.Inhibit(Inhibit/CreateMonitor) with release viaorg.freedesktop.portal.Request.Close
Config key:
enable_dbus_inhibit true|false(default true)
Use this when you want Stasis to honor session-bus inhibit requests from browsers, Steam, portal clients, and similar apps.
Important separation:
enable_dbus_inhibitis for browser/app inhibit traffic coming from session D-Bus.monitor_mediais only for non-browser media/audio state.- Browser media inhibit is not handled by
monitor_media; it is handled by D-Bus inhibit monitoring.
stasis info [--json]
stasis pause [for <duration> | until <time>]
stasis resume
stasis toggle-inhibit
stasis trigger <step|all>
stasis list actions
stasis list profiles
stasis profile <name|none>
stasis reload
stasis stop
Stasis integrates with each compositor's available IPC and standard Wayland protocols.
| Compositor | Support Status | Notes |
|---|---|---|
| Niri | ✅ Full Support | Tested and working perfectly |
| Hyprland | ✅ Full Support | Native IPC integration |
| labwc | Process-based fallback | |
| River | Process-based fallback | |
| Your Favorite | 🤝 PRs Welcome | Help us expand support |
These compositors have IPC limitations that affect window enumeration.
- Stasis falls back to process-based detection
- Regex patterns may need adjustment
- Enable verbose logging to inspect detected applications
Thank you for helping improve Stasis!
Guidelines:
- Bug reports and feature requests must start as issues
- Packaging and compositor support PRs are welcome directly
- Other changes should be discussed before submission
If you find this project useful, consider sponsoring its development.
GitHub Sponsors helps ensure continued maintenance, faster bug fixes, and long-term improvements.
➡ https://github.com/sponsors/saltnpepper97
Released under the GPL-3.0 License.
Built with ❤️ for the Wayland community
Keeping your session in perfect balance between active and idle
