From 5a04a138c4f2de4fd98cf28226d1e7e23899fa5f Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Wed, 7 May 2025 23:28:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BArdp=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=8C=E6=AD=A5=E5=89=AA=E5=88=87=E6=9D=BF=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/RemoteDesktopModal.vue | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/frontend/src/components/RemoteDesktopModal.vue b/packages/frontend/src/components/RemoteDesktopModal.vue index e80b0a0..8c8b08a 100644 --- a/packages/frontend/src/components/RemoteDesktopModal.vue +++ b/packages/frontend/src/components/RemoteDesktopModal.vue @@ -213,6 +213,30 @@ const handleConnection = async () => { } }; +const trySyncClipboardOnDisplayFocus = async () => { + if (!guacClient.value) { + return; + } + try { + const currentClipboardText = await navigator.clipboard.readText(); + if (currentClipboardText && guacClient.value) { + // @ts-ignore + const stream = guacClient.value.createClipboardStream('text/plain'); + // @ts-ignore + const writer = new Guacamole.StringWriter(stream); + writer.sendText(currentClipboardText); + writer.sendEnd(); + console.log('[RemoteDesktopModal] Sent clipboard to RDP on display focus:', currentClipboardText.substring(0, 50) + (currentClipboardText.length > 50 ? '...' : '')); + } + } catch (err) { + if (err instanceof DOMException && err.name === 'NotAllowedError') { + // console.log('[RemoteDesktopModal] Clipboard read on display focus skipped: Document not focused or permission denied.'); + } else { + console.warn('[RemoteDesktopModal] Could not read clipboard on display focus, or other error:', err); + } + } +}; + const setupInputListeners = () => { if (!guacClient.value || !rdpDisplayRef.value) return; try { @@ -227,6 +251,10 @@ const setupInputListeners = () => { activeElement.blur(); console.log('[RDP Modal] Blurred input field on RDP display click.'); } + // Ensure the RDP display element gets focus when clicked + if (displayEl && typeof displayEl.focus === 'function') { + displayEl.focus(); + } }; displayEl.addEventListener('click', handleRdpDisplayClick); @@ -290,6 +318,9 @@ const setupInputListeners = () => { guacClient.value.sendKeyEvent(0, keysym); } }; + + // Listen for display focus to sync clipboard + displayEl.addEventListener('focus', trySyncClipboardOnDisplayFocus); } catch (inputError) { console.error("Error setting up input listeners:", inputError); // 添加错误日志 @@ -305,6 +336,7 @@ const removeInputListeners = () => { if (displayEl) { // 恢复默认光标样式 displayEl.style.cursor = 'default'; + displayEl.removeEventListener('focus', trySyncClipboardOnDisplayFocus); } } catch (e) { console.warn("Could not reset cursor or remove listeners on display element during listener removal:", e);