This commit is contained in:
@@ -15,7 +15,11 @@ export default function ServerConsolePage() {
|
||||
const serverId = params.id as string;
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const connectionRef = useRef<{ disconnect: () => void; setScale: (scale: number) => void } | null>(null);
|
||||
const connectionRef = useRef<{
|
||||
disconnect: () => void;
|
||||
setScale: (scale: number) => void;
|
||||
resize: (width: number, height: number) => void;
|
||||
} | null>(null);
|
||||
|
||||
const [protocol, setProtocol] = useState<string>(searchParams.get("protocol") || "");
|
||||
const [keyId, setKeyId] = useState<string>("");
|
||||
@@ -121,9 +125,18 @@ export default function ServerConsolePage() {
|
||||
setPending(null);
|
||||
}, [connected, pending]);
|
||||
|
||||
// Apply zoom changes live without reconnecting.
|
||||
// Apply zoom live without reconnecting: resize the remote to a resolution
|
||||
// that, once scaled to fit the container, yields the requested zoom. Higher
|
||||
// zoom = fewer remote pixels rendered larger. Display always fits the
|
||||
// container exactly, so no scrollbars appear.
|
||||
useEffect(() => {
|
||||
connectionRef.current?.setScale(zoom / dprRef.current);
|
||||
if (!connectionRef.current || !containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const dpr = dprRef.current;
|
||||
const remoteW = Math.floor((rect.width * dpr) / zoom);
|
||||
const remoteH = Math.floor((rect.height * dpr) / zoom);
|
||||
connectionRef.current.resize(remoteW, remoteH);
|
||||
connectionRef.current.setScale(zoom / dpr);
|
||||
}, [zoom]);
|
||||
|
||||
function handleDisconnect() {
|
||||
@@ -276,7 +289,7 @@ export default function ServerConsolePage() {
|
||||
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="min-h-[500px] flex-1 overflow-auto rounded-lg border border-border bg-black"
|
||||
className="min-h-[500px] flex-1 overflow-hidden rounded-lg border border-border bg-black"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ export function openConsole(
|
||||
container: HTMLElement,
|
||||
wsUrl: string,
|
||||
connectData = ""
|
||||
): { disconnect: () => void; setScale: (scale: number) => void } {
|
||||
): { disconnect: () => void; setScale: (scale: number) => void; resize: (width: number, height: number) => void } {
|
||||
// Guacamole's WebSocketTunnel builds the socket URL as `wsUrl + "?" + data`,
|
||||
// so wsUrl must NOT already contain a query string — pass params via connectData.
|
||||
const tunnel = new Guacamole.WebSocketTunnel(wsUrl);
|
||||
@@ -46,10 +46,15 @@ export function openConsole(
|
||||
const keyboard = new Guacamole.Keyboard(container);
|
||||
keyboard.onkeydown = (k: number) => client.sendKeyEvent(1, k);
|
||||
keyboard.onkeyup = (k: number) => client.sendKeyEvent(0, k);
|
||||
// Guacamole.Mouse consumes the native mousedown, so clicking the console never
|
||||
// moves DOM focus back to it. Refocus explicitly so keyboard capture resumes.
|
||||
const refocus = () => container.focus();
|
||||
container.addEventListener("mousedown", refocus);
|
||||
container.focus();
|
||||
|
||||
return {
|
||||
disconnect() {
|
||||
container.removeEventListener("mousedown", refocus);
|
||||
keyboard.onkeydown = null;
|
||||
keyboard.onkeyup = null;
|
||||
if (typeof keyboard.reset === "function") keyboard.reset();
|
||||
@@ -59,5 +64,8 @@ export function openConsole(
|
||||
scale = s;
|
||||
display.scale(s);
|
||||
},
|
||||
resize(width: number, height: number) {
|
||||
client.sendSize(width, height);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user