This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/tools/re-capture/bin/screenshot
Sylpheed RE agent 2b06c68412 tools: screenshot was grabbing a 10-pixel sliver, silently
The wrapper takes the xenia window's geometry from `xwininfo -root -children`
and crops the game surface out of it. Two things are wrong with that here, and
neither errors:

* `-children` lists only DIRECT children of the root, and openbox reparents the
  game window — so the real one is not in that list at all;
* the app owns more than one window of class "xenia_canary" — an off-screen 10x10
  helper as well as the 1280x745 game window — so `head -1` picked the 10x10 one.

Every grab came back a 10-pixel sliver, and nothing failed: `screen_id.py`
happily classified the sliver, the movie-skip heuristic fired on its noise, and
a whole session's worth of screen ids were meaningless. It also drove a stray
tap into the title screen's save-data probe, which crashed the guest.

Walk the full tree and take the largest xenia window by area, using its absolute
geometry (a reparented window's own +X+Y is relative to its frame).
2026-08-18 18:57:29 +00:00

63 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Grab the GAME's image, not the emulator window.
#
# Every pixel oracle in this toolkit (at_menu, at_title, wait_not_black, the
# HUD readers) was measured against a bare 1280x720 game image. xenia's window
# is a GTK window with a menu bar, so the game surface actually starts ~25 px
# down — and when it does, all of those constants read the wrong pixels. That
# is not a hypothetical: a run sat on a plainly visible MAIN MENU for 300 s
# reporting "no main menu", and a later one missed the title screen entirely and
# let the attract movie loop for ten minutes.
#
# The offset is not guessed: it is the xenia window's height minus 720. So this
# works whether or not the menu bar is there, and needs no per-display constant.
# Put this directory first on PATH and existing scripts keep working unchanged.
set -u
REAL=/usr/local/bin/screenshot
OUT="${1:-}"
if [ -z "$OUT" ]; then
dir="${HOME:-/tmp}/shots"; mkdir -p "$dir"
n_file="$dir/.counter"; n=$(( $(cat "$n_file" 2>/dev/null || echo 0) + 1 )); echo "$n" > "$n_file"
OUT="$dir/shot-$(printf '%04d' "$n").png"
fi
RAW="$(mktemp /tmp/shot-raw-XXXXXX.png)"
trap 'rm -f "$RAW"' EXIT
"$REAL" "$RAW" >/dev/null || exit 1
# "…": ("xenia_canary" "Xenia_canary") 1280x745+1+20 +1+45
#
# TWO traps here, both measured (2026-08-18):
# * `-children` only lists DIRECT children of the root, and openbox reparents
# the game window, so the real one is not there at all;
# * this app owns more than one window with the class "xenia_canary" — an
# off-screen 10x10 helper as well as the 1280x745 game window — so `head -1`
# picked the 10x10 one and every grab came back a 10-pixel sliver. Nothing
# errored: the pixel oracles simply classified the sliver, and a whole
# session's screen ids were noise.
# So walk the full tree and take the LARGEST xenia window, by area. Use the
# trailing ABSOLUTE geometry (the second +X+Y), because a reparented window's
# own +X+Y is relative to its frame.
geo=$(xwininfo -root -tree 2>/dev/null \
| grep '"xenia_canary"' \
| grep -oE '[0-9]+x[0-9]+\+-?[0-9]+\+-?[0-9]+[[:space:]]+\+-?[0-9]+\+-?[0-9]+' \
| awk '{ split($1, g, /[x+]/); a = g[1] * g[2];
if (a > best) { best = a; split($2, p, /\+/);
out = g[1] "x" g[2] "+" p[2] "+" p[3] } }
END { if (best) print out }')
if [ -z "$geo" ]; then # no window found — hand back the raw grab
cp "$RAW" "$OUT"; echo "$OUT"; exit 0
fi
W=${geo%%x*}; rest=${geo#*x}; H=${rest%%+*}; rest=${rest#*+}; X=${rest%%+*}; Y=${rest#*+}
OFF=$(( H - 720 )); [ "$OFF" -lt 0 ] && OFF=0
TOP=$(( Y + OFF ))
[ "$TOP" -lt 0 ] && TOP=0
if [ "$OFF" -eq 0 ] && [ "$TOP" -eq 0 ] && [ "$X" -eq 0 ]; then
cp "$RAW" "$OUT"; echo "$OUT"; exit 0
fi
# Height is whatever is still on screen: a 1280x745 window on a 720-high root
# loses its last rows, and every oracle point in use sits well above them.
convert "$RAW" -crop "${W}x720+${X}+${TOP}" +repage "$OUT" 2>/dev/null \
|| cp "$RAW" "$OUT"
echo "$OUT"