wraith/frontend/components/rdp/RdpCanvas.vue
Vantz Stockwell a75e21138e fix: RDP keyboard capture yields to form elements in modals and toolbars
Keyboard events now check if focus is on an input, textarea, select, or
contenteditable element and let the browser handle them normally. Also
fixes connectRdp type (Awaited<>) and async onMounted in RdpCanvas.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:49:30 -04:00

65 lines
1.5 KiB
Vue

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useRdp } from '~/composables/useRdp'
const props = defineProps<{
hostId: number
hostName: string
sessionId: string
color?: string | null
}>()
const container = ref<HTMLDivElement | null>(null)
const { connectRdp } = useRdp()
let rdpSession: Awaited<ReturnType<ReturnType<typeof useRdp>['connectRdp']>> | null = null
// Expose to parent (RdpToolbar uses these)
const sendClipboard = (text: string) => rdpSession?.sendClipboardText(text)
const disconnect = () => rdpSession?.disconnect()
defineExpose({ sendClipboard, disconnect })
onMounted(async () => {
if (!container.value) return
rdpSession = await connectRdp(
container.value,
props.hostId,
props.hostName,
props.color ?? null,
props.sessionId,
{
width: container.value.clientWidth,
height: container.value.clientHeight,
},
)
})
onBeforeUnmount(() => {
rdpSession?.disconnect()
rdpSession = null
})
</script>
<template>
<!-- Full-size container for the Guacamole display canvas.
The Guacamole client appends its own <canvas> element here. -->
<div
ref="container"
class="rdp-canvas-container"
/>
</template>
<style scoped>
.rdp-canvas-container {
@apply absolute inset-0 bg-gray-950 overflow-hidden cursor-default;
}
/* Guacamole manages its own display element sizing via display.scale().
Do NOT override width/height — it breaks the internal rendering pipeline. */
.rdp-canvas-container :deep(canvas) {
display: block;
}
</style>