#!/bin/bash
# Runs random TTE (terminal text effects) animations in a loop.
# Meant to be launched inside a fullscreen terminal by screensaver-launch.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ART_FILE="${SCREENSAVER_ART:-$SCRIPT_DIR/screensaver.txt}"
# 120fps of full-canvas terminal effects pegged a CPU core and, on this
# machine, the fans -- most effects don't need anywhere near that to look
# smooth. Cuts CPU roughly in half on its own; combined with the larger
# font in screensaver-launch (fewer cells to animate per frame) it's closer
# to a 3-4x reduction.
FRAME_RATE="${SCREENSAVER_FPS:-30}"
WIN_CLASS="screensaver"
# DPMS blanking (xset dpms, 300s by default -- see ~/.xinitrc) turns the
# display off but doesn't stop this from rendering into its window, so
# without this tte just kept animating into a screen nobody could see,
# burning CPU/GPU for as long as the machine stayed idle.
#
# This has to pause tte in place rather than screensaverd killing the
# window from outside: creating *or* destroying an X window forces the
# display live again (confirmed live -- mapping or killing an unrelated
# window while DPMS-off flips "Monitor is Off" back to "On" instantly;
# writing new content into an already-mapped window does not), so killing
# the window the moment it blanks just wakes it right back up, and with
# screensaverd still seeing >IDLE_SECONDS of idle, relaunches the
# screensaver -- which wakes it again. The screen never actually stayed off.
monitor_off() {
xset q 2>/dev/null | grep -q "Monitor is \(Off\|Standby\|Suspend\)"
}
screensaver_in_focus() {
local id
id=$(xdotool getactivewindow 2>/dev/null) || return 1
xprop -id "$id" WM_CLASS 2>/dev/null | grep -q "\"$WIN_CLASS\""
}
exit_screensaver() {
tput cnorm 2>/dev/null
pkill -x tte 2>/dev/null
exit 0
}
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT
printf '\033]11;rgb:00/00/00\007' # black background
tput civis 2>/dev/null # hide text cursor
tty=$(tty 2>/dev/null)
while true; do
# Blanked: sit idle without touching the window at all (see monitor_off
# above for why) until either DPMS wakes on its own or screensaverd kills
# this whole window from outside because of real input.
if monitor_off; then
sleep 1
continue
fi
tte -i "$ART_FILE" \
--frame-rate "$FRAME_RATE" --canvas-width 0 --canvas-height 0 --reuse-canvas --anchor-canvas c --anchor-text c \
--random-effect --no-eol --no-restore-cursor &
while pgrep -t "${tty#/dev/}" -x tte >/dev/null; do
if read -n1 -t 1 || ! screensaver_in_focus; then
exit_screensaver
fi
if monitor_off; then
pkill -x tte 2>/dev/null
break
fi
done
done