fix(kiosk): correct --window-size to DIPs + panel-derived layout target
The kiosk window was sized in physical pixels, but Chromium interprets
--window-size in DIPs: with any device-scale > 1 the window painted
scale-times larger than the panel, and with no window manager in the
kiosk X session --kiosk/--start-fullscreen could not snap it back. On a
4K TV at scale 3 that meant an 11520x6480 window — 9x the panel area —
which blew the compositor tile-memory budget ("tile memory limits
exceeded, some content may not draw") and froze the screen on the last
painted frame; smaller scales cropped content off the right/bottom.
- Size the window in DIPs (panel / scale) so DIPs x scale = the panel.
- Panels >=2560 wide now target a 1920-wide layout (4K -> scale 2.0,
validated on the Framework's 72" 4K TV: spacious desktop layout at 2x
sharpness); smaller panels keep the 1280 target (1080p TV -> 1.5).
- Optional ARCHIPELAGO_KIOSK_MAX_WIDTH cap: drop to the best <=N-wide
xrandr mode for weak hardware (TV upscales instead of us rasterizing).
- Source /etc/archipelago/kiosk-display.conf so the upcoming Settings
display-resolution picker can manage these knobs per node.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
918b0275a9
commit
be5122048b
@ -22,6 +22,11 @@ if [ "$X_READY" != "true" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Settings-managed display overrides (system.kiosk-display.set writes this
|
||||
# file, then restarts the kiosk): may set ARCHIPELAGO_KIOSK_SCALE,
|
||||
# ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH or ARCHIPELAGO_KIOSK_MAX_WIDTH.
|
||||
[ -f /etc/archipelago/kiosk-display.conf ] && . /etc/archipelago/kiosk-display.conf
|
||||
|
||||
KIOSK_SAFE_AREA_X_PX=${ARCHIPELAGO_KIOSK_SAFE_AREA_X_PX:-}
|
||||
KIOSK_SAFE_AREA_Y_PX=${ARCHIPELAGO_KIOSK_SAFE_AREA_Y_PX:-}
|
||||
|
||||
@ -54,6 +59,25 @@ configure_display() {
|
||||
' /tmp/archipelago-kiosk-xrandr.txt)
|
||||
[ -n "$mode" ] || mode=1920x1080
|
||||
|
||||
# Optional resolution cap for weak hardware: ARCHIPELAGO_KIOSK_MAX_WIDTH=1920
|
||||
# drops a 4K panel to its best <=1920-wide mode (the TV upscales) so the
|
||||
# software rasterizer paints 1/4 the pixels. Off by default — native mode
|
||||
# is sharp and fits the tile budget now that --window-size is in DIPs.
|
||||
local max_w=${ARCHIPELAGO_KIOSK_MAX_WIDTH:-0}
|
||||
if [ "$max_w" -gt 0 ] 2>/dev/null && [ "${mode%x*}" -gt "$max_w" ] 2>/dev/null; then
|
||||
local capped
|
||||
capped=$(awk -v out="$output" -v maxw="$max_w" '
|
||||
$1 == out { active = 1; next }
|
||||
active && /^[[:space:]]+[0-9]+x[0-9]+/ {
|
||||
split($1, wh, "x")
|
||||
if (wh[1] + 0 <= maxw && wh[1] + 0 > best_w) { best_w = wh[1] + 0; best = $1 }
|
||||
}
|
||||
active && /^[^[:space:]]/ { active = 0 }
|
||||
END { if (best) print best }
|
||||
' /tmp/archipelago-kiosk-xrandr.txt)
|
||||
[ -n "$capped" ] && mode=$capped
|
||||
fi
|
||||
|
||||
# Kiosk should use one native output. A spanning desktop makes Chromium land
|
||||
# on the laptop panel or stretch across both outputs.
|
||||
for internal in $(awk '/ connected/ && $1 ~ /^eDP|^LVDS/{print $1}' /tmp/archipelago-kiosk-xrandr.txt); do
|
||||
@ -90,9 +114,17 @@ configure_display
|
||||
# panel becomes a 3840px-wide viewport and the UI renders tiny — and a
|
||||
# keyboard-less kiosk can't zoom. Derive Chromium's device-scale-factor from
|
||||
# the detected panel width so the *effective* CSS viewport lands near a
|
||||
# comfortable across-the-room target, scaling the whole UI up on big screens:
|
||||
# 1920x1080 -> 1.50 | 2560x1440 -> 2.00 | 3840x2160 -> 3.00 (clamped 1.0-3.0)
|
||||
KIOSK_TARGET_CSS_WIDTH=${ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH:-1280}
|
||||
# comfortable target. Panels >=2560 wide get a 1920-wide layout (4K -> scale
|
||||
# 2.0 — user-validated on a 72" TV: spacious desktop layout, 2x sharp);
|
||||
# smaller panels get a 1280-wide layout (1920 -> 1.50, laptops -> 1.0).
|
||||
if [ -z "${ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH:-}" ]; then
|
||||
if [ "$KIOSK_MODE_W" -ge 2560 ] 2>/dev/null; then
|
||||
ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH=1920
|
||||
else
|
||||
ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH=1280
|
||||
fi
|
||||
fi
|
||||
KIOSK_TARGET_CSS_WIDTH=$ARCHIPELAGO_KIOSK_TARGET_CSS_WIDTH
|
||||
if [ -n "${ARCHIPELAGO_KIOSK_SCALE:-}" ]; then
|
||||
KIOSK_SCALE=$ARCHIPELAGO_KIOSK_SCALE
|
||||
else
|
||||
@ -100,6 +132,14 @@ else
|
||||
'BEGIN{if(t<=0)t=1280; s=w/t; s=int(s*4+0.5)/4; if(s<1)s=1; if(s>3)s=3; printf "%.2f", s}')
|
||||
fi
|
||||
|
||||
# Chromium's --window-size is in DIPs (CSS px), not physical pixels: at scale S
|
||||
# the window paints S x larger. This X session has no window manager, so
|
||||
# --kiosk/--start-fullscreen cannot snap an oversized window back to the panel
|
||||
# — it just hangs off the right/bottom edges (content cropped, background art
|
||||
# offscreen). Size the window in DIPs so DIPs x scale = the panel exactly.
|
||||
KIOSK_WIN_W=$(awk -v w="$KIOSK_MODE_W" -v s="$KIOSK_SCALE" 'BEGIN{printf "%d", w/s}')
|
||||
KIOSK_WIN_H=$(awk -v h="$KIOSK_MODE_H" -v s="$KIOSK_SCALE" 'BEGIN{printf "%d", h/s}')
|
||||
|
||||
xhost +SI:localuser:archipelago 2>/dev/null || true
|
||||
xsetroot -solid black 2>/dev/null || true
|
||||
xset s off 2>/dev/null || true
|
||||
@ -157,7 +197,7 @@ while true; do
|
||||
--disable-component-update \
|
||||
$GPU_FLAGS \
|
||||
--renderer-process-limit=2 \
|
||||
--window-size=${KIOSK_MODE_W},${KIOSK_MODE_H} \
|
||||
--window-size=${KIOSK_WIN_W},${KIOSK_WIN_H} \
|
||||
--window-position=0,0 \
|
||||
--start-fullscreen \
|
||||
--force-device-scale-factor=${KIOSK_SCALE} \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user