Dynamic wallpapers with Sway

During the last few months, I fell in love with Sway, a tiling window manager modeled on i3 that runs natively under Wayland. I found there all the efficiency and all my habits acquired under i3, but with a much smoother and more responsive display.

All the applications I use run very smoothly, and I am discovering the joy of a responsive display without tearing. Firefox in particular has an incredibly smooth scroll with a touchpad, which until now only existed under macOS.

On a daily basis, I use waybar for displaying workspaces and status bar, kitty for the terminal emulator and wofi as an launcher. All the applications I use every day are Wayland native, with the exception of steam and gimp: for these, xwayland makes the gateway with unfortunately a lack of HiDPI support for the moment which results in pixelized applications.

The only thing I regretted however, although useless and fancy, is to be able to automate a wallpaper change. It is managed by swaybg which, when restarted, displays a grey screen for a moment.

Reloading the wallpaper without a grey blink

The trick is not to relaunch swaybg, but to create a new instance and then kill the old one.

Let’s say you launch your wallpaper with:

swaybg -i image1.png -m fill &

The process identifier (PID) of the last command is automatically stored in $!. We record it in a variable:

PID=$!

When desired, we can launch a second instance with a second wallpaper. This one will not appear at the moment because the first instance is still running:

swaybg -i image2.png -m fill &

The wallpaper will then refresh, without a gray screen, as soon as the first instance is killed:

kill $PID

Random wallpaper change

Suppose we have a folder img/ containing several images. It is possible to select one of them randomly with:

find img/. -type f | shuf -n1

To randomly change the wallpaper, you can then use:

swaybg -i $(find img/. -type f | shuf -n1) -m fill &

One can then create, on this basis, a small script that changes the wallpaper, for example every ten minutes (600 seconds):

#!/bin/sh
swaybg -i $(find img/. -type f | shuf -n1) -m fill &
OLD_PID=$!
while true; do
    sleep 600
    swaybg -i $(find img/. -type f | shuf -n1) -m fill &
    NEXT_PID=$!
    sleep 5
    kill $OLD_PID
    OLD_PID=$NEXT_PID
done

Make it executable with chmod +x, then you can load it automatically with Sway by adding, in your sway config:

exec "cd your_script_folder && ./your_script.sh"

A better way would be to use pidof swaybg, then kill: it is illustrated in the next section.

Dynamic wallpaper depending of the hour of the day

I recently made a dynamic wallpaper, based on Louis Coyle‘s 25th hour animation.

The 25th hour

The animation was recorded and transformed into 144 images, 6 images per hour, making it possible to obtain a wallpaper that changes every 10 minutes. You can see it here:

Lakesize dynamic wallpaper (git repository)

The script uses this command to round the current time to ten minutes:

#!/bin/sh
#!/bin/sh
cd projets/lakeside
while true; do
    PID=`pidof swaybg`
    swaybg -i ./img/$(date -u -d @$((($(date -u +%s) / 600) * 600)) "+%Hh%M").png -m fill &
    sleep 1
    kill $PID
    sleep 599
done