Safari on a Mac wants the webkit prefix; Safari on iOS has no fullscreen for an ordinary
element at all, only for a <video>, so requestFullscreen was simply undefined and the tab
threw. It now uses whichever spelling the browser has, and where there is none the frame
fills the viewport in-page instead — the same result minus the browser's own chrome — with
a Done button and Escape to come back. The button reads Expand rather than Fullscreen when
that is what it will do.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It was a hub-side list you pointed at machines, which had it backwards. A machine has one
KVM; switch to grid and you get grid's. The address is still kept on the hub rather than on
the machine, because a KVM earns its keep exactly when that machine is down and cannot
answer for itself — so the tab reaches the device either way. Adding a second KVM for a
machine replaces the first rather than sitting beside it.
The tab is no longer hub-only and now sits beside Machines in the rail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ham Lab proxies each KVM from its own origin, which is what makes the simple version
possible. A KVM that speaks only plain HTTP would otherwise be blocked outright as mixed
content in a TLS console; served from here it loads, it is behind this login rather than a
second one, and the iframe is same-origin.
Nothing in it knows anything about any particular device. The prefix /kvm/<id>/ is only the
entry point — a device UI asks for its assets by absolute path, which no prefix can rewrite
away, so any request Ham Lab does not serve itself is routed back to whichever KVM the
asking page belongs to, worked out from the Referer and from a cookie when there is no
Referer, as on a WebSocket upgrade. Ham Lab's own routes always match first, so a device can
never shadow the console, and the fallback is gated on a live session.
The list is hub-side on purpose: a KVM earns its keep when the machine is down, which is
when that machine's own Ham Lab cannot answer.
On the keyboard, a page cannot forward keys into an iframe and does not need to — one with
focus receives them directly. Fullscreen plus navigator.keyboard.lock() is what takes
Escape, Tab and Ctrl-W back from the browser; that is Chromium-only and the tab says so
rather than pretending otherwise.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>