Introduction
If you spend late nights at the terminal (and let's be honest, who on this blog doesn't), you've probably leaned on KDE Plasma's Night Light feature to keep the blue light from frying your eyes at 2 AM. The GUI slider works fine — but what if you want to script your color temperature, tie it to a cron job, or just toggle it faster than clicking through System Settings? Turns out KDE doesn't give you an official CLI for that. So I built one.
This is a smaller, more focused project than some of the infrastructure builds I've covered here, but it scratches the same itch: understanding what's actually happening under the hood instead of settling for "it just works." Here's how you can build your own settemp utility in about ten minutes.
Core Concept
The obvious approach doesn't work
Your first instinct is probably to write directly to the config file with kwriteconfig6:
kwriteconfig6 --file kwinrc --group NightColor --key NightTemperature 3000
This looks like it should work, but it doesn't do anything visible. The value gets written to ~/.config/kwinrc, but KWin's Night Light manager never notices. That's because KWin caches its config at startup and only re-reads it when it receives a KConfigBase::Notify D-Bus signal. kwriteconfig6 writes the file but skips sending that signal, so your change just sits there ignored until the next login.
The actual fix: talk to KConfig directly
The real solution is to bypass the CLI tool entirely and use KDE's KConfig API with the Notify flag baked in. That flag is what triggers the D-Bus signal KWin is listening for, so the temperature change applies instantly — no restart, no relogin.
Building the utility
You need two files: a CMakeLists.txt and a small C++ source file.
Install dependencies first.
On Debian/Ubuntu:
sudo apt install cmake g++ extra-cmake-modules \
libkf6config-dev qt6-base-dev
Arch users:
sudo pacman -S cmake gcc extra-cmake-modules \
kconfig qt6-base
Fedora users:
sudo dnf install cmake gcc-c++ extra-cmake-modules \
kf6-kconfig-devel qt6-base-devel
CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(settemp)
find_package(Qt6 REQUIRED COMPONENTS Core)
find_package(KF6Config REQUIRED)
add_executable(settemp settemp.cpp)
target_link_libraries(settemp Qt6::Core KF6::ConfigCore)
settemp.cpp:
#include <KConfig>
#include <KConfigGroup>
#include <QCoreApplication>
#include <cstdio>
#include <cstdlib>
int main(int argc, char* argv[]) {
QCoreApplication app(argc, argv);
if (argc < 2) {
printf("Usage: settemp <temperature>\n");
return 1;
}
int temp = atoi(argv[1]);
if (temp < 1000 || temp > 6500) {
printf("Temperature must be 1000-6500\n");
return 1;
}
KConfig config("kwinrc");
KConfigGroup group(&config, "NightColor");
group.writeEntry("Active", true, KConfigBase::Notify);
group.writeEntry("Mode", "Constant", KConfigBase::Notify);
group.writeEntry("NightTemperature", temp, KConfigBase::Notify);
config.sync();
printf("Set to %dK\n", temp);
return 0;
}
The key line is this one:
group.writeEntry("NightTemperature", temp, KConfigBase::Notify);
That third argument is doing all the work — it's the difference between a value that sits in a file and a value that actually changes what's on your screen.
Build and install:
mkdir build && cd build
cmake ..
make
sudo cp settemp /usr/local/bin/settemp
sudo chmod +x /usr/local/bin/settemp
Using it
settemp 3000 # Warm, anti-blue
settemp 4500 # Slightly warm
settemp 6500 # Neutral daylight
Quick reference if you're not sure where to start:
| Temperature | Description |
|---|---|
| 6500K | Neutral daylight (default) |
| 4500K | Slightly warm |
| 4000K | Warm |
| 3500K | Warm, noticeable blue light reduction |
| 3000K | Very warm (like incandescent bulb) |
| 2700K | Standard anti-blue |
| 2300K | Strong anti-blue (like candlelight) |
| 1900K | Maximum anti-blue (like firelight) |
Wire it into your shell
Add a few aliases to ~/.zshrc or ~/.bashrc so you can flip modes without remembering exact Kelvin values:
# Anti-blue light modes
alias anti-blue-mild="settemp 3000"
alias anti-blue="settemp 2700"
alias anti-blue-strong="settemp 2300"
alias anti-blue-max="settemp 1900"
# Day mode (disable Night Light)
alias day-mode="kwriteconfig6 --file kwinrc --group NightColor --key Active false && qdbus6 org.kde.KWin /KWin reconfigure"
Now anti-blue-strong is one command away instead of three clicks deep in System Settings.
What's actually happening under the hood
The utility writes to ~/.config/kwinrc under the [NightColor] group:
[NightColor]
Active=true
Mode=Constant
NightTemperature=3000
KWin also exposes Night Light over D-Bus, so you can check the live temperature without opening any settings panel:
qdbus6 org.kde.KWin.NightLight /org/kde/KWin/NightLight \
org.freedesktop.DBus.Properties.Get org.kde.KWin.NightLight currentTemperature
That's a handy one-liner to keep around if you ever want to confirm a change actually landed.
Best Practices
- Verify Night Light is enabled first. If nothing changes after running
settemp, double-check System Settings > Display > Night Light is turned on — the utility setsActive=true, but it's worth confirming on a fresh install. - Check compiler and library versions before building. This depends on KDE Frameworks 6 and Qt6; if
cmakefails, it's almost always a missing dev package rather than a code issue. - Use the D-Bus query to debug, not guesswork. If a temperature change doesn't seem to apply, querying
currentTemperatureover D-Bus tells you definitively whether KWin picked it up. - Keep
Mode=Constant. IfModeis left onAutomatic(KDE's default sunrise/sunset schedule), your manual temperature calls will get overridden the next time the schedule ticks over. - Respect the 1000–6500K range. The utility enforces this, but it mirrors KWin's own accepted range — going outside it won't do anything useful even if you hack around the check.
Final Thoughts
This was a fun, self-contained little build — a good reminder that sometimes the "no CLI available" wall in a GUI-first desktop environment is really just a missing wrapper around an API that's been there the whole time. If you want to take this further, the natural next step is wrapping settemp in a systemd timer or cron job to automate warm/cool transitions on a schedule, instead of relying on aliases you have to remember to run.
Credit where it's due: this build is based on the set_KDE_nightlight_temperature utility by Will Avudim, available at codeberg.org/Will_Avudim/set_KDE_nightlight_temperature.