#!/bin/bash
# Release display pipes the kernel left enabled on unplugged connectors.
#
# After suspend/resume (or unplugging a USB-C display) i915 can leave a
# connector "disconnected" but still "enabled" on a pipe that Hyprland has
# forgotten. That pipe then blocks every other external output from
# modesetting (black screens, or a ~5 s re-modeset loop).
#
# Fix: force the connector on so Hyprland sees it, disable it from Hyprland
# (which releases the pipe), force it off, then return it to auto-detect.
# Never `hyprctl reload` here: a reload re-enables the connector while it is
# forced on and re-sticks the pipe.

log() { echo "fix-stuck-displays: $*"; logger -t fix-stuck-displays -- "$*"; }

wait_for() { # wait_for <seconds> <command...>
  local n=$(( $1 * 4 )); shift
  for _ in $(seq "$n"); do "$@" && return 0; sleep 0.25; done
  return 1
}

stuck=()
for d in /sys/class/drm/card*-*; do
  [[ -f $d/status && -f $d/enabled ]] || continue
  [[ $d == *eDP* ]] && continue
  [[ $(<"$d/status") == disconnected && $(<"$d/enabled") == enabled ]] && stuck+=("$d")
done

if (( ${#stuck[@]} == 0 )); then
  log "no stuck connectors"
  exit 0
fi

systemctl --user stop hyprmoncfgd

for d in "${stuck[@]}"; do
  out=${d##*/}; out=${out#card*-}
  log "releasing $out"
  echo on | sudo -n tee "$d/status" >/dev/null
  wait_for 5 sh -c "hyprctl monitors all | grep -q '^Monitor $out '" || log "$out never appeared in Hyprland"
  hyprctl eval "hl.monitor({ output = \"$out\", disabled = true })" >/dev/null
  wait_for 5 grep -qx disabled "$d/enabled" || log "$out still enabled after disable"
  echo off | sudo -n tee "$d/status" >/dev/null
  sleep 1
  echo detect | sudo -n tee "$d/status" >/dev/null
  log "$out now $(<"$d/status") $(<"$d/enabled")"
done

# Drop any low-refresh fallback hyprmoncfgd wrote while outputs were failing.
rm -f ~/.config/hyprmoncfg/display-fallbacks.json

# hyprmoncfgd re-applies the matching profile (modes, positions) on startup.
systemctl --user start hyprmoncfgd
