Custom screen saver with XSecureLock

Vincent Bernat

i3lock is a popular X11 screen lock utility. As far as customization goes, it only allows one to set a background from a PNG file. This limitation is part of the design of i3lock: its primary goal is to keep the screen locked, something difficult enough with X11. Each additional feature would increase the attack surface and move away from this goal.1 Many are frustrated with these limitations and extend i3lock through simple wrapper scripts or by forking it.2 The first solution is usually safe, but the second goes against the spirit of i3lock.

XSecureLock is a less-known alternative to i3lock. One of the most attractive features of this locker is to delegate the screen saver feature to another process. This process can be anything as long it can attach to an existing window provided by XSecureLock, which won’t pass any input to it. It will also put a black window below it to ensure the screen stays locked in case of a crash.

XSecureLock is shipped with a few screen savers, notably one using mpv to display photos or videos, like the Apple TV aerial videos. I have written my own saver using Python and GTK.3 It shows a background image, a clock, and the current weather.4

Custom screen saver for XSecureLock, displaying a clock and the
current weather
Custom screen saver for XSecureLock

I add two patches over XSecureLock:

  • Sleep before mapping screen saver window. This patch prevents a flash of black when starting XSecureLock by waiting a bit for the screen saver to be ready before displaying it. As I am also using a custom dimmer fading to the expected background before locking, the flash of black was quite annoying for me. I have good hope this patch will be accepted upstream.
  • Do not mess with DPMS/blanking. This patch prevents XSecureLock from blanking the screen. I think this is solely the role of the X11 DPMS extension. This makes the code simpler. I am unsure if this patch would be accepted by upstream.

Update (2023-05)

The first patch has been accepted and is available in 1.8.0. Instead of the second patch, I am now setting XSECURELOCK_BLANK_TIMEOUT to -1.

XSecureLock also delegates the authentication window to another process, but I was less comfortable providing a custom one as it is a bit more security-sensitive. While basic, the shipped authentication application is fine by me.

I think people should avoid modifying i3lock code and use XSecureLock instead. I hope this post will help a bit.

Update (2022-01)

XScreenSaver can also run arbitrary programs as a screen saver.


  1. See for example this comment or this one explaining the rationale. ↩︎

  2. This Reddit post enumerates many of these alternatives. ↩︎

  3. Using GTK makes it a bit difficult to use some low-level features, like embedding an application into an existing window. However, the high-level features are easier, notably drawing an image and a text with a shadow. ↩︎

  4. Weather is retrieved by another script running on a timer and written to a file. The screen saver watches this file for updates. ↩︎