Backlight
Screen brightness might be tricky to control. On some machines physical hardware switches are missing and software solutions may not work well. However, it is generally possible to find a functional method for a given hardware. This article aims to summarize all possible ways to adjust the backlight.
Contents
Overview
There are many ways to control brightness of a monitor, laptop or integrated panel (such as the iMac). According to these discussions and this wiki page the control method can be divided into these categories:
- brightness is controlled by vendor-specified hotkey and there is no interface for the OS to adjust the brightness.
- brightness is controlled by either the ACPI, graphic or platform driver.
- brightness is controlled by HW register through setpci.
All methods are exposed to the user through /sys/class/backlight
and xrandr/xbacklight can choose one method to control brightness. It is still not very clear which one xbacklight prefers by default.
ACPI
The brightness of the screen backlight is adjusted by setting the power level of the backlight LEDs or cathodes. The power level can often be controlled using the ACPI kernel module for video. An interface to this module is provided via a sysfs directory at /sys/class/backlight/
.
The name of the directory depends on the graphics card model.
$ ls /sys/class/backlight/
acpi_video0
In this case, the backlight is managed by an ATI graphics card. In the case of an Intel card, the directory is called intel_backlight
. In the following examples, acpi_video0
is used. If you use an Intel card, simply replace acpi_video0
with intel_backlight
in the examples.
The directory contains the following files and subdirectories:
$ ls /sys/class/backlight/acpi_video0/
actual_brightness brightness max_brightness subsystem/ uevent bl_power device/ power/ type
The maximum brightness can be displayed by reading from max_brightness
, which is often 15.
$ cat /sys/class/backlight/acpi_video0/max_brightness
15
The brightness can be set by writing a number to brightness
. Attempting to set a brightness greater than the maximum results in an error.
# echo 5 > /sys/class/backlight/acpi_video0/brightness
By default, only root
can change the brightness by this method. To allow users in the video
group to change the brightness, a udev rule such as the following can be used:
/etc/udev/rules.d/backlight.rules
ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="acpi_video0", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness" ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="acpi_video0", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
Kernel command-line options
Sometimes ACPI does not work well due to different motherboard implementations and ACPI quirks. This results in, for instance, inaccurate brightness notifications. This includes some laptops with dual graphics (e.g., Nvidia/Radeon dedicated GPU with Intel/AMD integrated GPU). Additionally, ACPI sometimes needs to register its own acpi_video0
backlight even if one already exists (such as intel_backlight
), which can be done by adding one of the following kernel parameters:
acpi_backlight=video acpi_backlight=vendor acpi_backlight=native
If you find that changing the acpi_video0
backlight does not actually change the brightness, you may need to use acpi_backlight=none
.
- On Nvidia Optimus laptops, the kernel parameter
nomodeset
can interfere with the ability to adjust the backlight. - On an Asus notebooks you might also need to load the
asus-nb-wmi
kernel module. - Disabling legacy boot on Dell XPS13 breaks backlight support.
Udev rule
If the ACPI interface is available, the backlight level can be set at boot using a udev rule:
/etc/udev/rules.d/81-backlight.rules
# Set backlight level to 8 SUBSYSTEM=="backlight", ACTION=="add", KERNEL=="acpi_video0", ATTR{brightness}="8"
OLED screen brightness
If using a desktop environment or a laptop with an OLED screen, you may notice the backlight does not function (the brightness control keys toggles the on-screen display and the brightness values can be manually adjusted in /sys/class/backlight/intel_backlight
, but it doesn't change the actual brightness level of the screen). Since the screen is OLED (which do not have physical backlights) and until brightness control for OLED screens is supported by the kernel, you may need to shim the ACPI backlight functions to update Xrandr's "--backlight" option. This is done by monitoring the acpi_video0 (or intel_backlight) levels, and updating the xrandr brightness levels accordingly.
For this to work, you must first install inotify-tools and bc. Then, create the following file:
$ cat /usr/local/bin/xbacklightmon
#!/bin/sh #use LC_NUMERIC if you are using an European LC, else printf will not work because it expects an comma instead of a decimal point LC_NUMERIC="en_US.UTF-8" # modify this path to the location of your backlight class path=/sys/class/backlight/intel_backlight # get name of primary screen to adjust brightness primaryOutput=$(xrandr | grep -E " connected primary ?[1-9]+" | sed -e "s/\([A-Z0-9]\+\) connected.*/\1/") luminance() { read -r level < "$path"/actual_brightness factor=$((max)) new_brightness="$(bc -l <<< "scale = 2; $level / $factor")" printf '%f\n' $new_brightness } read -r max < "$path"/max_brightness xrandr --output $primaryOutput --brightness "$(luminance)" inotifywait -me modify --format '' "$path"/actual_brightness | while read; do xrandr --output $primaryOutput --brightness "$(luminance)" done
Then make this file executable and owned by root:
$ chown root:root /usr/local/bin/xbacklightmon $ chmod 755 /usr/local/bin/xbacklightmon
You may test this by running the file, and using the backlight keys to test if the brightness updates. Finally, configure the script to run when you display manager starts.
While all this fixes brightness issues on laptops with OLED screens, there might still be some issues showing up, e.g.:
- Chromium and some other programs reset brightness to 100% upon their first start since reboot.
- Hotkeys aren't working prior to login.
Backlight with OLED screen in Wayland
The above xrandr based script and commands do not work on Wayland.
Instead you can use the icc-brightness
tool to control the OLED display brightness by applying ICC color profiles (this approach works both in xorg and wayland).
The tool can be found and downloaded here: https://github.com/udifuchs/icc-brightness
Switch off the backlight
Switching off the backlight (for example when one locks a notebook) can be useful to conserve battery energy. Ideally the following command should work for any Xorg graphical session:
xset dpms force off
The backlight should switch on again on mouse movement or keyboard input. Alternately xset s
could be used.
The following example will toggle the screen saver timeout for a similar result (should be bound to a key):
~/.local/bin/xlcd.sh
#!/usr/bin/dash read lcd < /tmp/lcd if [ "$lcd" -eq "0" ]; then xset s echo 1 > /tmp/lcd sleep 1 notify-send -t 2000 LCD\ ON else xset s 3 echo 0 > /tmp/lcd notify-send -t 2000 LCD\ OFF fi
If the previous commands do not work, there is a chance that vbetool may work. Note, however, that in this case the backlight must be manually activated again. The command is as follows:
$ vbetool dpms off
To activate the backlight again:
$ vbetool dpms on
For example, this can be put to use when closing the notebook lid using Acpid.
Save/Restore functionality
The systemd package includes the service systemd-backlight@.service
, which is enabled by default and "static". It saves the backlight brightness level at shutdown and restores it at boot. The service uses the ACPI method described in #ACPI, generating services for each folder found in /sys/class/backlight/
. For example, if there is a folder named acpi_video0
, it generates a service called systemd-backlight@backlight:acpi_video0.service
. When using other methods of setting the backlight at boot, it is recommended to stop systemd-backlight from restoring the backlight by setting the kernel parameters parameter systemd.restore_state=0
. See systemd-backlight@.service(8) for details.
systemd-backlight@backlight:acpi_video1
for acpi_video1
).The relightAUR package provides an alternative systemd-based method of saving and restoring screen brightness.
Additionally, the brilloAUR and light utilities support save/restore functionality. These two may be more useful if one wishes to restore the screen brightness on a per-user basis, however no systemd units are provided to accomplish this.
Backlight utilities
The utilities in the following table can be used to control screen brightness. All of them are compatible with Wayland and do not require X.
Name | Controls keyboard backlights | Reacts to ambient brightness | Language | License | Notes | Package | Homepage |
---|---|---|---|---|---|---|---|
acpilight | Yes | No | Python3 | GPL-3.0-or-later | "xbacklight" compatible | acpilight | https://gitlab.com/wavexx/acpilight |
brightd | No | No | C | GPL-2.0 | Dims the screen when there is no user input for some time. | brightdAUR | http://www.pberndt.com/Programme/Linux/brightd |
brillo | Yes | No | C | GPL-3.0-only | Supports smooth and relative adjustments. | brilloAUR | https://gitlab.com/cameronnemo/brillo |
brightnessctl | Yes | No | C | MIT | Binary is setuid unless otherwise configured. | brightnessctl | https://github.com/Hummer12007/brightnessctl |
Calise | No | Yes | Python2 | GPL-3.0 | - | caliseAUR | http://calise.sourceforge.net |
Clight | Yes | Yes | C | GPL-3.0-or-later | Manages screen temperature and smoothly dims brightness after a timeout. Turns webcam into an ambient light sensor. | clightAUR | https://github.com/FedeDP/Clight |
macbook-lighter | Yes | Yes | Bash,Perl | GPL | Macbook screen/keyboard backlight CLI and auto-adjust on ambient light. | macbook-lighterAUR | https://github.com/harttle/macbook-lighter |
enlighten | No | No | C | GPL-3.0-or-later | - | enlighten-gitAUR | https://github.com/HalosGhost/enlighten |
illum | No | No | C | AGPL-3.0 | Reacts to key presses. | illum-gitAUR | https://github.com/jmesmon/illum |
Light | Yes | No | C | GPL-3.0-only | Binary is setuid unless otherwise configured. | light | https://haikarainen.github.io/light |
Lux | No | No | Shell | MIT | - | luxAUR | https://github.com/Ventto/lux |
xbacklight
Brightness can be set using the xorg-xbacklight package.
To set brightness to 50% of maximum:
$ xbacklight -set 50
Increments can be used instead of absolute values, for example to increase or decrease brightness by 10%:
$ xbacklight -inc 10 $ xbacklight -dec 10
Gamma can be set using either the xorg-xrandr or xorg-xgamma package. The following commands create the same effect:
$ xrandr --output LVDS1 --gamma 1.0:1.0:1.0 $ xgamma -rgamma 1 -ggamma 1 -bgamma 1
If you get the "No outputs have backlight property" error, it is because xrandr/xbacklight does not choose the right directory in /sys/class/backlight
. You can specify the directory by setting the Backlight
option of the device section in /etc/X11/xorg.conf.d/20-video.conf
. For instance, if the name of the directory is intel_backlight
and using the Intel driver, the device section may be configured as follows:
/etc/X11/xorg.conf.d/20-intel.conf
Section "Device" Identifier "Intel Graphics" Driver "intel" Option "Backlight" "intel_backlight" EndSection
See FS#27677 and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=651741 for details.
If you have enabled Intel Fastboot you might also get the No outputs have backlight property
error. In this case, trying the above method may cause Xorg to crash on start up. You should disable it to fix the issue. It is known to cause issues with brightness control.
setpci
It is possible to set the register of the graphic card to adjust the backlight. It means you adjust the backlight by manipulating the hardware directly, which can be risky and generally is not a good idea. Not all of the graphic cards support this method.
When using this method, you need to use lspci
first to find out where your graphic card is.
# setpci -s 00:02.0 F4.B=0
Using DBus with Gnome
Brightness can also be adjusted as the gnome controls do. Changes are reflected in the gnome UI using this method.
gdbus call --session --dest org.gnome.SettingsDaemon.Power --object-path /org/gnome/SettingsDaemon/Power --method org.freedesktop.DBus.Properties.Set org.gnome.SettingsDaemon.Power.Screen Brightness "<int32 50>"
Steps in brightness for keyboard contol can be implemented with this method as well.
gdbus call --session --dest org.gnome.SettingsDaemon.Power --object-path /org/gnome/SettingsDaemon/Power --method org.gnome.SettingsDaemon.Power.Screen.StepUp gdbus call --session --dest org.gnome.SettingsDaemon.Power --object-path /org/gnome/SettingsDaemon/Power --method org.gnome.SettingsDaemon.Power.Screen.StepDown
Color correction
- Clight — User daemon utility that aims to fully manage your display. It can manage the screen temperature depending on the current time of the day, just like redshift does. It tries to use geoclue to retrieve the user position if neither latitude or longitude are set in the configuration file. It also supports fixed times for sunrise and sunset.
- Monica — Monitor calibration tool. It works as frontend to xgamma to alter the gamma correction.
- Redshift — Color temperature adjustment tool. It adjusts the color temperature of your screen according to your surroundings. This may help your eyes hurt less if you are working in front of the screen at night. This program is inspired by f.lux.
- xcalib — Lightweight monitor calibration loader which can load an ICC monitor profile to be shared across desktop applications.
- xgamma — Alter a monitor's gamma correction.
xcalib
xcalib -clear
to reset the LUT.The package xcalibAUR (upstream URL) is available in the AUR and can be used to dim the screen. A demonstration video is available on YouTube. This program can correct gamma, invert colors, and reduce contrast, the latter of which we use in this case. For example, to dim down:
$ xcalib -co 40 -a
This program uses ICC technology to interact with X11 and while the screen is dimmed, you may find that the mouse cursor is just as bright as before.
NVIDIA settings
Users of NVIDIA's proprietary drivers users can change display brightness via the nvidia-settings utility under "X Server Color Correction." However, note that this has absolutely nothing to do with backlight (intensity), it merely adjusts the color output. (Reducing brightness this way is a power-inefficient last resort when all other options fail; increasing brightness spoils your color output completely, in a way similar to overexposed photos.)
Increase brightness above maximum level
You can use xrandr to increase perceived brightness above its maximum level (the same caveats mentioned above for Nvidia apply):
$ xrandr --output output_name --brightness 2
This should roughly double luma in the image. It will sacrifice color quality for brightness, nevertheless it is particularly suited for situations where the ambient light is very bright (e.g. sunlight).
External monitors
DDC/CI (Display Data Channel Command Interface) can be used to communicate with external monitors implementing MCCS (Monitor Control Command Set) over I2C. DDC can control brightness, contrast, inputs, etc on supported monitors. Settings available via the OSD (On-Screen Display) panel can usually also be managed via DDC. The kernel module i2c-dev
may need to be loaded if the /dev/i2c-*
devices do not exist.
ddcutil can be used to query and set brightness settings:
# ddcutil capabilities | grep "Feature: 10"
Feature: 10 (Brightness)
# ddcutil getvcp 10
VCP code 0x10 (Brightness ): current value = 60, max value = 100
# ddcutil setvcp 10 70
Alternatively, one may use ddcci-driver-linux-dkmsAUR to expose external monitors in sysfs. Then, after loading the ddcci
kernel module, one can use any backlight utility.
Troubleshooting
Backlight PWM modulation frequency (Intel i915 only)
Laptops with LED backlight are known to have screen flicker sometimes. This is because the most efficient way of controlling LED backlight brightness is by turning the LED's on and off very quickly varying the amount of time they are on.
However, the frequency of the switching, so-called PWM (pulse-width modulation) frequency, may not be high enough for the eye to perceive it as a single brightness and instead see flickering. This causes some people to have symptoms such as headaches and eyestrain.
If you have an Intel i915 GPU, then it may be possible to adjust PWM frequency to eliminate flicker.
Period of PWM (inverse to frequency) is stored in 2 higher bytes of 0xC8254
register (if you are using the Intel GM45 chipset use address 0x61254
instead). To manipulate registers values install intel-gpu-tools from the official repositories.
To increase the frequency, period must be reduced. For example:
# intel_reg read 0xC8254
0xC8254 : 0x12281228
Then to double PWM frequency divide 2 higher bytes (4 higher hex digits) by 2 and write back resulting value, keeping lower bytes unchanged:
# intel_reg write 0xC8254 0x09141228
You can use online calculator to calculate desired value http://devbraindom.blogspot.com/2013/03/eliminate-led-screen-flicker-with-intel.html
To set new frequency automatically, consider writing an udev rule or install intelpwm-udevAUR.
Inverted Brightness (Intel i915 only)
Symptoms:
- after installing
xf86-video-intel
systemd-backlight.service turns off the backlight during boot- possible solution: mask systemd-backlight.service
- switching from X to another VT turns the backlight off
- the brightness keys are inverted (i.e. turning up the brightness makes the screen darker)
This problem may be solved by adding i915.invert_brightness=1
to the list of kernel parameters.
Unable to control eDP Panel brightness (Intel i915 only)
Embedded Display Port (eDP) v1.2 introduced a new display panel control protocol for backlight and other controls that works through the AUX channel.[2]
By default the i915 driver tries to use PWM to control backlight brightness, which might not work.
To set the backlight through writes to DPCD registers using the AUX channel set i915.enable_dpcd_backlight
as kernel parameter or set in /etc/modprobe.d/i915.conf
:
/etc/modprobe.d/i915.conf
options i915 enable_dpcd_backlight
sysfs modified but no brightness change
On some systems, the brightness hotkeys on your keyboard correctly modify the values of the acpi interface in /sys/class/backlight/acpi_video0/actual_brightness
but the brightness of the screen is not changed. Brightness applets from desktop environments may also show changes to no effect.
If you have tested the recommended kernel parameters and only xbacklight
works, then you may be facing an incompatibility between your BIOS and kernel driver.
In this case the only solution is to wait for a fix either from the BIOS or GPU driver manufacturer.
A workaround is to use the inotify kernel api to trigger xbacklight
each time the value of /sys/class/backlight/acpi_video0/actual_brightness
changes.
First install inotify-tools. Then create a script around inotify that will be launched upon each boot or through autostart.
/usr/local/bin/xbacklightmon
#!/bin/sh path=/sys/class/backlight/acpi_video0 luminance() { read -r level < "$path"/actual_brightness factor=$((100 / max)) printf '%d\n' "$((level * factor))" } read -r max < "$path"/max_brightness xbacklight -set "$(luminance)" inotifywait -me modify --format '' "$path"/actual_brightness | while read; do xbacklight -set "$(luminance)" done