diff --git a/virtweb_frontend/src/routes/VNCRoute.tsx b/virtweb_frontend/src/routes/VNCRoute.tsx index 18712fe..64e8da2 100644 --- a/virtweb_frontend/src/routes/VNCRoute.tsx +++ b/virtweb_frontend/src/routes/VNCRoute.tsx @@ -1,7 +1,7 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import FullscreenIcon from "@mui/icons-material/Fullscreen"; import FullscreenExitIcon from "@mui/icons-material/FullscreenExit"; -import { IconButton } from "@mui/material"; +import { IconButton, Tooltip } from "@mui/material"; import React, { useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { VncScreen } from "react-vnc"; @@ -10,6 +10,8 @@ import { VMApi, VMInfo } from "../api/VMApi"; import { useSnackbar } from "../hooks/providers/SnackbarProvider"; import { time } from "../utils/DateUtils"; import { AsyncWidget } from "../widgets/AsyncWidget"; +import RFB from "react-vnc/dist/types/noVNC/core/rfb"; +import KeyboardAltIcon from "@mui/icons-material/KeyboardAlt"; interface VNCTokenInfo { url: string; @@ -41,6 +43,7 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement { const [token, setToken] = React.useState(); const [counter, setCounter] = React.useState(1); + const [rfb, setRFB] = React.useState(); const vncRef = React.createRef(); @@ -67,6 +70,7 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement { }; const disconnected = () => { + setRFB(undefined); connect(true); }; @@ -96,10 +100,12 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement { return (
{/* Controls */} -
+
+ + {/* Toggle fullscreen */} {!document.fullscreenElement ? ( @@ -109,6 +115,15 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement { )} + + {/* Keystrokes */} + {rfb && ( + + rfb?.sendCtrlAltDel()}> + + + + )}
{/* Screen */} @@ -126,6 +141,7 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement { console.info("VNC disconnected " + token?.url); disconnected(); }} + onConnect={(rfb) => setRFB(rfb)} />