β οΈ STASYS - STABLE FORK This is Stasys - a stable fork of Stasis v0.7.0, maintained to preserve brightness restoration and stable media detection. Why this fork exists: Upstream v0.8+ removed automatic brightness restoration and introduced media detection instability. Goal: Keep v0.7.0 stability with selective bug fixes from later versions.
A modern Wayland idle manager that knows when to step back.
Stable Fork of Stasis v0.7.0 β’ Preserving brightness restoration and stable media detection
Features β’ Installation β’ Quick Start β’ Compositor Support β’ Configuration β’ Profiles
Stasys doesn't just lock your screen after a timerβit understands context. Watching a video? Reading a document? Playing music? Stasys detects these scenarios and intelligently manages idle behavior.
- π§ Smart idle detection with configurable timeouts
- π΅ Media-aware idle handling β automatically detects media playback
- π« Application-specific inhibitors β prevent idle when specific apps are running
- βΈοΈ Idle inhibitor respect β honors Wayland idle inhibitor protocols
- π Lid events via DBus β detect laptop lid open/close events
- βοΈ Flexible action system β supports named action blocks and custom commands
- π Regex pattern matching β powerful app filtering with regular expressions
- π Clean configuration β uses the intuitive RUNE configuration language
- β‘ Live reload β update configuration without restarting the daemon
- π‘ Automatic brightness restoration β captures and restores brightness on resume
- Download the appropriate archive from Releases
- Extract
stasysbinary somewhere in your $PATH (ex. .local/bin) - Adjust systemd service accordingly or add
stasysto your DEβs startup menu
Build and install manually:
# Clone and build
git clone https://github.com/Alanon202/stasys
cd stasys
cargo build --release --locked
# Install system-wide
sudo install -Dm755 target/release/stasys /usr/local/bin/stasys
# Or install to user directory
install -Dm755 target/release/stasys ~/.local/bin/stasysA systemd user service file is provided in systemd/stasys.service. Copy it to your systemd user directory:
mkdir -p ~/.config/systemd/user
cp systemd/stasys.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now stasys.serviceEdit the service file if you installed stasys to a different location than /usr/local/bin/stasys.
Stasys requires access to input devices and brightness controls:
sudo usermod -aG input,video $USERLog out and back in for group changes to take effect.
On first run, Stasys automatically generates a default configuration at ~/.config/stasys/stasys.rune. You can also create it manually:
mkdir -p ~/.config/stasys
cp examples/stasys.rune ~/.config/stasys/stasys.runeEdit the configuration to your needs.
# Start the daemon
stasys daemon
# Or use systemd (recommended)
systemctl --user start stasysstasys infoStasys integrates with each compositor's native IPC protocol for optimal app detection and inhibition.
| 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 |
Both River and labwc have IPC protocol limitations:
- Limited window enumeration β Can't get complete window lists via IPC
- Fallback mode β Uses process-based detection (sysinfo) for app inhibition
- Pattern adjustments β Executable names may differ from app IDs
π‘ Tip: When using River or labwc, include both exact executable names and flexible regex patterns in your
inhibit_appsconfiguration.
Stasys uses RUNEβa purpose-built configuration language.
- User config:
~/.config/stasys/stasys.rune - System config:
/etc/stasys/stasys.rune - Logs:
~/.cache/stasys/stasys.log
stasis:
pre_suspend_command "hyprlock"
monitor_media true
ignore_remote_media true
respect_idle_inhibitors true
# Laptop lid events
lid_close_action "lock-screen"
lid_open_action "wake"
# Desktop idle actions
lock_screen:
timeout 300 # 5 minutes
command "loginctl lock-session"
resume-command "notify-send 'Welcome Back!'"
lock-command "swaylock"
end
dpms:
timeout 60 # 1 minute
command "niri msg action power-off-monitors"
resume-command "niri msg action power-on-monitors"
end
suspend:
timeout 1800 # 30 minutes
command "systemctl suspend"
end
end
# Show current state
stasys info
# Trigger action manually
stasys trigger lock-screen
# Pause idle detection
stasys pause for 1h
stasys resume
# Toggle idle inhibition (Waybar-friendly)
stasys toggle-inhibit
# Reload config
stasys reload
# View recent logs
stasys dump 50
# Stop daemon
stasys stopProfiles let you switch between different configurations for different scenarios (work, gaming, presentations, etc.).
- Each profile is a standalone config file in
~/.config/stasys/profiles/ - Switching profiles completely replaces your current config
- Actions not defined in a profile are disabled during that profile, unless your system provides fallbacks
- Profile state persists across restarts
- Create a profiles directory in
~/.config/stasys/profiles - Create a profile (e.g., work.rune) manually or use one of the examples in the repo
# List available profiles
stasys profile list
# Switch to a profile
stasys profile work
# Return to base config
stasys profile none
# Check current profile
stasys infoThree example profiles are included in examples/profiles/:
| Profile | Purpose | Key Changes |
|---|---|---|
| work.rune | Office work | Longer timeouts, video call apps inhibited |
| gaming.rune | Gaming | Gaming apps inhibited, no brightness auto-dim |
| presentation.rune | Presentations | No idle, max brightness, inhibitors disabled |
Add profile switching to your Waybar module:
"custom/stasys": {
"exec": "stasys info --json",
"format": "{icon}",
"format-icons": {
"idle_active": "σ°Ύ",
"idle_inhibited": "σ°
Ά",
"manually_inhibited": "σ°
Ά",
"not_running": "σ°²"
},
"tooltip": true,
"on-click": "stasys toggle-inhibit",
"on-click-right": "stasys profile cycle",
"on-click-middle": "stasys info",
"interval": 2,
"return-type": "json"
}Profile cycling: Right-click cycles through: none β work β gaming β presentation β none...
Alternatively, you can simply use one fallback profile and invoke it directly, i.e. "stasys profile work"
Create a script for custom profile cycling:
#!/bin/bash
# ~/.local/bin/stasys-profile-cycle
PROFILES=("none" "work" "gaming" "presentation")
CURRENT=$(cat ~/.config/stasys/active_profile 2>/dev/null || echo "none")
# Find current index
for i in "${!PROFILES[@]}"; do
if [[ "${PROFILES[$i]}" == "$CURRENT" ]]; then
NEXT="${PROFILES[$(( (i + 1) % ${#PROFILES[@]} ))]}"
stasys profile "$NEXT"
notify-send "Stasys Profile" "Switched to: $NEXT"
exit 0
fi
done
# Fallback
stasys profile noneMake it executable and update Waybar:
chmod +x ~/.local/bin/stasys-profile-cycle"custom/stasys": {
"on-click-right": "~/.local/bin/stasys-profile-cycle"
}Contributions are welcome! Here's how you can help:
- π Report bugs β Open an issue with reproduction steps
- π‘ Suggest features β Share your use cases and ideas
- π§ Submit PRs β Fix bugs, add features, or improve code
- π Improve docs β Better explanations, examples, and guides
Released under the MIT License β free to use, modify, and distribute.
Built with β€οΈ for the Wayland community
Keeping your session in perfect balance between active and idle
