#!/bin/bash
# Launches the screensaver fullscreen on every connected monitor (X11 / st).
set -u

export PATH="$HOME/.local/bin:$PATH"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WIN_CLASS="screensaver"

command -v tte >/dev/null || { echo "tte not found (pipx install terminaltexteffects)" >&2; exit 1; }

# Already running? Don't stack another instance.
if xdotool search --class "^${WIN_CLASS}\$" >/dev/null 2>&1; then
  exit 0
fi

for mon in $(xrandr --listmonitors | awk 'NR>1 {print $3}'); do
  # mon looks like 3440/798x1440/334+0+0
  geom="${mon%%+*}"          # 3440/798x1440/334
  offsets="+${mon#*+}"       # +0+0
  w="${geom%%/*}"
  h_part="${geom#*x}"
  h="${h_part%%/*}"
  x="$(echo "$offsets" | cut -d+ -f2)"
  y="$(echo "$offsets" | cut -d+ -f3)"

  # st has no runtime equivalent of kitty's window_padding_width/mouse_hide_wait
  # overrides (those are compile-time-only in st), so they're just dropped here.
  st -c "$WIN_CLASS" \
    -f "JetBrainsMono Nerd Font:pixelsize=24:antialias=true:autohint=true" \
    -A 1.0 \
    -e "$SCRIPT_DIR/screensaver" &
  kpid=$!

  # Wait for the window owned by this st process to appear, then pin it
  # to this monitor and fullscreen it.
  newwin=""
  for _ in $(seq 1 50); do
    for win in $(xdotool search --class "^${WIN_CLASS}\$" 2>/dev/null); do
      if [[ "$(xdotool getwindowpid "$win" 2>/dev/null)" == "$kpid" ]]; then
        newwin="$win"
        break 2
      fi
    done
    sleep 0.1
  done

  if [[ -n "$newwin" ]]; then
    # The window may not be fully mapped/reparented yet right after it
    # appears in `xdotool search`, so retry placement to ride out the
    # occasional BadWindow race with the window manager. `wmctrl`
    # returning success only means the fullscreen request was sent, not
    # that the WM actually acted on it (e.g. it's silently dropped if the
    # window isn't mapped yet in the WM's eyes) -- read the geometry back
    # and keep retrying until it actually matches the monitor, instead of
    # giving up after a fixed few tries and leaving it windowed.
    for attempt in $(seq 1 30); do
      xdotool windowactivate --sync "$newwin" 2>/dev/null
      xdotool windowmove "$newwin" "$x" "$y" 2>/dev/null
      xdotool windowsize "$newwin" "$w" "$h" 2>/dev/null
      wmctrl -ir "$newwin" -b add,fullscreen 2>/dev/null

      geo="$(xdotool getwindowgeometry --shell "$newwin" 2>/dev/null)"
      gx="$(grep -m1 '^X=' <<<"$geo" | cut -d= -f2)"
      gy="$(grep -m1 '^Y=' <<<"$geo" | cut -d= -f2)"
      gw="$(grep -m1 '^WIDTH=' <<<"$geo" | cut -d= -f2)"
      gh="$(grep -m1 '^HEIGHT=' <<<"$geo" | cut -d= -f2)"
      if [[ "$gx" == "$x" && "$gy" == "$y" && "$gw" == "$w" && "$gh" == "$h" ]]; then
        break
      fi
      sleep 0.1
    done
  fi
done
