7

For my i3 window-manager settings, I am looking for a command line tool, similar to xbacklight, but to control the brightness of the leds which are in the keyboard.

Basically, I can set up the leds through a command line, but it requires to be root:

# Light off the leds
echo 0 > /sys/class/leds/smc::kbd_backlight/brightness
# Light on the leds (full power)
echo 100 > /sys/class/leds/smc::kbd_backlight/brightness

I know that it is possible because Gnome3 has support for that, but I do not know exactly how they proceed...

For now, my ~/.config/i3/config looks like this:

# screen brightness controls
bindsym XF86MonBrightnessUp exec xbacklight -inc 10
bindsym XF86MonBrightnessDown exec xbacklight -dec 10

# keyboard backlight controls
#TODO
# XF86KbdBrightnessUp
# XF86KbdBrightnessDown

So, is there a tool, similar to xbacklight to do the same than screen brightness with keyboard backlight? It would be even better if this tool would have the control on both (screen and keyboard).

3 Answers 3

5

Giorgos Keramidas wrote a script that relies in dbus and UPower - which most desktop distros have up and running.

I would recommend using this instead of scripts that write to /sys/class/... as they need to be run as root - either through sudo or a by having SUID set - and that is bad security practice.

Basic usage is as simple as

kbdbacklight up
kbdbacklight down
kbdbacklight [ 0 | 1 | 2 | 3 ]

Add this to the i3 config

# increase/decrease keyboard brightness
bindsym XF86KbdBrightnessUp exec kbdbacklight up
bindsym XF86KbdBrightnessDown exec kbdbacklight down 

The script itself is very simple

#!/bin/sh
# By Giorgos Keramidas

# backlight_get
#       Print current keyboard brightness from UPower to stdout.
backlight_get()
{
    dbus-send --type=method_call --print-reply=literal --system         \
        --dest='org.freedesktop.UPower'                                 \
        '/org/freedesktop/UPower/KbdBacklight'                          \
        'org.freedesktop.UPower.KbdBacklight.GetBrightness'             \
        | awk '{print $2}'
}

# backlight_get_max
#       Print the maximum keyboard brightness from UPower to stdout.
backlight_get_max()
{
    dbus-send --type=method_call --print-reply=literal --system       \
        --dest='org.freedesktop.UPower'                               \
        '/org/freedesktop/UPower/KbdBacklight'                        \
        'org.freedesktop.UPower.KbdBacklight.GetMaxBrightness'        \
        | awk '{print $2}'
}

# backlight_set NUMBER
#       Set the current backlight brighness to NUMBER, through UPower
backlight_set()
{
    value="$1"
    if test -z "${value}" ; then
        echo "Invalid backlight value ${value}"
    fi

    dbus-send --type=method_call --print-reply=literal --system       \
        --dest='org.freedesktop.UPower'                               \
        '/org/freedesktop/UPower/KbdBacklight'                        \
        'org.freedesktop.UPower.KbdBacklight.SetBrightness'           \
        "int32:${value}}"
}

# backlight_change [ UP | DOWN | NUMBER ]
#       Change the current backlight value upwards or downwards, or
#       set it to a specific numeric value.
backlight_change()
{
    change="$1"
    if test -z "${change}" ; then
        echo "Invalid backlight change ${change}."                    \
            "Should be 'up' or 'down'." >&2
        return 1
    fi

    case ${change} in
    [1234567890]|[[1234567890][[1234567890])
        current=$( backlight_get )
        max=$( backlight_get_max )
        value=$( expr ${change} + 0 )
        if test ${value} -lt 0 || test ${value} -gt ${max} ; then
            echo "Invalid backlight value ${value}."                  \
                "Should be a number between 0 .. ${max}" >&2
            return 1
        else
            backlight_set "${value}"
            notify-send -t 800 "Keyboard brightness set to ${value}"
        fi
        ;;

    [uU][pP])
        current=$( backlight_get )
        max=$( backlight_get_max )
        if test "${current}" -lt "${max}" ; then
            value=$(( ${current} + 1 ))
            backlight_set "${value}"
            notify-send -t 800 "Keyboard brightness set to ${value}"
        fi
        ;;

    [dD][oO][wW][nN])
        current=$( backlight_get )
        if test "${current}" -gt 0 ; then
            value=$(( ${current}  - 1 ))
            backlight_set "${value}"
            notify-send -t 800 "Keyboard brightness set to ${value}"
        fi
        ;;

    *)
        echo "Invalid backlight change ${change}." >&2
        echo "Should be 'up' or 'down' or a number between"           \
            "1 .. $( backlight_get_max )" >&2
        return 1
        ;;
    esac
}

if test $# -eq 0 ; then
    current_brightness=$( backlight_get )
    notify-send -t 800 "Keyboard brightness is ${current_brightness}"
else
    # Handle multiple backlight changes, e.g.:
    #   backlight.sh up up down down up
    for change in "$@" ; do
        backlight_change "${change}"
    done
fi

Just save somewhere in your PATH and enjoy. I went with the name kbdbacklight and used it in the examples and i3 config above, please be mindful to update those if you name it differently.

Please note that Giorgio's script also makes use of notify-send, so make sure you have the right package installed (libnotify-bin on Debian and Ubuntu) or comment/remove those lines from the script.

2

Use light:

bindsym XF86KbdBrightnessUp     exec light -k -A 10
bindsym XF86KbdBrightnessDown   exec light -k -U 10

It is available in a packaged version for Arch and Fedora at the moment. But you can always build if from source easily. Find the git repository here: https://github.com/haikarainen/light .

1
  • 1
    it can also replace xbacklight, which sometimes does not work on some distributions
    – patzm
    Sep 2, 2018 at 18:33
1

You could write your own pretty easily.

Create two shell scripts containing the echo lines above somewhere in your path (/usr/local is the normal place). Set the permissions 755 owned by root. Then either edit your sudoers file to allow them to be run as root, or use chmod +s to set them SUID.

This sort of thing is considered a security risk, BTW, so make absolutely sure the permissions are set appropriately. You don't want anyone without root permissions to be able to edit the scripts, and you don't want the scripts to use any input.

It would be trivial to add support for a brightness level flag, but unless you're an accomplished shell scripter I'd recommend against it as a bug in your code would be a security hole.

6
  • Yes, I know. It should be quite easy. But, before trying to do it I was looking for something already done.
    – perror
    Feb 6, 2016 at 20:19
  • Give me a few minutes to figure out github and I'll have a C solution for you. Feb 6, 2016 at 21:38
  • I've written a utility for it. I have minimal testing since I'm on a desktop without keyboard backlighting. Look at github.com/Spauldo/kbd_backlight Feb 6, 2016 at 21:53
  • Actually, only using sudo will work. Setting the SUID bit on shell scripts (or any other kind of script) does not work. At least not in the manner that it allows the script to be run as other user. The reason is that the process that is actually run is /bin/sh or whatever may be set in the #!-line and not the script itself. You would have to set SUID on the shell binary (e.g. /bin/sh) and that most assuredly would be a massive security risk.
    – Adaephon
    Feb 16, 2016 at 7:18
  • You're right, I discovered that myself a few days ago when writing a firewall control script on OpenBSD. The utility I linked to above should work, though. Feb 16, 2016 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .