Framework Laptop 16 — keyboard backlight in GNOME (Fedora 44)
Published 14 June 2026
- date
- env
- linux Fedora 44 (GNOME/Wayland) — Framework Laptop 16, AMD Ryzen AI 300, white Keyboard Module (ISO) macos N/A
- tags
The step-by-step Framework doesn’t ship. Tailored to: FW16 (AMD Ryzen AI 300), white Keyboard Module - ISO, Fedora 44, GNOME/Wayland. Last updated: 2026-06-14.
Why this is needed (and why there’s no official guide)
On the FW16 the keyboard is a self-contained QMK/VIA device with its own MCU,
deliberately not driven by the embedded controller (EC). That’s what makes the
input modules hot-swappable and reflashable — but it means the keyboard looks like
a generic USB HID gadget to Linux and is not exposed as a standard
org.freedesktop.UPower.KbdBacklight device. So GNOME’s Quick Settings slider,
the keyboard-brightness keys, and brightnessctl can’t see it out of the box.
Framework provides no first-party daemon for this on Linux; their engineer (DHowett) said it’s left to community efforts. This guide builds that bridge.
Important trap: framework_tool --kblight does NOT work here
framework_tool --kblight 80 will report 80% but the keys stay dark — it
writes an EC-side value that never reaches the QMK keyboard on the FW16. The tool
that actually drives the LEDs is qmk_hid (talks to the keyboard over HID).
How it works
GNOME slider / brightness keys → UPower.KbdBacklight.SetBrightness → /sys/class/leds/framework16::kbd_backlight/brightness (kernel: uleds) → bridge daemon (reads the value) → qmk_hid via --backlight <0-100> → QMK keyboard LEDsUPower auto-discovers any LED whose name contains kbd_backlight, so creating a
virtual one via the kernel uleds interface is enough for native GNOME control.
Step 0 — Sanity check (no install)
Press Fn + Space a few times. This is the QMK hotkey that cycles backlight effects/brightness; one state is fully off. Make sure the keys can glow at all before blaming software.
Step 1 — Install qmk_hid
Not in Fedora repos. Use the official prebuilt binary:
- Download the Linux asset from https://github.com/FrameworkComputer/qmk_hid/releases
- Install it:
Terminal window chmod +x qmk_hidsudo install -m755 qmk_hid /usr/local/bin/qmk_hidqmk_hid --version
(Alternative — build it: sudo dnf install systemd-devel hidapi-devel then
cargo install --git https://github.com/FrameworkComputer/qmk_hid, then copy
~/.cargo/bin/qmk_hid to /usr/local/bin/.)
Step 2 — Verify the backend actually lights the keyboard
sudo qmk_hid via --backlight 80 --save # --save = persist across kbd power-cycleThe keys should light to ~80%. If they don’t, stop here — the bridge can’t work until this single command does. (Re-check Step 0, firmware version, and that you have the keyboard — not just the macropad — connected.)
Step 3 — Install the bridge daemon + service
The corrected files are staged in ~/Downloads/:
fw16-kbd-backlight-bridge.py(white-keyboard backend,qmk_hid via --backlight)fw16-kbd-backlight.service
cd ~/Downloadssudo install -m755 fw16-kbd-backlight-bridge.py /usr/local/bin/fw16-kbd-backlight-bridge.pysudo install -m644 fw16-kbd-backlight.service /etc/systemd/system/fw16-kbd-backlight.serviceecho uleds | sudo tee /etc/modules-load.d/uleds.confsudo modprobe uledssudo systemctl daemon-reloadsudo systemctl enable --now fw16-kbd-backlight.servicesudo systemctl restart upower # only needed the FIRST time (UPower scans /sys/class/leds at startup)On later boots, the service’s Before=upower.service ordering means the virtual
LED already exists when UPower starts — no restart needed.
Step 4 — Verify GNOME integration
ls /sys/class/leds/ | grep kbd_backlight# -> framework16::kbd_backlight
gdbus call --system --dest org.freedesktop.UPower \ --object-path /org/freedesktop/UPower/KbdBacklight \ --method org.freedesktop.UPower.KbdBacklight.GetMaxBrightness# -> (100,)Then the GNOME Quick Settings keyboard-backlight slider and the keyboard-brightness keys should drive the keyboard.
Troubleshooting
journalctl -u fw16-kbd-backlight.service -b- Slider/LED node missing right after install → you skipped
sudo systemctl restart upower(one-time). qmk_hid failedin the journal → confirm/usr/local/bin/qmk_hidexists and Step 2 works manually; checkqmk_hid via --helpfor the exact flag names of your version.- After resume from sleep the backlight doesn’t come back — known FW16
firmware behavior, independent of this bridge. Quick fix:
sudo systemctl restart fw16-kbd-backlight. To automate, add the optional sleep hook below.
Optional: re-arm after sleep
Create /etc/systemd/system/fw16-kbd-backlight-resume.service:
[Unit]Description=Re-arm FW16 keyboard backlight bridge after resumeAfter=suspend.target hibernate.target hybrid-sleep.target
[Service]Type=oneshotExecStart=/usr/bin/systemctl restart fw16-kbd-backlight.service
[Install]WantedBy=suspend.target hibernate.target hybrid-sleep.targetsudo systemctl daemon-reloadsudo systemctl enable fw16-kbd-backlight-resume.serviceNotes / design choices
- The daemon does not pass
--saveon every slider change: GNOME/UPower restores the last brightness at login, so writing the keyboard’s EEPROM on each tick would only add flash wear. Use--savemanually if you want a value to survive a keyboard power-cycle. uledsstruct used:char name[64]+int max_brightness(4-byte int read back for brightness) — matches the Fedora 44 kernel UAPI.- A packaged equivalent exists on Arch (
fw16-kbd-uleds-git); this is the hand-rolled Fedora version of the same idea.
Alternatives considered
framework_tool --kblight— reads/writes EC state; does not light the FW16 keyboard (EC is not wired to the QMK keyboard). Useful for other EC functions, not this.keylightdand other EC-based daemons — FW13-era, EC-driven; don’t apply to the FW16’s separate QMK keyboard.
Sources
- Framework Community — DHowett: FW16 keyboard is a separate QMK device, not EC-controlled: https://community.frame.work/t/linux-keyboard-backlight-support/59158/2
- FrameworkComputer/qmk_hid (
--backlight,--save, FW16 modules): https://github.com/FrameworkComputer/qmk_hid - FrameworkComputer/framework-system (
--kblight, EC-side): https://github.com/FrameworkComputer/framework-system/blob/main/EXAMPLES.md - ArchWiki — Framework Laptop 16: https://wiki.archlinux.org/title/Framework_Laptop_16
- AUR — fw16-kbd-uleds-git (packaged bridge): https://aur.archlinux.org/packages/fw16-kbd-uleds-git
- UPower — KbdBacklight interface: https://upower.freedesktop.org/docs/KbdBacklight.html
- Kernel docs — userspace LEDs (uleds): https://docs.kernel.org/leds/uleds.html