Fix external monitor brightness OSD
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
set -u
|
||||
|
||||
readonly PANAMA_OSD_SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
strict_delivery() {
|
||||
[[ ${PANAMA_OSD_STRICT:-false} == true || ${PANAMA_OSD_STRICT:-false} == 1 ]]
|
||||
}
|
||||
@@ -67,18 +69,151 @@ adjust_microphone() {
|
||||
show_volume "$target" microphone
|
||||
}
|
||||
|
||||
brightness_percent() {
|
||||
local output="$1" percent
|
||||
percent="$(awk -F, 'NR == 1 { value=$5; gsub(/%/, "", value); print value }' <<<"$output")"
|
||||
[[ $percent =~ ^[0-9]+$ ]] || return 1
|
||||
printf '%s\n' "$percent"
|
||||
}
|
||||
|
||||
brightness_error() {
|
||||
local detail="$1" label="External brightness unavailable"
|
||||
if [[ $detail == *udev* || $detail == *accessible* || $detail == *permission* ]]; then
|
||||
label="Brightness needs permission"
|
||||
fi
|
||||
|
||||
show_message dialog-warning-symbolic "$label" || true
|
||||
if command -v notify-send >/dev/null 2>&1; then
|
||||
notify-send --app-name=Panama --icon=display-brightness-symbolic \
|
||||
"Brightness unavailable" "$detail" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
discover_ddc_bus() {
|
||||
local helper="$1" cache_file="$2" list_json focused selected error bus connector
|
||||
|
||||
command -v jq >/dev/null 2>&1 || {
|
||||
brightness_error "jq is required to discover DDC/CI displays."
|
||||
return 1
|
||||
}
|
||||
|
||||
list_json="$("$helper" list 2>/dev/null)" || {
|
||||
brightness_error "The external brightness helper could not inspect connected displays."
|
||||
return 1
|
||||
}
|
||||
if ! jq -e 'type == "object" and (.displays | type == "array")' >/dev/null 2>&1 <<<"$list_json"; then
|
||||
brightness_error "The external brightness helper returned invalid display information."
|
||||
return 1
|
||||
fi
|
||||
|
||||
error="$(jq -r '.error // empty' <<<"$list_json")"
|
||||
if [[ -n $error ]]; then
|
||||
brightness_error "$error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
focused="$(hyprctl -j monitors 2>/dev/null \
|
||||
| jq -r '.[] | select(.focused == true) | .name' 2>/dev/null \
|
||||
| head -n1)"
|
||||
selected="$(jq -r --arg connector "$focused" '
|
||||
([.displays[] | select(.connector == $connector)][0] // .displays[0] // empty)
|
||||
| [.bus, .connector]
|
||||
| @tsv
|
||||
' <<<"$list_json")"
|
||||
IFS=$'\t' read -r bus connector <<<"$selected"
|
||||
if [[ ! $bus =~ ^[0-9]+$ ]]; then
|
||||
brightness_error "No connected monitor exposes DDC/CI brightness control."
|
||||
return 1
|
||||
fi
|
||||
|
||||
umask 077
|
||||
printf '%s\t%s\n' "$bus" "$connector" >"$cache_file"
|
||||
printf '%s\n' "$bus"
|
||||
}
|
||||
|
||||
adjust_ddc_brightness() {
|
||||
local action="$1" step="$2"
|
||||
local helper="${PANAMA_OSD_BRIGHTNESS_HELPER:-$PANAMA_OSD_SCRIPT_DIR/panama-brightness}"
|
||||
local runtime_dir="${PANAMA_OSD_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/panama-osd-${UID}}"
|
||||
local cache_file="$runtime_dir/brightness-bus" lock_file="$runtime_dir/brightness.lock"
|
||||
local bus="" connector="" current target lock_fd
|
||||
|
||||
[[ -x $helper ]] || {
|
||||
brightness_error "The external brightness helper is not installed."
|
||||
return 0
|
||||
}
|
||||
mkdir -p "$runtime_dir" || return 0
|
||||
chmod 700 "$runtime_dir" 2>/dev/null || true
|
||||
|
||||
exec {lock_fd}>"$lock_file" || return 0
|
||||
# DDC transactions on one I2C bus cannot safely overlap. A short wait also
|
||||
# sheds an excessive key-repeat backlog instead of replaying it seconds later.
|
||||
flock -w 2 "$lock_fd" || return 0
|
||||
|
||||
if [[ -r $cache_file ]]; then
|
||||
IFS=$'\t' read -r bus connector <"$cache_file" || true
|
||||
[[ $bus =~ ^[0-9]+$ ]] || bus=""
|
||||
fi
|
||||
|
||||
if [[ -n $bus ]]; then
|
||||
current="$("$helper" get "$bus" 2>/dev/null)" || current=""
|
||||
if [[ ! $current =~ ^[0-9]+$ ]]; then
|
||||
: >"$cache_file"
|
||||
bus=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $bus ]]; then
|
||||
bus="$(discover_ddc_bus "$helper" "$cache_file")" || return 0
|
||||
current="$("$helper" get "$bus" 2>/dev/null)" || current=""
|
||||
fi
|
||||
if [[ ! $current =~ ^[0-9]+$ ]]; then
|
||||
brightness_error "The selected monitor stopped responding over DDC/CI."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ $action == up ]]; then
|
||||
target=$(( current + step ))
|
||||
else
|
||||
target=$(( current - step ))
|
||||
fi
|
||||
(( target > 100 )) && target=100
|
||||
(( target < 0 )) && target=0
|
||||
|
||||
if ! "$helper" set "$bus" "$target" >/dev/null 2>&1; then
|
||||
brightness_error "The selected monitor did not accept the brightness change."
|
||||
return 0
|
||||
fi
|
||||
show_progress brightness "$target" "${target}%"
|
||||
}
|
||||
|
||||
adjust_brightness() {
|
||||
local action="${1:-}" step="${2:-5}" output percent
|
||||
[[ $step =~ ^[0-9]+$ ]] || {
|
||||
printf 'Usage: panama-osd brightness up|down [step]\n' >&2
|
||||
return 2
|
||||
}
|
||||
case "$action" in
|
||||
up) brightnessctl -e4 -n2 set "${step}%+" >/dev/null || return ;;
|
||||
down) brightnessctl -e4 -n2 set "${step}%-" >/dev/null || return ;;
|
||||
up|down) ;;
|
||||
*) printf 'Usage: panama-osd brightness up|down [step]\n' >&2; return 2 ;;
|
||||
esac
|
||||
|
||||
output="$(brightnessctl -m -c backlight 2>/dev/null)" || return 0
|
||||
percent="$(awk -F, 'NR == 1 { value=$5; gsub(/%/, "", value); print value }' <<<"$output")"
|
||||
[[ $percent =~ ^[0-9]+$ ]] || return 0
|
||||
show_progress brightness "$percent" "${percent}%"
|
||||
# Laptop panels expose a kernel backlight class and remain the fastest,
|
||||
# most reliable path. Desktops fall through to DDC/CI monitor control.
|
||||
output="$(brightnessctl -m -c backlight 2>/dev/null)" || output=""
|
||||
if percent="$(brightness_percent "$output")"; then
|
||||
if [[ $action == up ]]; then
|
||||
brightnessctl -e4 -n2 -c backlight set "${step}%+" >/dev/null || return 0
|
||||
else
|
||||
brightnessctl -e4 -n2 -c backlight set "${step}%-" >/dev/null || return 0
|
||||
fi
|
||||
output="$(brightnessctl -m -c backlight 2>/dev/null)" || return 0
|
||||
percent="$(brightness_percent "$output")" || return 0
|
||||
show_progress brightness "$percent" "${percent}%"
|
||||
return
|
||||
fi
|
||||
|
||||
adjust_ddc_brightness "$action" "$step"
|
||||
}
|
||||
|
||||
media_action() {
|
||||
|
||||
Reference in New Issue
Block a user