65 lines
2.2 KiB
Bash
Executable File
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
|