From d1cebec142e4739b7a3f8c8db0d5169e52cf90cb Mon Sep 17 00:00:00 2001 From: Brad Anderson Date: Wed, 14 Oct 2026 18:03:33 -0700 Subject: [PATCH] fix(streaming): measure Flash Player's menu bar from the movie's offset GTK draws the projector's menu bar in its window, not in a child window, so the previous lookup found nothing and, under set -e and pipefail, silently ended the block that moves the window. The movie is the window's largest child, and its offset is the menu bar's height (56px on flashbox). The block no longer stops on errors, logs what it measured and where the window ended up, and GAME_WIDTH/GAME_HEIGHT, unused now, are dropped. --- streaming/session-manager/src/docker.ts | 4 +-- streaming/streamer/Dockerfile | 1 + streaming/streamer/README.md | 8 ++++-- .../streamer/root/usr/local/bin/fp-launch | 28 +++++++++++++------ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/streaming/session-manager/src/docker.ts b/streaming/session-manager/src/docker.ts index 981deec..32f7043 100644 --- a/streaming/session-manager/src/docker.ts +++ b/streaming/session-manager/src/docker.ts @@ -46,9 +46,7 @@ export class DockerDriver implements Driver { `PUID=${uid}`, `PGID=${gid}`, `SUBFOLDER=${streamPath(id)}`, - // The game's exact size, and the display's, rounded up to even for H.264 - `GAME_WIDTH=${size.width}`, - `GAME_HEIGHT=${size.height}`, + // The game's size, rounded up to even for H.264 `SELKIES_MANUAL_WIDTH=${size.width + (size.width % 2)}`, `SELKIES_MANUAL_HEIGHT=${size.height + (size.height % 2)}`, 'SELKIES_UI_SHOW_SIDEBAR=false', diff --git a/streaming/streamer/Dockerfile b/streaming/streamer/Dockerfile index 3a95ceb..fa325bc 100644 --- a/streaming/streamer/Dockerfile +++ b/streaming/streamer/Dockerfile @@ -30,6 +30,7 @@ RUN apt-get update && \ libxtst6 \ libxxf86vm1 \ sqlite3 \ + x11-utils \ xdotool && \ rm -rf /var/lib/apt/lists/* diff --git a/streaming/streamer/README.md b/streaming/streamer/README.md index 1b0605a..ad1e4db 100644 --- a/streaming/streamer/README.md +++ b/streaming/streamer/README.md @@ -54,6 +54,8 @@ is Flash Player's save directory, so the session manager syncs both to the player's browser. OldCPUSimulator hangs under Wine, so its target runs under `cpulimit` at the same share of the CPU. A Flash projector's window is stretched to the display and moved up by its menu bar's height, which hides the -menu bar; the height is the window's opening height less the movie's -(`GAME_HEIGHT`). Its full-screen mode isn't used, since some games, such as -Bloons, don't play right in it. Flashpoint Navigator's toolbars are hidden. +menu bar. GTK draws the menu bar in the window itself and the movie in a child +window below it, so the movie's offset, read with `xwininfo`, is the menu bar's +height. The window is made override-redirect first, since the window manager +keeps windows on screen. Its full-screen mode isn't used, since some games, such +as Bloons, don't play right in it. Flashpoint Navigator's toolbars are hidden. diff --git a/streaming/streamer/root/usr/local/bin/fp-launch b/streaming/streamer/root/usr/local/bin/fp-launch index 8b327ff..b20c873 100755 --- a/streaming/streamer/root/usr/local/bin/fp-launch +++ b/streaming/streamer/root/usr/local/bin/fp-launch @@ -49,16 +49,28 @@ case ${app,,} in if [[ ${app,,} == 'fpsoftware\flash\'* ]]; then # Hide the projector's menu bar by moving it above the display, and fill # the display with the movie. Not full screen, which some games, such as - # Bloons, don't play right in. The window opens at the movie's size plus - # the menu bar, which gives the menu bar's height. + # Bloons, don't play right in. The window manager keeps windows on + # screen, so the window is taken out of its hands first. ( + set +eo pipefail wid=$(xdotool search --sync --onlyvisible --name 'Flash Player' | head -1) - eval "$(xdotool getwindowgeometry --shell "$wid")" - read -r display_width display_height < <(xdotool getdisplaygeometry) - menu=$((HEIGHT - ${GAME_HEIGHT:-$display_height})) - ((menu > 0 && menu < 100)) || menu=0 - xdotool windowsize "$wid" "$display_width" $((display_height + menu)) \ - windowmove "$wid" 0 $((-menu)) windowactivate "$wid" + read -r width height < <(xdotool getdisplaygeometry) + # GTK draws the menu bar in the window itself, and the movie in the + # largest child window, below it: the movie's offset is the menu bar's height + menu=$(xwininfo -children -id "$wid" | awk ' + match($0, /[0-9]+x[0-9]+\+-?[0-9]+\+-?[0-9]+/) { + split(substr($0, RSTART, RLENGTH), g, /[x+]/) + if (g[1] * g[2] > area) { area = g[1] * g[2]; top = g[4] } + } + END { print top + 0 }') + ((menu >= 0 && menu < height)) || menu=0 + echo "Flash Player window $wid: menu bar ${menu}px, display ${width}x${height}" + xdotool windowunmap --sync "$wid" + xdotool set_window --overrideredirect 1 "$wid" + xdotool windowmap --sync "$wid" + xdotool windowsize "$wid" "$width" $((height + menu)) \ + windowmove "$wid" 0 $((-menu)) windowfocus "$wid" + xdotool getwindowgeometry "$wid" ) & fi cd "${argv[0]}"