fix(rdp): proper display scaling via Guacamole display.scale()
Remove CSS width/height !important override that broke Guacamole's internal rendering pipeline. Replace with display.scale() auto-fitting using ResizeObserver for responsive container sizing. Scale mouse coordinates back to remote display space to keep input accurate. Clean up diagnostic instruction logging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f9070c81f3
commit
95271f065a
@ -56,12 +56,8 @@ onBeforeUnmount(() => {
|
||||
@apply absolute inset-0 bg-gray-950 overflow-hidden cursor-default;
|
||||
}
|
||||
|
||||
/* Guacamole appends a display div; make it fill the container */
|
||||
.rdp-canvas-container :deep(> div) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ function createJsonWsTunnel(wsUrl: string, connectMsg: object) {
|
||||
let onDisconnected: ((reason: string) => void) | null = null
|
||||
let onGatewayError: ((message: string) => void) | null = null
|
||||
|
||||
let instructionCount = 0
|
||||
function dispatchInstructions(raw: string) {
|
||||
if (!tunnel.oninstruction) return
|
||||
let remaining = raw
|
||||
@ -38,17 +37,6 @@ function createJsonWsTunnel(wsUrl: string, connectMsg: object) {
|
||||
pos = dotIdx + 1 + len + 1
|
||||
}
|
||||
if (parts.length > 0) {
|
||||
instructionCount++
|
||||
const opcode = parts[0]
|
||||
// Log first 50 instructions, then every 200th, plus any layer-0 draw ops
|
||||
const isLayer0Draw = (opcode === 'img' || opcode === 'rect' || opcode === 'cfill' || opcode === 'copy' || opcode === 'transfer')
|
||||
&& parts[1] !== undefined && parseInt(parts[1]) === 0
|
||||
if (instructionCount <= 50 || instructionCount % 200 === 0 || isLayer0Draw) {
|
||||
const argSummary = opcode === 'blob'
|
||||
? `[stream=${parts[1]}, ${(parts[2] || '').length} bytes]`
|
||||
: parts.slice(1).join(',')
|
||||
console.log(`[RDP] Instruction #${instructionCount}: ${opcode}(${argSummary})`)
|
||||
}
|
||||
tunnel.oninstruction(parts[0], parts.slice(1))
|
||||
}
|
||||
}
|
||||
@ -202,22 +190,48 @@ export function useRdp() {
|
||||
console.log(`[RDP] State: ${states[state] || state}`)
|
||||
}
|
||||
|
||||
// Log when display is ready
|
||||
client.onready = () => {
|
||||
const display = client.getDisplay()
|
||||
console.log(`[RDP] Ready! Display: ${display.getWidth()}x${display.getHeight()}, element: ${displayEl.offsetWidth}x${displayEl.offsetHeight}, container: ${container.offsetWidth}x${container.offsetHeight}`)
|
||||
}
|
||||
|
||||
// Attach Guacamole display element to container
|
||||
const displayEl = client.getDisplay().getElement()
|
||||
const display = client.getDisplay()
|
||||
const displayEl = display.getElement()
|
||||
container.appendChild(displayEl)
|
||||
|
||||
// Mouse input
|
||||
// Auto-scale the Guacamole display to fit the container
|
||||
function fitDisplay() {
|
||||
const dw = display.getWidth()
|
||||
const dh = display.getHeight()
|
||||
if (!dw || !dh) return
|
||||
const scale = Math.min(container.clientWidth / dw, container.clientHeight / dh)
|
||||
display.scale(scale)
|
||||
}
|
||||
|
||||
// Re-fit when guacd sends a sync (display dimensions may have changed)
|
||||
const origOnSync = display.onresize
|
||||
display.onresize = (w: number, h: number) => {
|
||||
origOnSync?.call(display, w, h)
|
||||
fitDisplay()
|
||||
}
|
||||
|
||||
// Re-fit when the browser container resizes
|
||||
const resizeObserver = new ResizeObserver(() => fitDisplay())
|
||||
resizeObserver.observe(container)
|
||||
|
||||
// Mouse input — bind to the display element
|
||||
const mouse = new Guacamole.Mouse(displayEl)
|
||||
mouse.onEach(
|
||||
['mousedown', 'mousemove', 'mouseup'],
|
||||
(e: Guacamole.Mouse.Event) => {
|
||||
client.sendMouseState(e.state)
|
||||
// Scale mouse coordinates back to remote display space
|
||||
const scale = display.getScale()
|
||||
const scaledState = new Guacamole.Mouse.State(
|
||||
e.state.x / scale,
|
||||
e.state.y / scale,
|
||||
e.state.left,
|
||||
e.state.middle,
|
||||
e.state.right,
|
||||
e.state.up,
|
||||
e.state.down,
|
||||
)
|
||||
client.sendMouseState(scaledState)
|
||||
},
|
||||
)
|
||||
|
||||
@ -230,6 +244,7 @@ export function useRdp() {
|
||||
client.connect()
|
||||
|
||||
function disconnect() {
|
||||
resizeObserver.disconnect()
|
||||
keyboard.onkeydown = null
|
||||
keyboard.onkeyup = null
|
||||
client.disconnect()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user