Controlling External Monitor Brightness on Linux Using Brightness Control Keys

How I built a GNOME Shell extension to control external monitor brightness using brightness controls on keyboard

Brightness OSD on Ubuntu 24.04

I recently moved from macOS to Linux. It’s been a mixed experience overall (more on that later) and every now and then you find something that just worked on Mac and doesn’t have a straightforward equivalent on Linux.

Controlling external monitor brightness was one of those things.

The Mac Days

On Mac, I used BetterDisplay. It’s a fantastic tool that lets you control a ton of settings for external displays — resolution scaling, color profiles, and more. But the killer feature for me was being able to control the brightness of my external monitor using the keyboard brightness keys. No reaching for the physical buttons on the monitor. No opening a settings panel. Just press the brightness keys and it works.

I never thought much about it. It was one of those things that felt so natural you forget it’s not a default behavior.

The Linux Situation

On Linux, I quickly realized there’s no equivalent. The brightness keys on the keyboard only control the built-in laptop display. The external monitor? You’re on your own. Open the OSD menu, navigate to brightness, nudge the value. Every. Single. Time.

What I wanted was simple — focus on the display I want to change the brightness on and use the brightness keys on my keyboard. If I’m working on my external monitor, brightness keys should change the external monitor’s brightness. If I’m on the laptop display, the default behavior kicks in. Minimal, but works.

Turns out, that’s easier said than done.

The Exploration

I started exploring this with Claude and we discovered a bunch of tools in the Linux ecosystem.

ddcutil was clearly the tool we needed. Running ddcutil setvcp 10 + 5 bumps your external monitor’s brightness up by 5 (on a 0-100 scale). The challenge was wiring this up to the keyboard brightness keys in a smart way.

Building the Extension

Here’s where things got interesting. You’d think you could just bind the brightness keys to a script and call it a day. Nope.

On GNOME (which is what Ubuntu ships with), a daemon called gsd-power grabs the brightness keys at a very low level — the Mutter accelerator level. Custom keyboard shortcuts simply never see these keys. They’re consumed before they reach your bindings.

So Claude and I went down the GNOME Shell extension route. The idea was to listen for brightness changes via D-Bus and intercept them when the focused window is on the external monitor.

The challenges were… plenty.

Each one of these took multiple iterations to get right. Claude was instrumental here — not just for writing the code but for quickly iterating through approaches when things didn’t work. The kind of stuff where you change something, log out, log back in, test, find a new issue, and repeat. Having an AI that can reason about GNOME Shell internals, D-Bus protocols, and I2C bus quirks in the same conversation is genuinely useful.

The Result

A GNOME Shell extension called Smart Brightness that does exactly what I wanted.

Install It

The extension is available on GitHub — praveenpuglia/smart-brightness-gnome.

git clone https://github.com/praveenpuglia/smart-brightness-gnome.git
cd smart-brightness-gnome
./install.sh

The install script handles everything — installing ddcutil, adding you to the i2c group, disabling the ACPI brightness switch, copying the extension files, and enabling it. You’ll need to log out and back in for it to take effect.

Check the README for requirements, configuration options, and debugging tips.

Caveats

A few things to know.

If you’re on Linux with an external monitor and you’ve been annoyed by this, give it a shot.