Changing my background based off the time of the day came down to needing two simple parts to work:
- A way to programmatically update the current background of KDE based on the current hour.
- A way to have that process run every hour.
Updating the background
The first thing I wanted to do, was given the current hour of the day, select a wallpaper that corresponds to the hour.
#!/bin/bash
if [ -z "$1" ]; then
HH=$(date +%H)
else
HH="$1"
fi
bg_dir="/home/joe/Pictures/DesktopSlides"
case "$HH" in
23|00|01)
bg="7.png"
;;
02|04)
bg="8.jpg"
;;
03)
bg="9.jpg"
;;
05|06|07)
bg="1.jpg"
;;
08|09|10)
bg="2.png"
;;
11|12|13)
bg="3.jpg"
;;
14|15|16)
bg="4.jpg"
;;
17|18|19)
bg="5.jpg"
;;
20|21|22)
bg="6.jpg"
;;
esac
After this, the image that we’ll want to assign to the background is ${bg_dir}/{bg}
.
From here, the only thing left to do is tell KDE we want this to be our desktop and lock screen backgrounds. The following is the solution I found for telling KDE that we want the given image file to be the desktop background on all desktop screens.
DISPLAY=:0 qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "var allDesktops = desktops(); print (allDesktops); for (i=0;i<allDesktops.length;i++) {d = allDesktops[i]; d.wallpaperPlugin = 'org.kde.image'; d.currentConfigGroup = Array('Wallpaper', 'org.kde.image', 'General'); d.writeConfig('Image', '${bg_dir}/${bg}')}"
Similarly, this was the solution that I found for updating the lock screen on all screens:
DISPLAY=:0 kwriteconfig5 --file /home/joe/.config/kscreenlockerrc --group Greeter --group Wallpaper --group org.kde.image --group General --key Image "file://${bg_dir}/${bg}"
This process is then saved as an executable script called ~/.local/bin/set-time-theme
Running it on the hour
Normally, for scheduling tasks, I’d reach for cron. The biggest issue that I have with cron however is easily scheduling tasks to be run for by the user. I found creating a user systemd service and timer to be easier than trying to jump through the sudo/su hoops of getting cron to run as the desktop user.
The following systemd unit file was installed to ~/.config/systemd/user/background-slides.service
,
which when called, will run shot call the ~/.local/bin/set-time-theme
script from above.
[Unit]
Description=Update the desktop and lockscreen background to match the current time.
Wants=background-slides.timer
[Service]
Type=oneshot
ExecStart=/home/joe/.local/bin/set-time-theme
[Install]
WantedBy=default.target
This service is setup to want the background-slides.timer
. This is a systemd
timer setup to be bound to background-slides.service
, setup to be run every
hour on the hour. The following are the contents of the
~/.config/systemd/user/background-slides.timer
file
[Unit]
Description=Try to update the lockscreen and desktop background every hour.
Requires=background-slides.service
[Timer]
OnCalendar=*-*-* *:00:00
Persistent=true
[Install]
WantedBy=timers.target
Following all of that, this service can be setup to run on login, as well as on the timer by running:
$ systemctl --user enable background-slides.service
$ systemctl --user enable background-slides.timer