Skip to content

Make brightness keys work on external displays with a kernel backlight - #14323

Open
wesleygrimes wants to merge 5 commits into
omacom:quattrofrom
wesleygrimes:brightness-external-backlight
Open

wesleygrimes wants to merge 5 commits into
omacom:quattrofrom
wesleygrimes:brightness-external-backlight

Conversation

@wesleygrimes

@wesleygrimes wesleygrimes commented Oct 5, 2026 •

Copy link
Copy Markdown

With an Apple Studio Display focused, the brightness keys show the OSD but the screen doesn't change. Today they go through sudo asdcontrol, and Studio Display firmware 17.0 ignores that command (macOS behaves the same).

What this changes

Some kernels expose an external display's brightness as a regular backlight device on its connector, for example apple-DP-3-bl for the Studio Display. When the focused external display has one, the brightness keys now use that kernel backlight instead of asdcontrol: brightnessctl, the usual step sizes, the OSD, and no sudo.

Kernel PR: iconidentify/aurora-linux#15 adds the Studio Display backlight. It's merged into the aurora-linux fork and reaches Omarchy once that fork is merged into omacom/linux and the kernel is built.

This PR is backwards compatible: on a kernel without a connector backlight every display takes the path it does today, so it can merge before the kernel work lands.

Everything else works as it does today:

  • Displays without a connector backlight (every display on a stock kernel, DDC monitors, Studio Displays on older kernels) take the existing path.
  • Laptop screens keep omarchy-hw-display's choice. Some GPU drivers attach a backlight to the internal connector that isn't the one driving the panel (gmux on dual-GPU Macs), so internal connectors aren't checked.
  • Only a connected connector's backlight is used, so a disconnected connector with the same name on another card can't be picked by mistake.
  • If more than one connected connector has the monitor's name (for example DP-1 on both GPUs of a hybrid laptop), neither backlight is used. Hyprland only gives us the name, so the keys can't tell the two displays apart, and they take the existing path instead of possibly changing the wrong display.
  • If the connector backlight can't be read or written, the keys fall back to asdcontrol or DDC with the original step instead of silently doing nothing.

This isn't Apple-specific: any external display whose kernel driver provides a backlight gets the same treatment.

The manual's monitor page and the BrightnessKeys.qml header now describe the connector backlight as the first backend for external displays.

Testing

  • New cases in test/shell.d/brightness-display-test.sh use a fake sysfs tree. They cover:
    • the external backlight winning over the Apple and DDC paths, the OSD, and 1% steps
    • laptop screens staying on omarchy-hw-display
    • Studio Displays without a kernel backlight still using asdcontrol
    • a disconnected same-name connector being skipped
    • a connector name shared by two connected cards using neither backlight
    • a backlight that can't be written falling back to asdcontrol and to DDC with the requested step, and one that can't be read falling back for the brightness query
    • a monitor with no DRM connector (e.g. HEADLESS-1) looking up quietly, without a sysfs error on stderr
  • On an Apple Silicon laptop with a Studio Display: with the Studio Display focused, the keys step it with the OSD and no sudo prompt, and ALT gives 1% steps. With the laptop screen focused, the keys change the panel. SHIFT still controls the keyboard backlight. The follow-up commits only change the fallback and duplicate-name paths, which the fake-sysfs cases cover.
  • ./test/all in a clean checkout passes apart from five shell tests (config, elsewhen-migration, passwordless-grant-lifecycle, snapper, unowned-system-paths) that fail the same way on quattro without this change.

This touches the same file as #13362, so whichever lands second will need a small rebase.

Hyprland monitor names are DRM connector names, so a backlight the kernel
registers on the focused external monitor's connected connector is used
through the existing brightnessctl path before the Apple asdcontrol and DDC
fallbacks. This lets the Studio Display use the plain brightness keys and
OSD on kernels that expose its DCP backlight, without sudo.

Internal panels keep omarchy-hw-display's pick: GPU drivers such as i915
register a backlight on the eDP connector that may not be the one driving
the panel (gmux on dual-GPU Macs).

Signed-off-by: Wes Grimes <wesgrimes@hey.com>
@wesleygrimes
wesleygrimes force-pushed the brightness-external-backlight branch from ae625d4 to 293a2c0 Compare October 5, 2026 15:26
@greptile-apps

greptile-apps Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds kernel backlight support to brightness key handling.

The PR appears safe to merge based on the reviewed changes.

Summary

The PR uses a connected external monitor’s kernel backlight for brightness control, retaining the Apple and DDC paths as fallbacks.

  • The latest changes avoid choosing a backlight when two connected cards share a connector name.
  • They also fall back when the selected backlight cannot be read or written, with tests for those paths.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Brightness request] --> B{Unique connected external connector backlight?}
  B -- Yes --> C{Backlight read and write succeed?}
  C -- Yes --> D[Use kernel backlight and show OSD]
  C -- No --> E[Try Apple, then DDC backend]
  B -- No --> E
  E --> F{Internal display?}
  F -- Yes --> G[Use omarchy-hw-display]
  F -- No --> H[Use available external backend]
Loading

Reviews (2) · Last reviewed commit: "Skip connector backlights when the conne..."

Comment thread bin/omarchy-brightness-display Outdated
Comment thread bin/omarchy-brightness-display
Signed-off-by: Wes Grimes <wesgrimes@hey.com>
Signed-off-by: Wes Grimes <wesgrimes@hey.com>
Signed-off-by: Wes Grimes <wesgrimes@hey.com>
Signed-off-by: Wes Grimes <wesgrimes@hey.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant