Daniele Fucini 0234456af8 Log SimulateUserActivity once per burst
Steam calls it thousands of times per hour during controller play, which made up
~98% of the journal. Log the first call and a summary with the count after 5
minutes of quiet, when the client leaves, or on shutdown.
2026-10-15 23:38:52 +02:00
2026-10-09 19:49:08 +02:00

xautolock-inhibit

Makes screen locking with xautolock respect the "don't lock the screen" requests that apps send, on X11 sessions without a desktop environment (for example a plain window manager like xmonad).

Browsers, Steam, gamemode and other apps ask the desktop not to lock or blank the screen while a video or game is running, through the D-Bus service org.freedesktop.ScreenSaver. Without a desktop environment nothing provides that service, so the requests are dropped and the screen locks in the middle of a video. xautolock-inhibit provides it:

  • While at least one request is active, it runs xautolock -disable and pauses X screen blanking and DPMS.
  • When the last request is released, it waits a few seconds, then runs xautolock -enable and resumes blanking.

xautolock stays your locker; xautolock-inhibit only switches it off and on.

How it works

  • Owns org.freedesktop.ScreenSaver on the session bus at both /org/freedesktop/ScreenSaver and /ScreenSaver (apps differ on the path), and implements Inhibit and UnInhibit.
  • Tracks requests per D-Bus client. If a client disconnects without releasing them (for example a browser crash), its requests are released.
  • Runs xautolock only when the number of active requests goes from 0 to 1 or back to 0. Re-enabling waits a few seconds (--release-delay), because browsers send short bursts of requests when a video starts.
  • Pauses X blanking with XScreenSaverSuspend, the same mechanism mpv uses, instead of changing xset settings. The X server ends the pause by itself if the daemon exits or crashes.
  • Requests whose reason is on an ignore list (default: Playing audio) are accepted and logged, but don't block locking. Firefox-based browsers send one for audio playback, which would otherwise keep the screen unlocked while music plays with nobody at the computer.
  • On exit (including SIGTERM), it re-enables xautolock. The systemd unit also runs xautolock -enable when it stops, as a fallback.
  • If another program (a desktop environment) already owns org.freedesktop.ScreenSaver, it exits with status 2 instead of taking over.

Requirements

  • xautolock, already running in the session
  • python, python-gobject
  • libx11, libxss

Installation

Build and install the package with the included PKGBUILD:

makepkg -si

Then start it from your window manager's startup, after xautolock. For xmonad:

spawnOnce "xautolock -time 10 -locker slock -detectsleep"
spawnOnce "systemctl --user start xautolock-inhibit"

The unit has no [Install] section on purpose. Enabling it at login would also start it in a desktop environment, or before X is up; starting it from the window manager limits it to that session. The user service manager needs DISPLAY (and XAUTHORITY) in its environment, which /etc/X11/xinit/xinitrc.d/50-systemd-user.sh sets up for startx sessions.

Usage

xautolock-inhibit [-i REASON] [--count-all] [-d SECONDS]
  • -i, --ignore-reason REASON: request reason that doesn't block locking. Can be repeated; replaces the default (Playing audio).
  • --count-all: every request blocks locking; no reasons are ignored.
  • -d, --release-delay SECONDS: wait this long after the last release before re-enabling xautolock (default 5).

To change the options used by the service:

systemctl --user edit xautolock-inhibit.service
[Service]
ExecStart=
ExecStart=/usr/bin/xautolock-inhibit --count-all

Every request, release and xautolock call is logged to the journal:

journalctl --user -u xautolock-inhibit

App notes

  • Sandboxed apps may be blocked from reaching the service. For a firejail profile that filters D-Bus (dbus-user filter, as the Firefox-based profiles do), allow it in the app's .local file, e.g. zen-browser.local:

    dbus-user.talk org.freedesktop.ScreenSaver
    
  • Games: Steam's overlay and gamemode (inhibit_screensaver=1) send requests on their own.

  • scrcpy only sends a request when started with --disable-screensaver.

  • mpv talks to the X server directly and doesn't need this daemon.

Limitations

  • Restarting the daemon loses the requests it holds; apps don't send them again. Avoid restarting it while a video or game is running.
  • SimulateUserActivity is accepted but does nothing. Calls are logged once when a client starts sending them and once, with a count, after 5 minutes without any.
  • GetActive always returns false.

License

GPL-3.0-or-later. See LICENSE.

S
Description
No description provided
Readme GPL-3.0
139 KiB
Languages
Python 97.3%
Shell 2.7%