hypridle
hypridle is Hyprland’s idle management daemon.
Configuration
Configuration is done via the config file at ~/.config/hypr/hypridle.conf.
A config file is required; hypridle won’t run without one.
To run hypridle at startup, add hypridle to your autostart commands in your Hyprland config.
General
Variables in the general category:
| Variable | Description | Type | Default |
|---|---|---|---|
lock_cmd | command to run when receiving a D-Bus lock event (e.g., loginctl lock-session) | string | [[Empty]] |
unlock_cmd | command to run when receiving a D-Bus unlock event (e.g., loginctl unlock-session) | string | [[Empty]] |
on_lock_cmd | command to run when the session gets locked by a lock screen app | string | [[Empty]] |
on_unlock_cmd | command to run when the session gets unlocked by a lock screen app | string | [[Empty]] |
before_sleep_cmd | command to run when receiving a D-Bus prepare_sleep event | string | [[Empty]] |
after_sleep_cmd | command to run when receiving a D-Bus post prepare_sleep event | string | [[Empty]] |
ignore_dbus_inhibit | whether to ignore D-Bus idle inhibit events (e.g., from firefox) | bool | false |
ignore_systemd_inhibit | whether to ignore systemd-inhibit --what=idle inhibitors | bool | false |
ignore_wayland_inhibit | whether to ignore Wayland protocol idle inhibitors | bool | false |
inhibit_sleep | sleep inhibition mode:0: disable1: normal2: auto3: lock notify | int | 2 |
Note
The general:inhibit_sleep option is used to make sure hypridle can perform certain tasks before the system goes to sleep.
Options:
0disables sleep inhibition.1makes the system wait until hypridle launchedgeneral:before_sleep_cmd.2(auto) selects either3or1depending on whether hypridle detects if you want to launch hyprlock before sleep.3makes your system wait until the session gets locked by a lock screen app. This works with all Wayland session-lock apps.
Listeners
Hypridle uses listeners to define actions on idleness.
Every listener has a timeout (in seconds).
After idling for timeout seconds, on-timeout will fire.
When action is resumed after idle, on-resume will fire.
You can define as many listeners as you want.
Example listener
listener {
timeout = 500 # in seconds.
on-timeout = notify-send "You are idle!" # command to run when timeout has passed.
on-resume = notify-send "Welcome back!" # command to run when activity is detected after timeout has fired.
}Variables in the listener category:
| Variable | Description | Type | Default |
|---|---|---|---|
timeout | Idle time in seconds | int | none, value must be specified |
on-timeout | Command to run when timeout has passed | string | [[Empty]] |
on-resume | Command to run when activity is detected after timeout has fired | string | [[Empty]] |
ignore_inhibit | Ignore idle inhibitors (of all types) for this rule | bool | false |
condition_cmd | Command run when the timeout is reached, before on-timeout. Run via /bin/sh -c; exit code 0 lets on-timeout fire, non-zero defers it | string | [[Empty]] |
condition_retry | When condition_cmd defers, re-run it every N seconds while the user stays idle, firing on-timeout as soon as it succeeds. 0 disables retrying (the deferred on-timeout is skipped for this idle cycle) | int | 0 |
Conditional timeouts
A listener can gate its on-timeout on external state with condition_cmd.
When the timeout is reached, hypridle runs condition_cmd first; on-timeout fires only if it exits 0.
A non-zero exit defers on-timeout.
Set condition_retry to keep re-checking while the user stays idle: hypridle re-runs condition_cmd every condition_retry seconds and fires on-timeout the moment it succeeds.
With condition_retry = 0 (the default), a deferred on-timeout is simply skipped until the next idle cycle.
Any user activity resets the listener and cancels a pending retry.
Note
condition_cmd runs synchronously on hypridle’s event loop, so keep it fast — a script that blocks holds up idle handling.
Retry timing is checked on hypridle’s ~5s event-loop tick, so very small condition_retry values are effectively rounded up to that granularity.
Examples
Don’t suspend while an SSH session is connected:
listener {
timeout = 900 # 15min.
on-timeout = systemctl suspend # suspend pc.
condition_cmd = ~/.config/hypr/scripts/can-suspend.sh # exit 0 = suspend, non-zero = stay awake.
condition_retry = 30 # re-check every 30s while still idle.
}#!/bin/sh
ss -tn state established '( sport = :ssh )' | grep -q . && exit 1
exit 0Full hypridle example with hyprlock:
general {
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances.
before_sleep_cmd = loginctl lock-session # lock before suspend.
after_sleep_cmd = hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' # to avoid having to press a key twice to turn on the display.
}
listener {
timeout = 150 # 2.5min.
on-timeout = brightnessctl -s set 10 # set monitor backlight to minimum, avoid 0 on OLED monitor.
on-resume = brightnessctl -r # monitor backlight restore.
}
# turn off keyboard backlight, comment out this section if you dont have a keyboard backlight.
listener {
timeout = 150 # 2.5min.
on-timeout = brightnessctl -sd rgb:kbd_backlight set 0 # turn off keyboard backlight.
on-resume = brightnessctl -rd rgb:kbd_backlight # turn on keyboard backlight.
}
listener {
timeout = 300 # 5min
on-timeout = loginctl lock-session # lock screen when timeout has passed
}
listener {
timeout = 330 # 5.5min
on-timeout = hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })' # screen off when timeout has passed
on-resume = hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' && brightnessctl -r # screen on when activity is detected after timeout has fired.
}
listener {
timeout = 1800 # 30min
on-timeout = systemctl suspend # suspend pc
}Fading the keyboard backlight
brightnessctl sets brightness instantly, so a plain on-timeout/on-resume pair turns the keyboard backlight off and on abruptly.
hypr-kbd-backlight-fade is a small script that steps through intermediate brightness values instead, fading in fast and out slowly,
with a lock file so overlapping in/out calls (e.g., quick touch-then-idle cycles) don’t race each other.
Note that video players and browsers commonly hold a Wayland idle-inhibit lock during video playback (not just fullscreen), which pauses every listener, not just screen lock/suspend.
If you want the keyboard backlight to keep responding to real input while a video plays, set ignore_inhibit = true on that listener specifically, rather than on general:ignore_wayland_inhibit which would disable inhibit-awareness for every listener.
Locking on suspend and hibernate
The session is locked before going to sleep, not after resuming.
Every route into sleep goes through logind’s PrepareForSleep signal — systemctl suspend, systemctl hibernate, systemctl suspend-then-hibernate, a listener with on-timeout = systemctl suspend, or closing the laptop lid with logind’s HandleLidSwitch.
general:before_sleep_cmd therefore fires for all of them, including sleeps that hypridle did not initiate itself.
general {
lock_cmd = pidof hyprlock || hyprlock # run when the session is asked to lock.
before_sleep_cmd = loginctl lock-session # ask for the lock before sleeping.
}before_sleep_cmd does not start the locker itself.
loginctl lock-session only emits logind’s Lock signal for the session; hypridle picks it up and runs general:lock_cmd.
Keeping the two apart means the locker is named in exactly one place, and a manual loginctl lock-session — from a keybind, for example — takes the same path as sleeping does.
Lid handling belongs to logind, not to Hyprland; see the warning about HandleLidSwitch.
No extra bind is needed to lock on lid close: logind emits PrepareForSleep for that path too.
hypridle does not choose between suspend and hibernate, it only runs the command you give it.
systemctl hibernate needs a working resume device, and systemctl suspend-then-hibernate suspends first and hibernates after HibernateDelaySec, set in /etc/systemd/sleep.conf.d/.
Waiting for the lock to be drawn
loginctl lock-session returns as soon as the signal has been sent, long before the locker has drawn anything.
Without inhibition the system can freeze in that gap, and the frame that shows up on resume is the unlocked desktop, until the locker finally appears on top of it.
general:inhibit_sleep exists for this: hypridle takes a delay sleep inhibitor from logind and releases it once its before-sleep handling is done.
What “done” means differs per mode:
1releases the inhibitor as soon asbefore_sleep_cmdhas been spawned, which is not enough forloginctl lock-session.3releases it only once the session is really locked, as reported over thehyprland-lock-notify-v1protocol.2(the default) picks3only when it recognizes hyprlock, that is whenbefore_sleep_cmdcontainshyprlock, or whenlock_cmdcontainshyprlockandbefore_sleep_cmdcontainslock-session. It falls back to1otherwise.
With any other lock screen app, set inhibit_sleep = 3 explicitly.
Prefer that over padding before_sleep_cmd with a sleep: the inhibitor waits for the lock event itself instead of for a guess.
Which mode was picked is printed at startup, as Sleep inhibition enabled - inhibiting until the wayland session gets locked.
Note
The session counts as locked once the lock surface is up, which can be before the locker has finished fading in.
If a translucent lock screen still shows through on resume, disable the fade-in as well (hypridle#146).
With hyprlock, start it as hyprlock --no-fade-in, or turn off its animations entirely.