4.3 KiB
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.
Architecture
The real brightness change is intentionally immediate:
brightness-up/down-all
-> brightnessctl immediately changes the internal display
-> brightness-osd only displays or updates the visual feedback
-> external-brightness-sync.service mirrors the internal percentage later
The actual brightnessctl call must not be debounced. Only the OSD may be smoothed by reusing the running OSD process and extending its hide timer.
The external monitor is not changed in the key-binding scripts. ddcutil is slower than an internal backlight write, so it runs separately in the sync service.
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_OSD_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.