User:Dungeonseeker
Introduction
There appears to be 2 general categories of hardware backlight control that exist on laptops dependant on the specific hardware:
- The backlight is fully handled by the laptop firmware and the OS sees nothing happening (e.g. HP EliteBook 745 G4#Function keys),
- The keybind has to be handled by the OS.
When the keybind is handled by the OS there are two further possibilities:
- The firmware is not involved at all and the raw key sequences is left for the OS to handle (e.g. what Toshiba Portege Z30-A#Keyboard backlight control describes)
- The keybind sends a specific
XF86
keysym (like what's described in ASUS ROG STRIX G17 (2022)#Function keys).
This can easily be tested by installing either xev or wev then pressing the backlight control hotkeys on your laptop.
- If you see an
xf86
keysym, for examplexf86KbdBrightnessUp
, then you fall into the handled by the OS category 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 OS category via raw sequence category.
- If you see an 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 will always work and should require no extra configuration at all however this scenario will also present issues if you wish to use scripting to control the backlight as the OS is never involved at all and as such, any scripts set to run on changes will never fire.
In contrast to that, either OS controlled scenario allows for easier scripting at the detriment of having backlight control outside of a running OS.
Controlling the backlight
There are various methods to control the keyboard backlight brightness level and different helpers tools to accomplish this, such as brightnessctl or light.
The sys
pseudo-file system exposes an interface to the keyboard backlight. The current brightness level can be obtained by reading /sys/class/leds/tpacpi::kbd_backlight/brightness
. For example to get the maximum brightness level:
$ cat /sys/class/leds/tpacpi::kbd_backlight/max_brightness
To set the brightness to 1:
# echo 1 > /sys/class/leds/tpacpi::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='tpacpi::kbd_backlight' info
This will show the absolute and relative current value and the maximum absolute value. To set a different value:
$ brightnessctl --device='tpacpi::kbd_backlight' set 1
xset
Some keyboard manufactores are not recognized by brightnessctl or light, 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 3. Install upower and dbus-python packages then place the following script in /usr/local/bin/
and make it executable. 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.
1
to determine the limits of the keyboard backlight levels/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 the following bash one-liner will set the backlight to the value specified in the argument:
setKeyboardLight () { dbus-send --system --type=method_call --dest="org.freedesktop.UPower" "/org/freedesktop/UPower/KbdBacklight" "org.freedesktop.UPower.KbdBacklight.SetBrightness" int32:$1 }
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
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>