From 54c337d86574089d0e92d1be83e0f6f1c77c3963 Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Thu, 8 May 2025 00:57:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E8=B0=83=E6=95=B4rdp/vnc=E7=AA=97=E5=8F=A3=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/RemoteDesktopModal.vue | 75 ++++++++++++++++++- packages/frontend/src/components/VncModal.vue | 59 ++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/components/RemoteDesktopModal.vue b/packages/frontend/src/components/RemoteDesktopModal.vue index b1d4773..0cbf763 100644 --- a/packages/frontend/src/components/RemoteDesktopModal.vue +++ b/packages/frontend/src/components/RemoteDesktopModal.vue @@ -25,6 +25,11 @@ const rdpDisplayRef = ref(null); const rdpContainerRef = ref(null); const guacClient = ref(null); const connectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected'); +const isResizing = ref(false); +const resizeStartX = ref(0); +const resizeStartY = ref(0); +const initialModalWidthForResize = ref(0); // Renamed to avoid conflict if other 'initialModalWidth' exists +const initialModalHeightForResize = ref(0); // Renamed const statusMessage = ref(''); const keyboard = ref(null); const mouse = ref(null); @@ -502,6 +507,11 @@ onUnmounted(() => { disconnectGuacamole(); // 这里已经调用了 removeInputListeners document.removeEventListener('mousemove', onRestoreButtonMouseMove); document.removeEventListener('mouseup', onRestoreButtonMouseUp); + // Clean up resize listeners if component is unmounted while resizing + if (isResizing.value) { + document.removeEventListener('mousemove', doResize); + document.removeEventListener('mouseup', stopResize); + } }); watch(() => props.connection, (newConnection, oldConnection) => { @@ -529,6 +539,59 @@ const computedModalStyle = computed(() => { }; }); +// Watch for modal size changes to update Guacamole client +watchEffect(() => { + const currentStyle = computedModalStyle.value; // Dependency + if (guacClient.value && connectionStatus.value === 'connected' && rdpContainerRef.value) { + nextTick(() => { + if (rdpContainerRef.value && guacClient.value) { + const displayWidth = rdpContainerRef.value.offsetWidth; + const displayHeight = rdpContainerRef.value.offsetHeight; + if (displayWidth > 0 && displayHeight > 0) { + // console.log(`[RDP Modal] Resizing Guacamole display to: ${displayWidth}x${displayHeight} due to style change.`); + guacClient.value.sendSize(displayWidth, displayHeight); + } + } + }); + } +}); + +const initResize = (event: MouseEvent) => { + isResizing.value = true; + resizeStartX.value = event.clientX; + resizeStartY.value = event.clientY; + initialModalWidthForResize.value = desiredModalWidth.value; + initialModalHeightForResize.value = desiredModalHeight.value; + + document.addEventListener('mousemove', doResize); + document.addEventListener('mouseup', stopResize); + event.preventDefault(); +}; + +const doResize = (event: MouseEvent) => { + if (!isResizing.value) return; + + const deltaX = event.clientX - resizeStartX.value; + const deltaY = event.clientY - resizeStartY.value; + + let newWidth = initialModalWidthForResize.value + deltaX; + let newHeight = initialModalHeightForResize.value + deltaY; + + newWidth = Math.max(MIN_MODAL_WIDTH, newWidth); + newHeight = Math.max(MIN_MODAL_HEIGHT, newHeight); + + desiredModalWidth.value = newWidth; + desiredModalHeight.value = newHeight; +}; + +const stopResize = () => { + if (!isResizing.value) return; + isResizing.value = false; + document.removeEventListener('mousemove', doResize); + document.removeEventListener('mouseup', stopResize); + // Guacamole size update is handled by the watchEffect above +}; +