I am the happy owner of an Intel NUC dual booting Windows 8.1 and Ubuntu, hooked up to a great-looking Apple LED Cinema Display. The only problem is that the Apple display comes with no physical controls for brightness and Ubuntu doesn't seem to be able to adjust it either. Being a geek I was anything but content with this situation. I finally found a solution to control the brightness using keyboard shortcuts.

Step 1 - control the brightness from the command line

We need a way to control the brightness of the display. There's a handy tool called acdcontrol to do that. Unfortunately it's not been maintained for over eight years and doesn't support the 27" Apple LED Cinema Display I own. After searching high and low I found a few posts mentioning that I had to modify its code but the proposed changes didn't work. After more digging around and some creative use of lsusb, dmesg and monkeying around with the code of acdcontrol I came up with this patched version that does work.

Download it and extract it into a folder. For example, using the Terminal:

$ tar xzf acdcontrol-0.4-PATCHED.tar.gz
$ cd acdcontrol-0.4
$ rm acdcontrol # removes my pre-built binary which may not work for you
$ make

After a second or so the acdcontrol binary will have been build. Now we need to put it somewhere in our PATH and make it execute with root privileges. Yes, it really does need the root privileges :(

$ sudo cp acdcontrol /usr/local/bin
$ sudo chown root:users /usr/local/bin/acdcontrol
$ sudo chmod 0755 /usr/local/bin/acdcontrol
$ sudo chmod +s /usr/local/bin/acdcontrol

Make sure that your display's USB cord is plugged in to your computer. The brightness control, just like the iSight camera and audio input/output, is sent to your display over USB. If you have a Thunderbolt display make sure that it's plugged into a Thunderbolt port. If you have a Thunderbolt display plugged into a Mini DisplayPort port you're out of luck, sorry. Now run the following:

$ acdcontrol --detect /dev/usb/hiddev*

It should reply with something like

Apple Cinema and Studio Display Control Program. Please, use --about switch to learn more
hiddev driver version is 1.0.4
hiddev driver version is 1.0.4
/dev/usb/hiddev1: USB Monitor - SUPPORTED. Vendor= 0x5ac (Apple), Product=0x9226[Apple Cinema HD Display 27"]

See the part I put in bold type, /dev/usb/hiddev1? It may be different for you. If nothing is detected you will not be able to control the monitor brightness.

Part 2 - writing a script to step through the brightness

acdcontrol has a major shortcoming: it assumes that the brightness only takes values 0-255 when in fact it takes values 0-1000. This means that its documented method for stepping the brightness up and down simply doesn't work and results in a display too dark to read in most circumstances. For this reason - and because my knowledge of C isn't good enough to modify acdcontrol itself - we need to write our own script to work around that. Put the following code into a new file /usr/local/bin/brightness

#!/bin/bash
HIDDEV=`acdcontrol --detect /dev/usb/hiddev* | grep -Po "/dev/usb/hiddev[0-9]"`
 
BRIGHTNESS=`acdcontrol $HIDDEV | grep -E '=[[:digit:]]*' -o | grep -E '[[:digit:]]*' -o`
 
if [[ $# -lt 1 ]]
then
        $1="invalid"
    $2=0
fi
 
OPERAND=$2
 
case "$1" in
        up )
                BRIGHTNESS=$((BRIGHTNESS + OPERAND))
                ;;
 
        down )
                BRIGHTNESS=$((BRIGHTNESS - OPERAND))
                ;;
 
        set )
                BRIGHTNESS=$2
                ;;
 
        * )
                echo"Usage: $0 {up|down|set} value"
                echo""
                echo"The value is usually in per mille (one tenth of percent).
Depends on monitor type."
                echo""
                echo"Example:"
                echo"$0 up 50 Increase brightness by 5%"
                echo"$0 down 50 Decrease brightness by 5%"
                echo"$0 set 500 Set brightness to 50%"
                ;;
esac
 
if [[ $BRIGHTNESS -lt 10 ]]
then
        BRIGHTNESS=10
fi
 
if [[ $BRIGHTNESS -gt 1000 ]]
then
        BRIGHTNESS=1000
fi
 
acdcontrol $HIDDEV $BRIGHTNESS> /dev/null

Now let's make it executable:

$ sudo chmod +x /usr/local/bin/brightness

You can now step the brightness up and down using our script. Let's try it out:

$ brightness up 500 # It will make the monitor much brighter
$ brightness down 500 # It will make the monitor much darker

If the brightness doesn't change double check your HIDDEV line. The value after the equals sign must be the one you determined at the end of step 1!

Step 3 - keyboard shortcuts

Now for the final touch, adding keyboard controls. Assuming that you're using Unity, the default Ubuntu Desktop interface, you just need to open System Settings and click on the Keyboard icon. In there click on the Shortcuts tab.

At the bottom of the list there's a plus (+) button. Click on it. Set:

  • Name: Brightness up
  • Command: /usr/local/bin/brightness up 50

Click on the plus icon a second time and add another entry with:

  • Name: Brightness down
  • Command: /usr/local/bin/brightness down 50

Our custom actions appear under the "Custom..." category and have no keyboard shortcut assignments. Click on the Inactive label to the right of each shortcut and press the key combination you want to use. I use CTRL-SHIFT-ALT-plus and CTRL-SHIFT-ALT-minus for the brightness up and down command respectively. Now try using the shortcuts you specified a few times. You'll see that each time you use the shortcut there's a small brightness change in your display. That was it! Now your Ubuntu Desktop can control the brightness of your display easily through the keyboard.

What about Kubuntu?

You can set up custom shirtcuts from KDE logo, Application, Settings, System Settings, Shortcuts, Custom Shortcuts. You can create a new Command/URL global shortcut and assign the scripts mentioned above. As for the shortcuts, I found that META-F1 and META-F2 work best without causing conflicts. Why F1/F2? This is where brightness down/up can be found on a Mac keyboard :)

Pitfalls

The acdcontrol utility has the supported USB vendor and device ID list hard-coded into it. I only have one Apple display to test with. It is possible that different generations of Apple displays may use a different USB device ID. In this case you'll need to modify the source code of the utility yourself.

Brightness control requires a USB connection between your computer and display, obviously. With older Apple displays this is as simple as connecting the USB cord of your display to your computer. With the Thunderbolt display you only have one Thurderbolt cord which transfers both the video signal and the USB data. If your computer has a Thunderbolt port and you connect it there it will work. If your computer has a Mini DisplayPort you will get video output normally but all USB-related features, including brightness control, iSight camera and audio, will not work. There's no workaround for that.

Ubuntu Desktop has brightness controls and options under the Displays section of the system configuration. These will still not work. Ubuntu is not aware of the need to use acdcontrol for Apple displays. That's why we had to go through these steps to get brightness controls working in the first place.