116 lines
2.7 KiB
Bash
Executable File
116 lines
2.7 KiB
Bash
Executable File
#!/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
|