Keyboard backlight

There are two general categories of
keyboard backlight
brightness level control on laptops, depending on the specific hardware:
The backlight is fully handled by the laptop firmware and the operating system sees nothing happening (e.g.
HP EliteBook 745 G4#Function keys
),
The keybind has to be handled by the operating system, with two sub-categories:
The firmware is not involved at all and the raw key sequences is left for the operating system to handle (e.g. what
Toshiba Portege Z30-A#Keyboard backlight control
describes)
The keybind sends a specific
XF86
keysym (like what is described in
ASUS ROG STRIX G17 (2022)#Function keys
).
This can be tested by installing either
xev
(from
xorg-xev
) or
wev
then pressing the backlight control hotkeys:
If you see an
XF86
keysym, for example
XF86KbdBrightnessUp
, then you fall into the "handled by the operating system via keysym" category.
If you see a raw key sequence, for example
key: serial: 4887; time: 8232514; key: 55; state: 1 (pressed) sym: v (118), utf8: 'v'
, then you fall into the "handled by the operating system via raw sequence" category.
If you see nothing at all then you fall into the "handled by firmware" category.
Which category your laptop falls into will impact which method you use to control the backlight.
A pure firmware controlled hotkey should always work and requires no configuration for daily usage. This scenario will complicate scripting as no event is exposed to build upon.
In contrast, either operating system–controlled scenario allows for easier scripting at the detriment of lacking backlight control outside of a running operating system.
Controlling the backlight
Even when the brightness is controlled by firmware, you can adjust the level programmatically. There are a variety ways to manage the brightness level and different helper tools to accomplish this, such as
brightnessctl
or
light
AUR
.
sysfs
The
sys
pseudo-file system exposes an interface to the keyboard backlight. The current brightness level can be obtained by reading
/sys/class/leds/
vendor
::kbd_backlight/brightness
where
vendor
can is replaced depending on the manufacturer, e.g.
tpacpi
for Lenovo (ThinkPads),
asus
for ASUS or
dell
for Dell. For example to get the maximum brightness level:
$ cat /sys/class/leds/
vendor
::kbd_backlight/max_brightness
To set the brightness to 1:
# echo 1 > /sys/class/leds/
vendor
::kbd_backlight/brightness
When using
brightnessctl
you can get a list of available brightness controls with
brightnessctl --list
, then to show the kbd backlight information:
$ brightnessctl --device='
vendor
::kbd_backlight' info
This will show the absolute and relative current value and the maximum absolute value. To set a different value:
$ brightnessctl --device='
vendor
::kbd_backlight' set 1
You can use script to toggle keyboard backlight every call, for example
#!/bin/bash

leds_path="/sys/class/leds"
for dir in "$leds_path"/input*[0-9]::scrolllock; do
    if [ -d "$dir" ]; then
        FILE="$dir/brightness"
        CONTENT=$(cat "$FILE")
        if [ "$CONTENT" = "0" ]; then
            echo "1" > "$FILE"
        elif [ "$CONTENT" = "1" ]; then
            echo "0" > "$FILE"
        fi
        exit 0
    fi
done
xset
Some keyboard manufacturers are not recognized by
brightnessctl
or
light
AUR
, but you can use
xorg-xset
to control its lights if you are running Xorg.
The first parameter
led
turns on the led, and
-led
turns it off, the
NUMBER
parameters accepts integers for 1 to 32 (each number corresponds to a led in you system, keyboards seem to generally be number 3), or 'on' and 'off' (on will turn ALL lights on, and off will turn ALL lights off).
To turn on the lights:
$ xset led NUMBER
To turn off the lights:
$ xset -led NUMBER
D-Bus
You can control your computer keyboard backlight via the
D-Bus
interface. The benefits of using it are that no modification to device files is required and it is vendor agnostic.
The following is an example implementation in Python, requiring
upower
and
python-dbus
to be
installed
. You can then map your keyboard shortcuts to run
/usr/local/bin/kb-light.py +
x
and
/usr/local/bin/kb-light.py -
x
to increase and decrease your keyboard backlight level by
x
amounts.
Tip
You should try with an
x
=
1
to determine the limits of the keyboard backlight levels.
Do not forget to make the script
executable
.
/usr/local/bin/kb-light.py
#!/usr/bin/env python3

import dbus
import sys

