Wire mouse + keyboard input for RDP sessions (#47)
The multi-session RemoteDesktop view rendered the remote display but never captured input — no Guacamole.Mouse / Guacamole.Keyboard were created — so the desktop showed but the mouse and keyboard did nothing. Add per-session input: - Guacamole.Mouse on the display element, forwarding mouse state via client.sendMouseState with coordinates divided by the current display scale so clicks land correctly on the scaled-down canvas. - Guacamole.Keyboard on document, forwarding key events via client.sendKeyEvent, but only while that session is the active/visible tab so a background session can't steal keystrokes. - Detach keyboard handlers on session close and on unmount. Co-authored-by: Samuel James <ssamjame@amazon.com> Co-authored-by: Kiro <noreply@kiro.dev>
This commit is contained in:
parent
5f27943974
commit
8ccc959dc9
1 changed files with 43 additions and 2 deletions
|
|
@ -18,6 +18,8 @@ interface SessionHandle {
|
|||
client: any
|
||||
container: HTMLDivElement
|
||||
display: any
|
||||
mouse: any
|
||||
keyboard: any
|
||||
}
|
||||
|
||||
// Scale the Guacamole display to fit its visible container. The display canvas
|
||||
|
|
@ -49,7 +51,13 @@ export default function RemoteDesktop() {
|
|||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
handlesRef.current.forEach(({ client }) => client.disconnect())
|
||||
handlesRef.current.forEach(({ client, keyboard }) => {
|
||||
if (keyboard) {
|
||||
keyboard.onkeydown = null
|
||||
keyboard.onkeyup = null
|
||||
}
|
||||
client.disconnect()
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
|
@ -79,7 +87,38 @@ export default function RemoteDesktop() {
|
|||
const tunnel = new Guacamole.WebSocketTunnel(`${proto}://${window.location.host}/api/guacamole`)
|
||||
const client = new Guacamole.Client(tunnel)
|
||||
const display = client.getDisplay()
|
||||
handlesRef.current.set(sessionId, { client, container, display })
|
||||
|
||||
// --- Input wiring (mouse + keyboard) ---
|
||||
// Mouse events are captured on the display element. Coordinates must be
|
||||
// divided by the current display scale so clicks land where the user sees
|
||||
// them (the canvas is scaled down to fit the panel).
|
||||
const mouse = new Guacamole.Mouse(display.getElement())
|
||||
const sendMouse = (mouseState: any) => {
|
||||
const scale = display.getScale() || 1
|
||||
const scaled = new Guacamole.Mouse.State(
|
||||
mouseState.x / scale,
|
||||
mouseState.y / scale,
|
||||
mouseState.left,
|
||||
mouseState.middle,
|
||||
mouseState.right,
|
||||
mouseState.up,
|
||||
mouseState.down,
|
||||
)
|
||||
client.sendMouseState(scaled)
|
||||
}
|
||||
mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = sendMouse
|
||||
|
||||
// Keyboard is captured on the document but only forwarded while THIS session
|
||||
// is the active/visible one (otherwise a background session would steal keys).
|
||||
const keyboard = new Guacamole.Keyboard(document)
|
||||
keyboard.onkeydown = (keysym: number) => {
|
||||
if (activeSessionIdRef.current === sessionId) client.sendKeyEvent(1, keysym)
|
||||
}
|
||||
keyboard.onkeyup = (keysym: number) => {
|
||||
if (activeSessionIdRef.current === sessionId) client.sendKeyEvent(0, keysym)
|
||||
}
|
||||
|
||||
handlesRef.current.set(sessionId, { client, container, display, mouse, keyboard })
|
||||
|
||||
client.onerror = (err: { message?: string }) => {
|
||||
patchSession(sessionId, { status: 'error', errorMessage: err?.message ?? 'Connection failed' })
|
||||
|
|
@ -99,6 +138,8 @@ export default function RemoteDesktop() {
|
|||
|
||||
function closeSession(sessionId: string) {
|
||||
const handle = handlesRef.current.get(sessionId)
|
||||
handle?.keyboard?.onkeydown && (handle.keyboard.onkeydown = null)
|
||||
handle?.keyboard?.onkeyup && (handle.keyboard.onkeyup = null)
|
||||
handle?.client.disconnect()
|
||||
handle?.container.remove()
|
||||
handlesRef.current.delete(sessionId)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue