#!/bin/bash
# Idle watcher: launches the screensaver after IDLE_SECONDS of inactivity
# and kills it the moment real activity resumes.
#
# DPMS blanking is handled inside bin/screensaver itself (it pauses tte
# without touching the window) rather than here -- destroying/creating the
# fullscreen window from this end wakes the display right back up (creating
# *or* destroying an X window forces the DRM connector live again to show
# whatever's now on screen, confirmed live: `xset dpms force off` then
# mapping or killing an unrelated window immediately flipped "Monitor is
# Off" back to "On"; writing new content into an *already-mapped* window
# does not). Killing the window here used to retrigger exactly that: blank
# -> this script kills the screensaver window -> killing it wakes the
# display -> still idle, so the screensaver relaunches -> new window wakes
# it again -- the screen never actually stayed off.
set -u

# sxwm's `exec` runs commands via execvp with whatever PATH the X session
# started with, which may not include a pipx-installed `tte`. Make sure it's
# found regardless.
export PATH="$HOME/.local/bin:$PATH"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
IDLE_SECONDS="${SCREENSAVER_IDLE_SECONDS:-150}"
WIN_CLASS="screensaver"
PAUSE_FILE="${XDG_RUNTIME_DIR:-/tmp}/screensaver-paused"

is_running() {
  xdotool search --class "^${WIN_CLASS}\$" >/dev/null 2>&1
}

# Set by screensaver-toggle. Checked fresh every loop iteration (not just
# at launch time) so toggling pause while the screensaver is already
# showing kills it immediately, same as real input would.
is_paused() {
  [[ -e "$PAUSE_FILE" ]]
}

# xssstate only tracks keyboard/mouse input, so a video playing quietly
# (no input for the whole runtime) still counts as "idle" and would get
# covered by the screensaver. playerctl (already a dependency for the
# media keybindings) reports MPRIS playback state for players that
# support it (mpv, VLC, Firefox/Chromium, ...), so use that as an extra
# "really idle" check.
media_playing() {
  command -v playerctl >/dev/null 2>&1 || return 1
  [ "$(playerctl status 2>/dev/null)" = "Playing" ]
}

# Only used to avoid *launching* (mapping a new window) while already
# blanked, which would wake the display right back up for no reason -- see
# the file header for why this isn't also used to stop it.
monitor_off() {
  xset q 2>/dev/null | grep -q "Monitor is \(Off\|Standby\|Suspend\)"
}

stop_screensaver() {
  pkill -f "$SCRIPT_DIR/screensaver\$" 2>/dev/null
  pkill -x tte 2>/dev/null
  for win in $(xdotool search --class "^${WIN_CLASS}\$" 2>/dev/null); do
    xdotool windowkill "$win" 2>/dev/null
  done
}

while true; do
  idle_ms=$(xssstate -i)
  idle_s=$((idle_ms / 1000))

  if (( idle_s >= IDLE_SECONDS )) && ! is_running && ! media_playing && ! is_paused && ! monitor_off; then
    "$SCRIPT_DIR/screensaver-launch"
  elif is_running && { (( idle_s < 1 )) || media_playing || is_paused; }; then
    stop_screensaver
  fi

  sleep 1
done
