Fedora Brightness Automation Buttons OSD
Small Fedora/GNOME brightness setup for laptops with an internal Linux backlight and an external DDC/CI monitor.
The internal display is the master. Brightness keys change the internal panel, show a compact OSD, and a user service mirrors the same percentage to the external monitor with ddcutil.
This avoids drift from letting two outputs auto-adjust independently.
Features
- Internal display controlled with
brightnessctl - External monitor mirrored with
ddcutilVCP code10 - Compact GTK4/libadwaita OSD for custom brightness shortcuts
- Optional Wayland top-edge positioning with
gtk4-layer-shell - systemd user service for continuous external sync
- Configurable backlight device, DDC bus, monitor model, step size, and sync interval
- Optional wluma config where only the internal display is managed
Tested Setup
- Fedora 43
- GNOME Shell 49
- Internal panel:
intel_backlight - External monitor: DDC/CI via
ddcutil
Other Fedora/GNOME setups should work if brightnessctl and ddcutil can control the displays.
Dependencies
sudo dnf install -y brightnessctl ddcutil python3-gobject gtk4 libadwaita gtk4-layer-shell
gtk4-layer-shell is recommended on GNOME Wayland. Without it, GNOME may place the OSD like a normal GTK window instead of pinning it at the top edge.
If your ddcutil command needs sudo, configure passwordless sudo for the specific command you use. Example:
jan ALL=(root) NOPASSWD: /usr/bin/ddcutil
Use a stricter sudoers rule if you prefer limiting arguments.
Quick Install
git clone https://gitea.diehanis.de/Jan/Fedora_Brightness_Automation_Buttons_OSD.git
cd Fedora_Brightness_Automation_Buttons_OSD
./install.sh
The installer writes:
~/.local/bin/brightness-osd
~/.local/bin/brightness-up-all
~/.local/bin/brightness-down-all
~/.local/bin/brightness-sync-hg342pcb
~/.config/systemd/user/external-brightness-sync.service
~/.config/brightness-automation/env
Then set your GNOME custom keyboard shortcuts to:
/home/YOUR_USER/.local/bin/brightness-down-all
/home/YOUR_USER/.local/bin/brightness-up-all
Use the full path in GNOME Settings.
Configuration
Edit:
~/.config/brightness-automation/env
Default config:
BRIGHTNESS_BACKLIGHT_DEVICE="intel_backlight"
BRIGHTNESS_SYNC_BACKLIGHT="/sys/class/backlight/intel_backlight"
BRIGHTNESS_STEP="10"
BRIGHTNESS_DDCUTIL_MODEL="HG342PCB"
BRIGHTNESS_DDCUTIL_DISPLAY="1"
BRIGHTNESS_DDCUTIL_BUS="16"
BRIGHTNESS_SYNC_INTERVAL="1"
BRIGHTNESS_SYNC_MIN_PERCENT="1"
BRIGHTNESS_OSD_VISIBLE_MS="1400"
After changing DDC or sync values:
systemctl --user restart external-brightness-sync.service
Finding Your Values
Backlight device:
brightnessctl -l
ls /sys/class/backlight
External monitor:
sudo ddcutil detect
sudo ddcutil getvcp 10
If ddcutil detect reports a bus like /dev/i2c-16, set:
BRIGHTNESS_DDCUTIL_BUS="16"
wluma
If you use wluma, let it manage only the internal display. The external monitor should follow through the sync service.
Optional install of the example wluma config:
INSTALL_WLUMA_CONFIG=1 ./install.sh
systemctl --user restart wluma.service
Example config is in:
wluma/config.toml
Status
systemctl --user status external-brightness-sync.service
journalctl --user -u external-brightness-sync.service -n 50 --no-pager
Design Notes
Implementation decisions and failed attempts are documented in:
docs/implementation-log.md
Uninstall
./uninstall.sh
The uninstall script keeps ~/.config/brightness-automation/env so local settings are not destroyed.