Users following the public Raspberry Pi Kiosk Tutorial
on a Pi 4 reported that the kiosk booted and loaded the URL correctly, but the
page occupied only part of the monitor — typically the left half, black to the
right. The same steps worked on a Pi 5, which is the only model the tutorial and
krill_kiosk_install.sh had ever been exercised against.
Nothing in the kiosk path pinned the display geometry. The launcher runs
xinit /home/kiosk/kiosk.sh -- :0 vt7 -nocursor — no window manager. Without
one, --kiosk / --start-fullscreen cannot go fullscreen via the EWMH
_NET_WM_STATE_FULLSCREEN hint, because there is nothing to honor it. Chromium
falls back to sizing its own window from whatever RandR reports at startup, and
nothing corrects it afterward. There was no xrandr call, no Virtual line, and
no --window-size anywhere in the tutorial, the installer, or krill-kiosk-fix.sh.
That is harmless when RandR reports the panel. On a Pi 4 it often doesn’t:
modesetting driver auto-enables every connected output side by side, so the
X screen becomes e.g. 3840x1080. Chromium lays the page out at 3840 wide and the
panel shows the left half. Phantom hotplug on the unused port (HDMI-to-VGA
adapters, splitters, some AV receivers) triggers this with one monitor attached.kmsdev pin at
/etc/X11/xorg.conf.d/99-kiosk.conf) was labeled “Pi 5 only”, but the Pi 4 has
the same two cards under vc4-kms-v3d with no guaranteed ordering. On the Pi 5
the ambiguity fails loudly (“Cannot run in framebuffer mode”); on the Pi 4 it
fails quietly, with Xorg on a default screen size instead of the panel’s.Added a geometry-pinning block ahead of the Chromium exec in all three places a
user can get a kiosk from — docs/_posts/2026-04-14-raspberry-pi-kiosk-tutorial.md,
server/package/usr/local/bin/krill_kiosk_install.sh, and krill-kiosk-fix.sh. It
picks the first connected output, turns every other output off so the X screen is
the panel rather than a bounding box, runs --auto --primary --pos 0x0, reads the
resulting WxH back, pins it with xrandr --fb, and passes
--window-position=0,0 --window-size=W,H to Chromium. When xrandr is absent or
reports nothing usable the flags are omitted and behavior is exactly as before.
The tutorial’s Step 4 is no longer scoped to the Pi 5, gained a section explaining
why the block is needed (including the video=HDMI-A-1:1920x1080@60
cmdline.txt escape hatch for the race), and a troubleshooting row pointing at
xrandr --listmonitors.
--kiosk
alone is a request to a WM that isn’t running. Any future “fullscreen browser”
path needs the size asserted, not assumed.KioskDisplayGeometryTest asserts all
three launchers pin the framebuffer, disable non-primary outputs, and pass explicit
window bounds, so the fix can’t be dropped from one of them while the others keep it.
Note these tests read repo files that Gradle doesn’t track as task inputs — use
--rerun-tasks when verifying them by hand or the task reports up-to-date.krill_kiosk_install.sh hard-gates on the Pi 5, so the tutorial was the only Pi 4
path in the repo and nothing had ever run it. Either test that path or say plainly
in the doc which model it was verified on — this post now does the latter.