Making wlsunset take Effect for a Locked Screen on Sway

Posted on 2026-10-18
TL;DR
wlsunset did not set the correct color temperature for my screens when they were switched off during sunset. This is how I fixed it by restarting it from swayidle's resume command. Bonus: A second press of the lock key turns the screens off on demand.

I’ve been using tiling window managers for way over a decade now. As a long time user of Xmonad on Xorg I switched to sway to be able to use the more modern Wayland based Desktop. On Xmonad I loved redshift, a program that adjusts the color temperature of the display in order to have a warmer display with less blue light during at night time.

On sway there is an alternative: wlsunset. It works basically the same. It’s a background program that I started in my sway config on startup of the desktop session.

But I noticed an issue with this setup: when I lock the screen before sunset and the monitors get switched off while I’m away, the screens are still cold when I wake up my monitors. The wlsunset process is running, and its log even says setting temperature to 4000 K. But the tint is just not being visible.

Cause of the Problem

wlsunset only talks to the compositor when it wants to change the temperature. During sunset that is every few seconds but after dusk the warmest value is reached and no changes are applied anymore. If the outputs are powered off while the last steps happen, nothing ever applies the final value.

The fix I found

Restarting wlsunset applies the current temperature right away. So I wake it up whenever the screens come back on. I put the restart into a small script:

#!/bin/sh
pkill -x wlsunset
while pgrep -x wlsunset >/dev/null; do sleep 0.1; done
setsid -f wlsunset -T 5500 -t 4000 -l 53.5 -L 9.9

The loop waits until the old process is gone. Then I start a new instance of wlsunset with the desired config1. If you’d want to use this for your setup just replace the coordinates with your own.

Killing a process and starting it again feels a bit dirty, but it is the best fix I found. If you can think of a better way I’d love to hear about that!

Then the script runs in two places: At startup it replaces the plain exec wlsunset line. Also it is called from the resume command of swayidle2. This is what the part of my sway config looks like:

exec swayidle -w timeout 300 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"; ~/.config/sway/wlsunset-restart'
exec ~/.config/sway/wlsunset-restart

After 300 seconds without input the screens go off. On the next key press or mouse movement they come back on and wlsunset is restarted.

Bonus: Lock and switch off the screens with one key

While I was at it I tried to find a way to switch the screens off right after locking, because sometimes I know I’ll be away from the computer for longer and I don’t want to wait for the screen to switch off after the timeout.

swayidle enters its idle state immediately when it receives the SIGUSR1 signal. That results in the same dpms off command being issued as caused by the timeout. The resume command takes care of waking everything up again in any case. The trick here is that sway lets you bind a key differently depending on whether a screen locker is running or not. That way a binding with the --locked flag3 can be used while swaylock is active and the one without it in the other case. In the sway configuration file this looks like that:

set $locker 'swaylock -f -c 000000 --inside-color 000000b3 -K'
bindsym $mod+Shift+z exec $locker
bindsym --locked $mod+Shift+z exec pkill -USR1 -x swayidle

So what does that do? I can simply press $mod+Shift+z once to lock my screen. The Displays stay powered and would switch off after the 300 second timeout. But when I press it again the screens go off immediately. Any key press wakes them up with the tint intact. This is only one combination and I can even press it with one hand on my split keyboard. Neat!

Conclusion

wlsunset itself does nothing wrong here. It just has no way to find out that the screens were switched off in between. Restarting it on resume is a cheap workaround that works for me. Maybe you are struggling with the same configuration issues.

Do you have a different solution for it? How does your sway configuration look like? I’d love to hear about it.

Footnotes


  1. setsid -f starts the command in a new session of its own, so it is detached from the script that launched it.↩︎

  2. swayidle is the idle management daemon for Wayland compositors like sway.↩︎

  3. By default sway does not trigger key bindings while a screen locker is active. The --locked flag makes a binding work anyway.↩︎

Portrait of the blog's author. Dude with full beard and short hair.
Author: Benjamin Brunzel I'm a software engineer based in Hamburg, Germany. If you want to get in touch contact me in the fediverse