I finally figured out an answer that at least works on my systems (a Lenovo ThinkPad X201 and a ThinkPad X201 Tablet, which both use LVDS panels). It actually disables the backlight, but unless you have a transflective or reflective LCD (which is pretty unusual), it should effectively be the same as having the LCD switched off.
First, I installed Intel GPU Tools (README here for more information). In debian, this was done with:
# apt-get install intel-gpu-tools
This package contains a program called intel_backlight
, which directly interacts with Intel GPUs' registers and thus is not limited to the 'safe range' in modern Linux kernels' sysfs
filesystem, where brightness level 0 is always supposed to be 'on at a low level of brightness.'
Unfortunately, this program needs to be run as root, and it doesn't really sanitize its inputs very well (it just blindly atoi()
's the first argument to the script and assumes it's actually a number). I'm still working on a proper solution to this, but for now your options are to either:
- Run this as root
- Write a script and acpid configuration to trigger it upon a specific ACPI event.
I chose the latter option. I picked a key combination which acpi_listen
detected as firing an ACPI event, but which was not mapped to do anything already on my laptop. I chose fn+f1. Theoretically, one could also have it fire on the brightness-down key, check if the brightness was already at the minimum, and if so turn off the backlight.
I wrote the following files:
/etc/acpi/events/fnf1-toggle-lcd:
event=button/fnf1
action=/etc/acpi/toggle-thinklight-or-tablet-lcd.sh "%e"
/etc/acpi/toggle-thinklight-or-tablet-lcd.sh:
#! /bin/bash
# intel_backlight appears to require root privs.
# is the light on or off?
export INTEL_BACKLIGHT="/usr/bin/intel_backlight"
export light_state=$("$INTEL_BACKLIGHT" | sed 's/current backlight value: //g'|sed 's/%//g')
if [ "$light_state" -eq 0 ]; then # if the backlight is currently off
# restore brightness level
cat /root/brightness > /sys/class/backlight/acpi_video0/brightness
else # the backlight is currently on
# back up current brightness level
cat /sys/class/backlight/acpi_video0/brightness > /root/brightness
# turn off backlight
"$INTEL_BACKLIGHT" 0
fi
Be sure the shell script is marked as executable.
Maybe not exactly what was wanted, and I know I'm late to the party, but it's working here.
Alternatively, on eDP panels, doing echo 0 > /sys/class/backlight/acpi_video0/bl_power
might work. This absolutely will not work on LVDS panels, because apparently some kernel developers thought that was a good idea.