#!/usr/bin/env bash
# Safety net: never let an orphaned eww backdrop block all input.
#
# The lockout failure mode: a full-screen click-catcher (panel-backdrop /
# spot-backdrop / dock-menu-backdrop) stays mapped after its owner window is gone
# (a race, a crash, an interrupted close) — niri keeps the layer surface up and
# it swallows every click. (The dock is catcher-free, so it can't cause this.)
#
# Detection is DETERMINISTIC and niri-geometry-free: a backdrop is an orphan iff
# it is open while NONE of its owner windows are. We only ever close eww windows
# (never kill the daemon), and we require the orphan to persist across two polls
# (~1.4 s) so a normal open/close animation never trips it.
set -u

EWW=eww
INTERVAL=0.7      # poll period
STRIKES_NEEDED=2  # consecutive orphan readings before acting

# backdrop  ->  regex of windows that legitimise it being open
declare -A OWNER=(
  [panel-backdrop]='^(control-center|calendar|music|sysmon|updates):'
  [spot-backdrop]='^spotlight:'
  [dock-menu-backdrop]='^(dock-menu|dock-bg-menu):'
  [dock-catcher]='^dock:'
)
# var to reset when we force-close each backdrop (so the next open is clean)
declare -A RESET=(
  [panel-backdrop]=panel-open
  [spot-backdrop]=spot-open
)

declare -A strike
for b in "${!OWNER[@]}"; do strike[$b]=0; done

while :; do
  sleep "$INTERVAL"
  wins=$("$EWW" active-windows 2>/dev/null) || continue
  [ -n "$wins" ] || continue

  for b in "${!OWNER[@]}"; do
    if printf '%s\n' "$wins" | grep -q "^${b}:"; then
      # backdrop is open — orphan only if no owner is open
      if printf '%s\n' "$wins" | grep -qE "${OWNER[$b]}"; then
        strike[$b]=0                       # legit (owner present)
      else
        strike[$b]=$(( strike[$b] + 1 ))
        if [ "${strike[$b]}" -ge "$STRIKES_NEEDED" ]; then
          strike[$b]=0
          "$EWW" close "$b" 2>/dev/null
          [ -n "${RESET[$b]:-}" ] && "$EWW" update "${RESET[$b]}=false" 2>/dev/null
        fi
      fi
    else
      strike[$b]=0                          # backdrop not open
    fi
  done

  # NOTE: the dock window is intentionally always mapped (collapsed when hidden,
  # dock-open=false). That is the normal hidden state now — NOT an orphan — so the
  # guard must never close it. The dock is catcher-free and tiny when collapsed,
  # so it can't cause a lockout anyway.
done
