#!/usr/bin/env bash set -u LOGTAG="revive-monitor-drm-watch" CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/revive-monitor/config.env" FIX_SCRIPT="${REVIVE_MONITOR_FIX_SCRIPT:-$HOME/.local/bin/revive-monitor-fix}" # Defaults. Override in ~/.config/revive-monitor/config.env DEBOUNCE_SECONDS="30" if [[ -r "$CONFIG_FILE" ]]; then # shellcheck disable=SC1090 source "$CONFIG_FILE" fi STATE_DIR="${XDG_RUNTIME_DIR:-/tmp}/revive-monitor" LAST_RUN_FILE="$STATE_DIR/last-drm-hotplug-run" mkdir -p "$STATE_DIR" log() { logger -t "$LOGTAG" -- "$*" } get_active_wayland_session() { local sid local name local type local active local vt while read -r sid; do [[ -n "$sid" ]] || continue name="$(loginctl show-session "$sid" -p Name --value 2>/dev/null)" [[ "$name" == "$USER" ]] || continue type="$(loginctl show-session "$sid" -p Type --value 2>/dev/null)" [[ "$type" == "wayland" ]] || continue active="$(loginctl show-session "$sid" -p Active --value 2>/dev/null)" [[ "$active" == "yes" ]] || continue vt="$(loginctl show-session "$sid" -p VTNr --value 2>/dev/null)" if [[ "$vt" =~ ^[1-9][0-9]*$ ]]; then printf '%s:%s\n' "$sid" "$vt" return 0 fi done < <( loginctl list-sessions --no-legend --no-pager 2>/dev/null | awk '{print $1}' ) return 1 } run_recovery() { local session_info local session_id local graphical_vt local now local last="0" local diff if ! session_info="$(get_active_wayland_session)"; then log "No active Wayland session - DRM hotplug ignored" return 0 fi session_id="${session_info%%:*}" graphical_vt="${session_info##*:}" now="$(date +%s)" if [[ -r "$LAST_RUN_FILE" ]]; then last="$(cat "$LAST_RUN_FILE" 2>/dev/null || printf '0')" fi [[ "$last" =~ ^[0-9]+$ ]] || last="0" diff=$((now - last)) if (( diff < DEBOUNCE_SECONDS )); then log "DRM hotplug ignored because of debounce (${diff}s)" return 0 fi printf '%s\n' "$now" > "$LAST_RUN_FILE" log "DRM hotplug detected - Wayland session $session_id on VT $graphical_vt" "$FIX_SCRIPT" "$graphical_vt" log "Recovery after DRM hotplug finished" } if ! command -v udevadm >/dev/null 2>&1; then log "udevadm not found" exit 1 fi if [[ ! -x "$FIX_SCRIPT" ]]; then log "Recovery script is not executable: $FIX_SCRIPT" exit 1 fi log "Listening for DRM hotplug events" stdbuf -oL udevadm monitor --kernel --property --subsystem-match=drm | while IFS= read -r line; do case "$line" in HOTPLUG=1) run_recovery ;; esac done