Hello folks! It's been a while since I've posted something here.
Today, I'm gonna give you a deep dive into the problem I have with KDE Plasma and the solution(s) I've tried before settling on developing
auto-dark-theme from scratch.
KDE Plasma doesn't have a "switch to the dark theme on a custom time" setting by default. Now, to be fair GNOME didn't add support before GNOME 42 but extensions were always available to solve this problem. I used Night Theme Switcher on Manjaro GNOME before I moved to KDE.
In my Windows setups, I install Auto Dark Mode and set it up according to my needs.
A quick Google search for "auto dark mode kde" suggests using Yin Yang which on further inspection looked promising.
So as a Manjaro user, I installed it via AUR. First impressions, it was great! I was able to select the themes I wanted for light and dark modes, setup timings for triggering light vs dark themes and I liked the "Plugins" feature.
However, things weren't as smooth as I thought. For example, the timer wasn't triggering on my machine. I ignored it for a few days until it became an annoyance that I had to take care of and so my investigation had begun. I uninstalled the AUR package, cloned the source to my local and tried to set it up manually to reproduce. This worked but I didn't want to "maintain" a local copy forever so the research continued.
After a few hours, I figured out the problem - yin-yang uses a user-level systemd service in the $HOME directory to store the timer information. The AUR package was setting a different path during installation. This means the user's timer information wasn't seen by
systemd even when the GUI reports it correctly.
I reported my findings to the AUR package maintainer here and a few days later, I received a response stating the path change during installation was to comply with AUR packaging guidelines which state that an AUR package is not allowed to reference
This was fixed in a few days with the next release however by that time I had lost interest in yin-yang. The experience had given me a sour taste towards the app and I realized I wanted a simpler solution to this problem that gets the job done with few moving parts.
After another research session on Google, I found a Reddit post that said we can use the CLI tool
lookandfeeltool to switch between themes.
lookandfeeltoolis a simple command-line tool provided by the KDE Plasma team to change themes by the KDE Plasma team.
It doesn't support any fancy features from yin-yang.
I got excited reading this and I began testing it on the terminal.
- Check out the help section and list all available commands.
$ lookandfeeltool -h Usage: lookandfeeltool [options] Command line tool to apply global theme packages for changing the look and feel. Options: -l, --list List available global theme packages -a, --apply <packagename> Apply a global theme package. This can be the name of a package, or a full path to an installed package, at which point this tool will ensure it is a global theme package and then attempt to apply it --resetLayout Reset the Plasma Desktop layout -h, --help Displays help on commandline options. --help-all Displays help including Qt specific options. -v, --version Displays version information. --author Show author information. --license Show license information. --desktopfile <file name> The base file name of the desktop entry for this application.
- Cool! Let's list out all available themes on my local machine.
$ lookandfeel -l org.manjaro.breath.desktop # <-- my preferred light theme org.kde.oxygen org.kde.breezedark.desktop org.manjaro.breath-light.desktop org.kde.breezetwilight.desktop org.kde.breeze.desktop org.manjaro.breath-dark.desktop # <-- my preffered dark theme
- Awesome! Let's try switching to the dark theme.
$ lookandfeeltool -a org.manjaro.breath-dark.desktop
So the next step was to turn it into a shell script that checks the local time and switches the theme if it's greater than 3 PM which is my preferred time.
Here is the final script I came up with:
echo "Auto theme script for KDE Plasma" # Get hour number in 24 hour format from current time # and store it in variable called "hour" hour=$(date --date="now" +%k) # log file LOG_FILE=/tmp/auto-theme.log # logic to switch themes if [ "$hour" -ge "18" ]; then echo "Switching to dark mode" lookandfeeltool -a org.manjaro.breath-dark.desktop 2>&1 | tee -a $LOG_FILE else echo "Switching to light mode" lookandfeeltool -a org.manjaro.breath.desktop 2>&1 | tee -a $LOG_FILE fi echo "Goodbye!"
Finally, I wrote a user-level systemd service to trigger it at startup.
# $HOME/.local/share/systemd/user/auto-dark-theme.service [Service] Type=exec RemainAfterExit=true Restart=on-failure RestartSec=5 Environment="QT_QPA_PLATFORM=wayland" WorkingDirectory=$HOME/Projects/auto-dark-theme ExecStart=/usr/bin/python -m auto-dark-theme StandardOutput=journal StandardError=journal [Install] WantedBy=plasma-workspace-wayland.target
I was quite happy to see it in action on each startup.
There were a few limitations to this approach:
Lack of screen lock/unlock detection (Win + L) - This means if I lock my screen for a few hours and I come back, the theme wouldn't switch. I was under the assumption was
systemdwouldn't know about this event.
Sleep detection - My machine is configured to go to sleep if it's locked for too long. This saves battery life and keeps the laptop cooler. But my systemd service wouldn't trigger when the machine resumes from sleep.
To be fair, this was on me. I didn't know we had a
resume.targetthat can trigger scripts on system resume. It could've fixed this issue.
In part 2 of this series, I will explain how the Python-based implementation overcame these issues.
Please use the emotes on the right if you liked this article. Add a comment with your thoughts on this. I would love to hear how you would've tackled this issue.
You can also @ me on Mastodon here.
Thanks for reading. See you next time :)