From 914ada46058229e46e8264af41bd67907dfd28a5 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Wed, 26 Aug 2026 23:02:08 +0000 Subject: [PATCH] tools: never crop to a window too narrow to be a game frame The app owns TWO windows of class xenia_canary -- measured in the tree right now as 10x10+10+10 and 1280x745+1+20. Largest-by-area picks the game window while both are present, but during a load or mode switch the game window is briefly absent from the tree, the 10x10 helper wins by default, and the crop produces a 10x710 SLIVER. That is exactly the grab screen_id classified as `menu` on 2026-08-26, which let a nav guard pass on garbage and loaded the wrong stage. Ignore candidates narrower than 640 so nothing is selected in that case and the existing fall-through hands back the raw root grab -- itself a valid full frame. Verified on the selection logic directly: with both windows listed the pick is unchanged (1280x745+1+45); with only the helper listed the old logic returned 10x10+10+10 and the new one selects nothing. Pairs with 6aa31e5, which rejects such a frame at the consumer. --- tools/re-capture/bin/screenshot | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/re-capture/bin/screenshot b/tools/re-capture/bin/screenshot index abccb1dc..593df3b6 100755 --- a/tools/re-capture/bin/screenshot +++ b/tools/re-capture/bin/screenshot @@ -42,8 +42,17 @@ 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] } } + # MIN_W: largest-by-area is not enough on its own. When the game + # window is momentarily absent from the tree (during a load or a + # mode switch) the only xenia_canary window left is the narrow + # helper, it wins by default, and the crop below produces a + # SLIVER. Measured 2026-08-26: a 10x710 grab that screen_id then + # classified as `menu`, so a nav guard passed on garbage and the + # run loaded the wrong stage. Ignore anything too narrow to be a + # game frame and fall through to the raw root grab instead. + if (g[1] >= 640 && 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