// The KVM of the machine you are looking at: the device's own web page, shown in the tab. // // One per machine, and it follows the machine switcher — switch to `grid` and you get // grid's KVM. The address is held on the **hub**, not on the machine, because a KVM earns // its keep exactly when that machine is down and cannot answer for itself; the hub proxies // the device either way. // // Nothing here knows anything about any particular KVM. It is an iframe pointed at Ham // Lab's own proxy, so whatever web UI the device serves is what you get. // // On the keyboard: a page cannot capture keys and forward them into an iframe, and does not // need to. An iframe with focus receives them directly. What the browser itself swallows — // Escape, Tab, Ctrl-W, the function keys — is what `navigator.keyboard.lock()` releases, // and that needs fullscreen and only exists in Chromium. Everywhere else you get the plain // version, which is most keys, and the device's own on-screen buttons for the rest. import { FormEvent, useCallback, useEffect, useRef, useState } from 'react' import { KVM as Device, api } from './api' import { Btn, Loading, askYes, toast, useEscape } from './ui' // lock() releases the keys the browser would otherwise keep for itself. Chromium only; a // browser without it simply does not get the extra keys. type KeyboardLock = { lock?: (keys?: string[]) => Promise; unlock?: () => void } const keyboardAPI = (): KeyboardLock | undefined => (navigator as unknown as { keyboard?: KeyboardLock }).keyboard // Fullscreen, across the three ways browsers spell it. Safari on a Mac wants the webkit // prefix; Safari on iOS has no fullscreen for an ordinary element at all — only for a //