Files
hyprland-hdmi-revive/scripts/revive-monitor-drm-watch.sh
T

65 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -uo pipefail
LOGTAG=revive-monitor-drm-watch
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
COMMON="$SCRIPT_DIR/../lib/hyprland-hdmi-revive/common.sh"
[[ -f "$COMMON" ]] || COMMON="$SCRIPT_DIR/../lib/common.sh"
# shellcheck source=lib/common.sh
source "$COMMON" || exit 1
load_config || exit 1
require_commands udevadm stdbuf timeout loginctl flock stat || exit 1
prepare_runtime || exit 1
if [[ -n "${REVIVE_MONITOR_FIX_SCRIPT:-}" ]]; then
FIX_SCRIPT="$REVIVE_MONITOR_FIX_SCRIPT"
else
FIX_SCRIPT="$SCRIPT_DIR/revive-monitor-fix"
[[ -e "$FIX_SCRIPT" ]] || FIX_SCRIPT="$SCRIPT_DIR/revive-monitor-fix.sh"
fi
if [[ ! -x "$FIX_SCRIPT" ]]; then
log "Recovery script is not executable: $FIX_SCRIPT"
exit 1
fi
exec 8>"$STATE_DIR/watcher.lock" || exit 1
if ! flock -n 8; then
log 'Another watcher is running or the watcher lock is unavailable'
exit 1
fi
run_recovery() {
local session_info now status
session_info="$(get_active_wayland_session)" || {
log 'No active Wayland session - DRM hotplug ignored'
return 0
}
now=$SECONDS
if (( last_run >= 0 && now - last_run < DEBOUNCE_SECONDS )); then
log 'DRM hotplug ignored because of debounce'
return 0
fi
log "DRM hotplug detected - Wayland session ${session_info%%:*} on VT ${session_info##*:}"
"$FIX_SCRIPT" "${session_info##*:}"
status=$?
# Measure from completion, so events queued during our own VT refresh are suppressed.
last_run=$SECONDS
if (( status != 0 )); then
log "Recovery after DRM hotplug failed (exit $status)"
else
log 'Recovery helper finished; see its log for completion or skip reason'
fi
}
log 'Listening for DRM hotplug events'
# pipefail propagates a failed producer. EOF (even exit 0) is unexpected for
# this long-running service and must also trigger Restart=on-failure.
stdbuf -oL udevadm monitor --kernel --property --subsystem-match=drm |
while IFS= read -r line; do
last_run=${last_run:--1}
case "$line" in
HOTPLUG=1) run_recovery ;;
esac
done
status=$?
log "DRM event stream ended (exit $status) - requesting service restart"
exit 1