import { useEffect, useRef, useState, type ReactNode } from "react"; import { subscribeDisplaySurface, type DisplaySurface } from "../platform/displayRouting"; import { subscribeControllerToken } from "../input/controller"; import { DEFAULT_CONTROLLER_GLYPHS } from "../input/controllerGlyphs"; export function DualDisplayFrame({ top, bottom }: { top: ReactNode; bottom: ReactNode }) { const dedicatedSurface = new URLSearchParams(window.location.search).get("display"); const [activeSurface, setActiveSurface] = useState(() => dedicatedSurface === "bottom" ? "bottom" : "top"); const activeSurfaceRef = useRef(activeSurface); activeSurfaceRef.current = activeSurface; useEffect(() => { if (!document.documentElement.classList.contains("native-platform")) return; if (dedicatedSurface === "top" || dedicatedSurface === "bottom") return; const toggle = () => setActiveSurface((surface) => surface === "top" ? "bottom" : "top"); const unsubscribeSurface = subscribeDisplaySurface(setActiveSurface); const unsubscribeController = subscribeControllerToken(({ token, repeat }) => { if (token === "Button8" && !repeat) toggle(); }); const onKeyDown = (event: KeyboardEvent) => { if (event.key !== "Tab" || event.repeat) return; event.preventDefault(); toggle(); }; window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); unsubscribeSurface(); unsubscribeController(); }; }, [dedicatedSurface]); if (dedicatedSurface === "top" || dedicatedSurface === "bottom") { return
{dedicatedSurface === "top" ? top : bottom}
; } return (
Main viewport960 × 540 CSS · 1920 × 1080 · 120Hz
{top}
Context display620 × 540 CSS · 1240 × 1080 · 60Hz
{bottom}
); }