Skip to content
← Back to projects

Omarchy Rgb Keyboard

Keyboard RGB backlight control for Avell/Clevo laptops as an Omarchy bar widget: presets, brightness and animated effects

#omarchy-rgb-keyboard

Keyboard RGB backlight control for Avell (rebadged Clevo) laptops, as an Omarchy shell bar widget: colour presets, brightness, and animated effects, all from the bar.

Ported from rgb-keyboard-avell-control, a PyQt6 desktop app written for Ubuntu.

Tested on an Avell A50i — Clevo board, Intel i5-13420H, kernel 7.1, single-zone keyboard, Omarchy/Hyprland. Other Clevo-based machines are likely to work, since the driver and the LED interface are the same, but they have not been verified.

#What it does

  • 9 colour presets and a live brightness slider
  • 8 animated effects: rainbow, wave, breathing, pulse, strobe, fire, ocean, matrix
  • A rgbctl CLI, usable on its own without the widget
  • No sudo at runtime — a udev rule grants the wheel group write access to the LED once, so nothing has to prompt for a password from inside the bar

#Requirements

  • Omarchy (Hyprland + the Quickshell-based omarchy-shell)
  • tuxedo-drivers-dkms (AUR)
  • A Clevo-based laptop whose kernel driver exposes /sys/class/leds/rgb:kbd_backlight

Developed and verified on an Avell A50i (Clevo board, i5-13420H, kernel 7.1, single-zone keyboard). The three-zone path in rgbctl is written from the driver's source (clevo_leds.h registers rgb:kbd_backlight, _1 and _2) but has not been exercised on real three-zone hardware.

#Installing the driver is not enough

tuxedo-drivers 4.x gates every module behind tuxedo_is_compatible() in tuxedo_compatibility_check.c. That check approves a machine only when DMI names TUXEDO as the vendor, or when the CPU appears on a list that stops at Intel's 12th generation. An Avell A50i reports vendor Avell and carries an i5-13420H (family 6, model 186 — Raptor Lake-P), so it fails both arms: tuxedo_keyboard aborts its init with -ENODEV, and clevo_acpi — which depends on it — never loads.

The visible symptom is tuxedo_compatibility_check sitting alone in lsmod with refcount 0, and no LED anywhere under /sys/class/leds.

The gate is a vendor policy, not a hardware limit. The ACPI device CLV0001:00 and the Clevo WMI GUIDs ABBC0F6B/6C/6D are all present on this machine — exactly the aliases clevo_acpi and clevo_wmi declare. Adding Avell to the DMI table is enough to make the stock driver bind and work.

#Install

git clone https://github.com/wallacemartinss/omarchy-rgb-keyboard \
  ~/.config/omarchy/plugins/wallace.rgb-keyboard

# Patch the DMI gate, rebuild the DKMS module, load it, install the udev rule
sudo bash ~/.config/omarchy/plugins/wallace.rgb-keyboard/patches/enable-rgb.sh

# Optional but recommended: survive package upgrades (see below)
sudo bash ~/.config/omarchy/plugins/wallace.rgb-keyboard/patches/enable-rgb.sh --install-hook

Then add the widget to the bar:

omarchy bar put wallace.rgb-keyboard --section right

If the icon does not appear, restart the shell — a hot reload does not invalidate already-compiled QML:

omarchy restart shell

#Surviving upgrades

Every tuxedo-drivers-dkms upgrade replaces /usr/src and takes the DMI patch with it, which would silently kill the backlight at the next boot. The --install-hook flag writes /etc/pacman.d/hooks/95-tuxedo-drivers-avell.hook, which re-runs the patch script post-transaction. The hook calls the script where it lives rather than keeping a copy, so the two cannot drift, and the path is resolved at install time so a clone in any location works.

enable-rgb.sh is idempotent, keeps a .orig of the source file it edits, and skips the DKMS rebuild when the module already on disk carries the patch.

#Manual use

scripts/rgbctl status
scripts/rgbctl set 255 0 0
scripts/rgbctl brightness 120
scripts/rgbctl effect rainbow 0.05
scripts/rgbctl stop
scripts/rgbctl off

On three-zone keyboards the driver registers rgb:kbd_backlight, _1 and _2. rgbctl writes every zone together, so the widget stays a single colour picker rather than three.

#What did not carry over from the original app

The reactive typing modes (ripple, explosion, trail) are gone. They rely on pynput, which captures keystrokes through Xlib. Under Wayland an ordinary process cannot see global key events, so on Hyprland those effects would capture nothing. Restoring them needs a different mechanism entirely — a Hyprland keybind, or a libinput reader in the compositor's privileged path — not a port.

The PyQt6 GUI, system tray and profile store are replaced by the bar widget and the shell's own settings; they were the desktop app's shell, not its feature.

#Layout

manifest.json           Omarchy plugin manifest
Panel.qml               Bar widget and its popup panel
scripts/rgbctl          Standalone CLI; the widget shells out to this
patches/enable-rgb.sh   DMI patch, DKMS rebuild, udev rule, pacman hook

#Permissions

Writes go through /etc/udev/rules.d/99-rgb-kbd-backlight.rules, which grants the wheel group write access to the LED's brightness and multi_intensity attributes. The original app used sudo tee; a shell plugin has no terminal to prompt in, so the privilege is granted once at the device instead.

#License

MIT — see LICENSE.

New version available.