* Support external monitor brightness Route brightness through the focused Hyprland monitor so internal panels keep using the kernel backlight while compatible external displays use DDC/CI. Preserve the Apple Display backend and leave brightness unavailable when the focused display cannot be controlled. Add cached DDC bus and VCP range handling, install ddcutil for new and existing systems, and cover backend selection and brightness conversion with shell tests. * Harden external brightness caching --------- Co-authored-by: David Heinemeier Hansson <david@hey.com>
123 lines
3.4 KiB
Bash
Executable File
123 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Show or adjust brightness on the focused display.
|
|
# omarchy:args=[--no-osd] [--monitor name] [+N%|N%-|N%|off|on]
|
|
# omarchy:examples=omarchy brightness display | omarchy brightness display +5% | omarchy brightness display --monitor DP-1 50% | omarchy brightness display off | omarchy brightness display on
|
|
|
|
no_osd=0
|
|
monitor=""
|
|
|
|
while (( $# > 0 )); do
|
|
case "$1" in
|
|
--no-osd)
|
|
no_osd=1
|
|
shift
|
|
;;
|
|
--monitor)
|
|
(( $# >= 2 )) || exit 1
|
|
monitor="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Get the brightness of the passed display
|
|
backlight_brightness() {
|
|
brightnessctl -d "$1" -m 2>/dev/null | awk -F, '{ gsub("%", "", $4); print $4; found=1 } END{ exit !found }'
|
|
}
|
|
|
|
[[ -n $monitor ]] || monitor="$(omarchy-hyprland-monitor-focused 2>/dev/null || true)"
|
|
|
|
monitor_is_internal() {
|
|
[[ $monitor =~ ^(eDP|LVDS|DSI)- ]]
|
|
}
|
|
|
|
use_apple_display() {
|
|
omarchy-hyprland-monitor-focused-apple "$monitor"
|
|
}
|
|
|
|
use_ddc_display() {
|
|
[[ -n $monitor ]] && ! monitor_is_internal
|
|
}
|
|
|
|
if (( $# == 0 )); then
|
|
if use_apple_display; then
|
|
omarchy-brightness-display-apple
|
|
exit
|
|
elif use_ddc_display; then
|
|
omarchy-brightness-display-ddc "$monitor"
|
|
exit
|
|
fi
|
|
|
|
device="$(omarchy-hw-display)" || exit 1
|
|
backlight_brightness "$device"
|
|
exit
|
|
fi
|
|
|
|
step="$1"
|
|
|
|
if [[ $step == "off" ]]; then
|
|
hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })' >/dev/null 2>&1
|
|
exit 0
|
|
elif [[ $step == "on" ]]; then
|
|
# Skip the dispatch when every active display is already lit: a redundant
|
|
# DPMS enable right after system resume forces another modeset, which blanks
|
|
# the panel for a beat (visible flash at the unlock screen).
|
|
hyprctl monitors -j 2>/dev/null | jq -e '[.[] | select(.disabled == false)] | length > 0 and all(.dpmsStatus)' >/dev/null 2>&1 && exit 0
|
|
hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' >/dev/null 2>&1
|
|
exit 0
|
|
fi
|
|
|
|
# Drop overlapping brightness key events so concurrent invocations do not race.
|
|
# Hardware key repeat present on some devices can otherwise glitch OSD rendering.
|
|
exec {lock_fd}>"${XDG_RUNTIME_DIR:-/tmp}/omarchy-brightness-display.lock"
|
|
flock -n "$lock_fd" || exit 0
|
|
|
|
if use_apple_display; then
|
|
if (( no_osd )); then
|
|
omarchy-brightness-display-apple --no-osd "$step"
|
|
else
|
|
omarchy-brightness-display-apple "$step"
|
|
fi
|
|
elif use_ddc_display; then
|
|
brightness="$(omarchy-brightness-display-ddc "$monitor" "$step")" || exit 1
|
|
(( no_osd )) || omarchy-osd -i brightness -p "$brightness"
|
|
else
|
|
# Current device highlighted
|
|
device="$(omarchy-hw-display)" || exit 1
|
|
|
|
# Current brightness percentage
|
|
current=$(backlight_brightness "$device") || exit 1
|
|
|
|
# Apply non-uniform step size: 1% steps if at or below 5%, otherwise set an
|
|
# absolute target percentage to avoid raw backlight rounding causing uneven OSD steps.
|
|
if [[ $step == "+5%" ]]; then
|
|
if (( current < 5 )); then
|
|
(( target = current + 1 ))
|
|
else
|
|
(( target = current + 5 ))
|
|
fi
|
|
|
|
(( target > 100 )) && target=100
|
|
step="$target%"
|
|
elif [[ $step == "5%-" ]]; then
|
|
if (( current <= 5 )); then
|
|
(( target = current - 1 ))
|
|
else
|
|
(( target = current - 5 ))
|
|
fi
|
|
|
|
(( target < 1 )) && target=1
|
|
step="$target%"
|
|
fi
|
|
|
|
# Set brightness of the display device.
|
|
brightnessctl -d "$device" set "$step" >/dev/null
|
|
|
|
# Show the new brightness in OSD
|
|
(( no_osd )) || omarchy-osd -i brightness -p "$(backlight_brightness "$device")"
|
|
fi
|