diff --git a/frontend/components/rdp/RdpCanvas.vue b/frontend/components/rdp/RdpCanvas.vue index 4ba0cbc..4814c7e 100644 --- a/frontend/components/rdp/RdpCanvas.vue +++ b/frontend/components/rdp/RdpCanvas.vue @@ -12,7 +12,7 @@ const props = defineProps<{ const container = ref(null) const { connectRdp } = useRdp() -let rdpSession: ReturnType['connectRdp']> | null = null +let rdpSession: Awaited['connectRdp']>> | null = null // Expose to parent (RdpToolbar uses these) const sendClipboard = (text: string) => rdpSession?.sendClipboardText(text) @@ -20,10 +20,10 @@ const disconnect = () => rdpSession?.disconnect() defineExpose({ sendClipboard, disconnect }) -onMounted(() => { +onMounted(async () => { if (!container.value) return - rdpSession = connectRdp( + rdpSession = await connectRdp( container.value, props.hostId, props.hostName, diff --git a/frontend/composables/useRdp.ts b/frontend/composables/useRdp.ts index 5e3aaa5..5fcb300 100644 --- a/frontend/composables/useRdp.ts +++ b/frontend/composables/useRdp.ts @@ -237,10 +237,28 @@ export function useRdp() { }, ) - // Keyboard input + // Keyboard input — attached to document for global capture, but yield to + // form elements (inputs, textareas, selects, contenteditable) so modals, + // toolbars, and other UI overlays can receive keystrokes normally. const keyboard = new Guacamole.Keyboard(document) - keyboard.onkeydown = (keysym: number) => client.sendKeyEvent(1, keysym) - keyboard.onkeyup = (keysym: number) => client.sendKeyEvent(0, keysym) + + function isTypingInFormElement(): boolean { + const el = document.activeElement as HTMLElement | null + if (!el) return false + const tag = el.tagName + return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || el.isContentEditable + } + + keyboard.onkeydown = (keysym: number) => { + if (isTypingInFormElement()) return true // let browser handle it + client.sendKeyEvent(1, keysym) + return false + } + keyboard.onkeyup = (keysym: number) => { + if (isTypingInFormElement()) return true + client.sendKeyEvent(0, keysym) + return false + } // Initiate the WebSocket connection client.connect()