Wednesday, June 15, 2016

Screen brightness using Fn keys in i3wm on Lenovo Thinkpad X260

Note: this is a first draft, I just want to jot down what  I currently have.

I got a new laptop for work, Lenovo Thinkpad X260. Installed Ubuntu 16.04 Xenial Xerus without much problem.
There are several Fn-hotkeys for the F1-F12 keys, most of them do not work out of the box in Ubuntu, at least not when running i3-window manager.
I managed to solve it in the end. This is how. Part of this solution is from
http://ttrmw.co.uk/linux/hardware_button_brightness.html
Thanks for that!

Changing the brightness

I figured out that the brightness can be changed with

$ sudo echo VALUE > /sys/class/backlight/intel_backlight/brightness

where VALUE is between 0 and what is given by the output

$ cat /sys/class/backlight/intel_backlight/max_brightness

These paths might be different for you, so you have to figure it out, and edit the paths in the script below to fit your needs.

The script

So I created a script that changes the brightness, as mentioned it borrows heavily from the above mentioned page, but there are some changes.

I save it as brightness_control in some place, perhaps in your bin folder or something.
The script is as follows:

#!/bin/bash

# script to control the brightness of a Lenovo Thinkpad X260
# in i3wm (Ubuntu Linux)
# Magnus Persson, with help from 
# http://ttrmw.co.uk/linux/hardware_button_brightness.html

# how much we change the brightness is the input parameter
change=$1
echo $change

# get the maximum brightness value
max_brightness=$(cat /sys/class/backlight/intel_backlight/max_brightness)

echo $max_brightness
# get the current brightness
brightness=$(cat /sys/class/backlight/intel_backlight/brightness)
echo $brightness

# calculate the new value that is requested.
# if input is negative it will subtract (?)
new_value=$(($brightness + $change))
echo $new_value

# if the new value is less than 1, we just set it to 1
# 0 is completely pitch black, just put pc to sleep
# if you want that.
if (( $new_value < 10 )); then  
        let brightness=10
# if the new value is greater than max brightness, set it to max brightness
elif  (($new_value > $max_brightness)); then
        let brightness=$max_brightness
# if none of the above if-statements are true, just set it to the 
# new brightness value
else
        let brightness=$new_value
fi

# now we can just echo the value into the brightness acpi(?) file
echo $brightness > /sys/class/backlight/intel_backlight/brightness #| bash #or zsh, csh or whateva

As you might see the main difference from the linked source, it takes an input argument, how much to lower or increase the brightness, no need for several scripts for up/down in brightness. If you do not have so many levels, i.e. if the output of the max brightness is very low, you have to change the value "10" that I have in the script, it is just to set the lowest possible level, so the screen wont go completely black because the brightness goes down to 0. Be careful.

To run the program it needs super user (sudo) privileges. So to run it without it we need to add it to the visudo file. To do this, run

$ sudo visudo 

and add, to the end of the file

your_user your_machine = NOPASSWD: /path/to/brightness_control

Now this makes it possible to run the script as before, but it wont ask for a password
(i.e. $ sudo ./brightness_control -400, to lower the brightness 400 units )

HOWEVER, this is a bit un-secure because if anyone edits your file, they can run whatever they want!

Give your file to root

Soooo we just give it to the root user

$ sudo chown root:root brightness_control

and

$ sudo chmod 0711 brightness_control

now you can run the script without filling in the password, but to edit it you need to put the sudo password in.


i3 window manager

Now you can start xev and klick your brightness up/down keys (with Fn), or you run

$ xmodmap -pk | grep Brightness

For me it shows

    232     0x1008ff03 (XF86MonBrightnessDown) 0x0000 (NoSymbol) 0x1008ff03 (XF86MonBrightnessDown)
    233     0x1008ff02 (XF86MonBrightnessUp) 0x0000 (NoSymbol) 0x1008ff02 (XF86MonBrightnessUp)
    237     0x1008ff06 (XF86KbdBrightnessDown) 0x0000 (NoSymbol) 0x1008ff06 (XF86KbdBrightnessDown)
    238     0x1008ff05 (XF86KbdBrightnessUp) 0x0000 (NoSymbol) 0x1008ff05 (XF86KbdBrightnessUp)

Here Mon is for monitor, and Kbd for keyboard (the backlit keyboard).

Now I have in my $HOME/.config/i3/config file

# Brightness control (without any fuzz)
bindsym XF86MonBrightnessUp exec --no-startup-id sudo /home/magnusp/scripts/brightness_control +100
bindsym XF86MonBrightnessDown exec --no-startup-id sudo /home/magnusp/scripts/brightness_control -100

Here you can change the number, "100" to whatever fits your hardware.

Done, Shift+Super+r, to reload i3 and then just hit brightness up/down to control brightness on your X260 in the awesome i3 tiling window manager.



No comments:

Post a Comment