def kb_light_set(delta):
    bus = dbus.SystemBus()
    kbd_backlight_proxy = bus.get_object('org.freedesktop.UPower', '/org/freedesktop/UPower/KbdBacklight')
    kbd_backlight = dbus.Interface(kbd_backlight_proxy, 'org.freedesktop.UPower.KbdBacklight')

    current = kbd_backlight.GetBrightness()
    maximum = kbd_backlight.GetMaxBrightness()
    new = max(0, min(current + delta, maximum))

    if 0 <= new <= maximum:
        current = new
        kbd_backlight.SetBrightness(current)

    # Return current backlight level percentage
    return 100 * current / maximum

if __name__ ==  '__main__':
    if len(sys.argv) == 2 or len(sys.argv) == 3:
        if sys.argv[1] == "--up" or sys.argv[1] == "+":
            if len(sys.argv) == 3:
                print(kb_light_set(int(sys.argv[2])))
            else:
                print(kb_light_set(17))
        elif sys.argv[1] == "--down" or sys.argv[1] == "-":
            if len(sys.argv) == 3:
                print(kb_light_set(-int(sys.argv[2])))
            else:
                print(kb_light_set(-17))
        else:
            print("Unknown argument:", sys.argv[1])
    else:
        print("Script takes one or two argument.", len(sys.argv) - 1, "arguments provided.")
Alternatively with
bash
, one can get the current brightness with:
$ dbus-send --type=method_call --print-reply=literal --system --dest="org.freedesktop.UPower" /org/freedesktop/UPower/KbdBacklight org.freedesktop.UPower.KbdBacklight.GetBrightness
To set the brightness to a specific value:
$ dbus-send --system --type=method_call  --dest="org.freedesktop.UPower" "/org/freedesktop/UPower/KbdBacklight" "org.freedesktop.UPower.KbdBacklight.SetBrightness" int32:
value
On GNOME
The following can be run from a terminal or mapped to keybindings
$ gdbus call --session --dest org.gnome.SettingsDaemon.Power --object-path /org/gnome/SettingsDaemon/Power --method org.gnome.SettingsDaemon.Power.Keyboard.StepUp
$ gdbus call --session --dest org.gnome.SettingsDaemon.Power --object-path /org/gnome/SettingsDaemon/Power --method org.gnome.SettingsDaemon.Power.Keyboard.StepDown
On MATE
This article or section needs language, wiki syntax or style improvements. See
Help:Style
for reference.
Reason:
Informal and unclear description. No relevance to MATE. (Discuss in
Talk:Keyboard backlight
)
In case you use
MATE
environment you might get tired with repeated lighting keyboard backlight while logging in, unlocking screen or waking up dimmed display. Following setup prevent from automatic lighting up during any action. The only triggers remain plugging in the adapter and fresh boot. After that you can control keyboard backlight only via hotkeys (eg. ThinkPad Fn + spacebar).
To prevent automatic lighting up just edit file
/usr/share/dbus-1/system.d/org.freedesktop.UPower.conf
as follows (two occurrences of "deny"):
/usr/share/dbus-1/system.d/org.freedesktop.UPower.conf
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->

<!DOCTYPE busconfig PUBLIC
 "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <!-- Only root can own the service -->
  <policy user="root">
    <allow own="org.freedesktop.UPower"/>
  </policy>
  <policy context="default">

    <allow send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.DBus.Introspectable"/>

    <allow send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.DBus.Peer"/>
    <allow send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.DBus.Properties"/>
    <allow send_destination="org.freedesktop.UPower.Device"
           send_interface="org.freedesktop.DBus.Properties"/>
    <deny  send_destination="org.freedesktop.UPower.KbdBacklight"
           send_interface="org.freedesktop.DBus.Properties"/>
    <allow send_destination="org.freedesktop.UPower.Wakeups"
           send_interface="org.freedesktop.DBus.Properties"/>

    <allow send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.UPower"/>
    <allow send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.UPower.Device"/>
    <deny  send_destination="org.freedesktop.UPower"
           send_interface="org.freedesktop.UPower.KbdBacklight"/>
    <allow send_destination="org.freedesktop.UPower"
	   send_interface="org.freedesktop.UPower.Wakeups"/>
  </policy>
</busconfig>
Troubleshooting
Restore after sleep
On some laptops (e.g. Dell XPS 15) the backlight is always off after sleep. In order to restore the previous brightness level you can use the following service.
~/.config/systemd/system/keyboard-brightness.service
[Unit]
Description=Set keyboard brightness after resume
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/sys/class/leds/
vendor
::kbd_backlight/
ExecStart=bash -c "cat brightness >> /var/tmp/kbd_brightness_current"
ExecStop=bash -c "sleep 3s && cat /var/tmp/kbd_brightness_current > brightness && rm /var/tmp/kbd_brightness_current"

[Install]
WantedBy=sleep.target