cadence’s website.

Some changes will be applied after reloading.
Some changes will be applied after reloading.

Implementing different wallpapers on KDE virtual desktops


I've been told that a tool called "Vallpaper" can also help with this. However, I haven't tested it at all, so it might not work! Don't come asking me for help, but do feel free to let me know if Vallpaper works for you, and I'll update this section of my blog post.

My original post continues below. You should read it! :)

Context and history

Over the last couple of days I've been setting up my new KDE install -- KDE is REALLY good, thank you so much to the people who work on the default applications and system integration -- and I wanted to take advantage of the great virtual desktops feature. It seems that in the past there used to be a way to display a different wallpaper on each virtual desktop, however, this feature was removed around the time that KDE 5 came out.

Nowadays, the only default way to have different wallpapers is to use the "activities" feature, which is very similar to virtual desktops but with some features added (like independent wallpapers and layouts and panels) and some features removed (like being able to zoom out to get an overview of which windows exist across all spaces).

Some KDE developers have been thinking about removing activities and combining their features with virtual desktops, so maybe that'll happen in the future to make this easier! For now, we have to create something to add that functionality.

KWin Scripts

If independent wallpapers don't really exist, the next alternative is quite straightforward: detect when the active desktop changes, and then change the global wallpaper to match it.

I'd heard of a few different KWin window tiling scripts, so I assumed that KWin would have the necessary functionality. I quickly discovered a built-in KWin script, located in /usr/share/kwin/scripts/desktopchangeosd, that has code to detect when the current desktop changes. I also found a shell command that appears to execute a Plasma script to change the wallpaper, which would complete the missing part of the puzzle. All I need to do is figure out how to put them into one file!

I'll save you the two hours of me failing to do this. It turns out that "KWin Scripts" and "Plasma Scripts" are entirely different things with different features? In particular, Plasma Scripts can change the wallpaper but not detect virtual desktops, and KWin Scripts can detect virtual desktops but not change the wallpaper.

How to actually do this

WARNING: This is cursed! Read on if you dare.

So KWin scripts can't actually communicate with the outside system at all, no wallpaper, no shell commands, no file access, all they can do is manipulate windows because KWin is only a window manager. Foiled? Not quite. KWin can actually affect the outside world in one way: error logging.

console.error(...) in a KWin script will send data, and journalctl _COMM=kwin_wayland -n 0 -f in a shell will read data. Perfect, we're now communicating in real-time (?) between KWin and the system. The shell script just needs to call plasma-apply-wallpaperimage to set the wallpaper.

Ok, let's do it already

Install the KWin script with:

kpackagetool5 --type=KWin/Script -i /path/to/wallpaperperdesktopfolder
kwriteconfig5 --file kwinrc --group Plugins --key wallpaperperdesktopEnabled true
qdbus org.kde.KWin /KWin reconfigure # ???

To complete the puzzle, download and edit the shell script to point to your favourite wallpapers, then run it in fish shell. Changing virtual desktops will change the wallpaper with a cross-fade animation.

If it doesn't work, check the shell script's logs and journalctl _COMM=kwin_wayland -n 0 -f I guess. But I'm probably not going to be able to help you debug anything since I know just as little as you do.


What can KDE people do to improve this?

An important thing is improving the documentation. I was flying completely blind creating these scripts. I had to trial-and-error the folder structure, each individual line of code, and run three commands and log out and log back in again after making each change to coerce it into applying the changes.

While the documentation technically exists, and there's almost a page with a tutorial, the tutorial could do a lot more to explain step-by-step how to set up the folder structure for your KWin script, how to install the script, how to reload it after making changes, how to produce debug logs, how to monitor debug logs. All of the tooling things that surround the actual code are extremely under-documented and I had to rely on code searching other people's GitHub repositories and reddit questions with 2 comments apiece to discover these basic steps.

After better documentation exists and has been user tested, add a link from the "KWin Scripts" settings pane to the main page of that documentation section, with a caption something like "How to create KWin scripts."

The best idea to solve the problem would be to merge workspaces and activities into parity with each other. This would also clean up a lot of end-user confusion about what the two features are. I've been using Linux for years and I've been using KDE Activities for 10 months up until today and I honestly don't know what a use case of activities is.

A workaround for this specific problem could be to allow KWin scripts to execute Plasma scripts. This would fill in the gap of KWin scripts being good at detecting signals and Plasma scripts being good at doing actions.

Finally, the method I described in this blog post actually answers the classic FP thought problem of whether output logging is a side-effect. It is. Lol.


A seal on a cushion spinning a globe on its nose.
Another seal. They are friends!