The problem
I use a Razer Blade on Fedora. Razer Synapse — the official software for managing RGB and profiles — only runs on Windows and macOS. On Linux: nothing.
openrazer exists: it's an open-source kernel driver that exposes an API to control Razer peripherals. There's even a GUI to go with it, Polychromatic. Except Polychromatic has been in minimal maintenance for a while and poorly supports my exact laptop model.
I spent an evening looking for an alternative. Then I spent a weekend writing my own.
How Linux talks to peripherals: D-Bus
On Linux, applications often communicate with each other via D-Bus — a system message bus. openrazer exposes its API this way: when you want to change the color of a key, you don't write directly to a hardware register, you send a D-Bus message to the openrazer daemon which handles it.
It's abstract but practical: any language that knows how to speak D-Bus can control the peripherals. In Python, it takes a few lines. The interface receives the event "user chose this color for this key", sends the D-Bus message, the daemon applies the color. The latency is low enough for smooth live preview.
Per-key RGB and PySide6
The Razer Blade supports per-key lighting: each key can have its own color independently. openrazer exposes this as a matrix — rows × columns, one RGB color per cell.
For the interface, I chose PySide6: the official Python bindings for Qt6. Qt allows creating custom widgets cleanly, handling events without fighting the framework, and making applications that look like something on native Linux.
The detail that makes the tool pleasant: the keyboard layout displayed in real time in the UI, updating as you choose colors in the color picker. It seems obvious, but many RGB config tools have an "Apply" button and a static preview. Seeing the color change live during selection completely changes the experience.
Temperatures, battery, performance profiles
Since the tool was open anyway, I centralized system monitoring too.
CPU and GPU temperatures come from sysfs — the Linux virtual filesystem that exposes hardware data. /sys/class/thermal/ contains one file per thermal sensor, you just need to read it. Battery goes through upower, a system daemon that aggregates the state of all power sources. Performance profiles (balanced, performance, quiet) use the kernel's DMI interfaces.
All of this refreshes every 2 seconds via QTimer. The app has been running in the background for months without detectable memory leaks. That's the kind of silent compliment a system tool gives itself.