I got the early 2015 Macbook Air (13") and put Fedora 21 Xfce on it, and everything works great except the webcam (Facetime HD camera uses PCIe instead of USB and no driver exists), and the brightness keys.

In Xfce the brightness keys on the keyboard will pop up a progress bar showing the brightness setting, and it will go up and down, but the brightness doesn't actually change. I was Googling around for a solution to this and couldn't find one, but I found that the root user can manually set the brightness by writing a number into /sys/class/backlight/intel_backlight/brightness (with the maximum value being readable from the max_brightness file in the same folder; on my system the maximum is 2777.

I found some hacky shell scripts on here for this. I wrote my own script in Python, and thought I'd share it with y'all in case it helps someone else. Hopefully the brightness keys will work out-of-box on a future Fedora release, but in the mean time, here's this.

Set the sudoers file to allow running the script without a password, and add keyboard shortcuts to run the script. I used Command+< and Command+> to adjust the brightness.

This is only tested on the Macbook Air which has an Intel graphics card (no Nvidia dual graphics like the Macbook Pro; the script might work on that setup, but the file paths in /sys/class may need tweaking).


#!/usr/bin/env python
from __future__ import print_function

"""mb-brightness: Adjust brightness on a Macbook Air 2015.

On a Macbook Air 2015 the keyboard brightness controls don't work automatically (as far as Fedora 21 Xfce,
anyway). A pop-up appears with a brightness bar indicator but the actual brightness doesn't change.

This model uses an Intel graphics card and you can manually adjust the brightness on the CLI, as root,
by echoing the number into /sys/class/backlight/intel_backlight/brightness. This script is a helper that
does exactly that.

To set up, you'll need to edit your sudoers file to allow executing this script as root without a password:
%wheel  ALL=(ALL)  NOPASSWD: /home/noah/bin/mb-brightness

Usage: mb-brightness [--up --down --set %]
See mb-brightness --help

You can set the brightness to a specific setting (percentage) by doing e.g. `mb-brightness --set 100`

Set this up in your desktop's key bindings. For example I chose Command+< and Command+> to decrease and increase
brightness, respectively:

* Command+< : sudo /home/noah/bin/mb-brightness --down
* Command+> : sudo /home/noah/bin/mb-brightness --up

This script has a minimum brightness coded into it so that the brightness won't drop below 5%. If the brightness
gets set to 0% the backlight gets completely turned off, which isn't fun for anybody.


# Device file paths. Edit this script if these differ on your system.
BRIGHTNESS     = "/sys/class/backlight/intel_backlight/brightness"
MAX_BRIGHTNESS = "/sys/class/backlight/intel_backlight/max_brightness"

# Set a minimum brightness level, because at 0% brightness the backlight turns completely off.

import os
import sys
import argparse
import logging

logger = logging.getLogger("mb-brightness")

def main(args):
    """Main function."""
    if args.debug:

    # Input validation.
    if args.up and args.down:
        die("--up and --down are mutually exclusive; use only one!")
    if args.interval < 0 or args.interval > 100:
        die("Interval must be a valid percentage between 0 and 100.")
    if args.set is not None and args.set < 0 or args.set > 100:
        die("Percentage for --set must be between 0 and 100.")

    # Got root?
    if os.geteuid() != 0:
        die("Got root?")

    # Get the max brightness.
    maximum = cat(MAX_BRIGHTNESS)
    logger.debug("Maximum brightness: {}".format(maximum))

    # The value we're setting it to.
    percent = 50

    # Have a hard value to set to?
    if args.set:
        percent = args.set
        # Moving it by an interval. First calculate the current brightness percentage.
        brightness = cat(BRIGHTNESS)
        percent = int((float(brightness) / float(maximum)) * 100)
        logger.debug("Current brightness percent: {}%".format(percent))

        # Bump the percentage and cap the result.
        if args.up:
            percent += args.interval
        elif args.down:
            percent -= args.interval
        if percent < 0: percent = 0
        if percent > 100: percent = 100

    # Set the brightness.
    set_brightness(percent, maximum)

def set_brightness(percent, maximum):
    """Write the brightness as a percentage (0-100)."""
    if percent < MIN_BRIGHTNESS:
        percent = MIN_BRIGHTNESS

    brightness = int(float(maximum) * (float(percent) / 100))
    logger.debug("Setting brightness to {} ({}%)".format(brightness, percent))
    logger.debug("Write {} > {}".format(brightness, BRIGHTNESS))
    fh = open(BRIGHTNESS, "w")

def cat(file):
    """Read an integer value from a file."""
    logger.debug("Read value from: {}".format(file))
    fh = open(file, "r")
    value = fh.read().strip()
    return int(value)

def die(message):
    """Print a message and exit with a non-zero code."""

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Macbook Brightness Helper")
        help="Turn on verbose logging, for debugging.",
    parser.add_argument("--interval", "-i",
        help="The brightness percentage interval, default 5.",
    parser.add_argument("--up", "-u",
        help="Increase the brightness by the set interval.",
    parser.add_argument("--down", "-d",
        help="Decrease the brightness by the set interval.",
    parser.add_argument("--set", "-s",
        help="Set the brightness to a specific percentage level (0-100).",
    args = parser.parse_args()