From 8cd238d9aa563b909dd2e66ac808cea2aa1548b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=B8=80=E5=AF=B0?= Date: Sat, 14 Mar 2026 16:32:10 +0800 Subject: [PATCH] fix vnc bug --- ui/src/ui/app-render.ts | 2 + ui/src/ui/components/claw-computer-panel.ts | 47 +++++++++++++++++++-- ui/src/ui/storage.ts | 7 ++- ui/src/ui/views/overview.ts | 2 +- ui/vnc-proxy-plugin.ts | 32 +++++++++++--- 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts index 8336fd8561f..105804eaaef 100644 --- a/ui/src/ui/app-render.ts +++ b/ui/src/ui/app-render.ts @@ -1509,7 +1509,9 @@ export function renderApp(state: AppViewState) { " > state.toggleClawComputer()} style="flex: 1; min-height: 0;" diff --git a/ui/src/ui/components/claw-computer-panel.ts b/ui/src/ui/components/claw-computer-panel.ts index be19518dbe5..1c3a0f4e5fb 100644 --- a/ui/src/ui/components/claw-computer-panel.ts +++ b/ui/src/ui/components/claw-computer-panel.ts @@ -22,7 +22,8 @@ interface RFBInstance { @customElement("claw-computer-panel") export class ClawComputerPanel extends LitElement { - @property() vncUrl = "ws://localhost:8081"; + @property() vncUrl = ""; + @property() vncTarget = ""; @property() password = ""; @state() status = "η­‰εΎ…ι€£ζŽ₯..."; @@ -33,6 +34,20 @@ export class ClawComputerPanel extends LitElement { private screenRef: Ref = createRef(); private autoConnectAttempted = false; + @property({ type: Boolean }) enabled = false; + + updated(changedProperties: Map) { + if (changedProperties.has("enabled")) { + if (this.enabled) { + if (!this.isConnected) { + setTimeout(() => void this.connect(), 100); + } + } else { + this.disconnect(); + } + } + } + static styles = css` :host { display: block; @@ -179,7 +194,25 @@ export class ClawComputerPanel extends LitElement { }; private connect = async () => { - const url = this.vncUrl || "ws://localhost:8081"; + let url = + this.vncUrl || `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/vnc`; + + // Append target configuration if available + if (this.vncTarget) { + try { + const urlObj = new URL(url); + urlObj.searchParams.set("target", this.vncTarget); + url = urlObj.toString(); + } catch { + // Fallback for non-standard WebSocket URLs if URL parsing fails + if (url.includes("?")) { + url += `&target=${encodeURIComponent(this.vncTarget)}`; + } else { + url += `?target=${encodeURIComponent(this.vncTarget)}`; + } + } + } + if (this.rfb) { this.rfb.disconnect(); } @@ -213,6 +246,12 @@ export class ClawComputerPanel extends LitElement { clipViewport: true, }); + // @ts-ignore + this.rfb.addEventListener("securityfailure", (e: CustomEvent) => { + console.error("VNC security failure:", e.detail); + this.status = `Security negotiation failed: ${e.detail.reason || "Unknown reason"}`; + }); + if (this.rfb) { this.rfb.scaleViewport = this.isFitted; } @@ -271,8 +310,8 @@ export class ClawComputerPanel extends LitElement { firstUpdated() { window.addEventListener("resize", this.handleResize); - // Auto-connect if URL is configured - if (this.vncUrl) { + // Auto-connect if enabled and URL is configured + if (this.enabled && this.vncUrl) { // Use setTimeout to ensure DOM is fully ready and to allow UI to render first setTimeout(() => { void this.connect(); diff --git a/ui/src/ui/storage.ts b/ui/src/ui/storage.ts index 8da8fe27c60..6914e026cc1 100644 --- a/ui/src/ui/storage.ts +++ b/ui/src/ui/storage.ts @@ -138,8 +138,11 @@ export function loadSettings(): UiSettings { navCollapsed: false, navWidth: 220, navGroupsCollapsed: {}, - vncWsUrl: "ws://localhost:8081", - vncTarget: "10.75.171.25900", + vncWsUrl: + typeof location !== "undefined" + ? `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/vnc` + : "ws://localhost:18789/vnc", + vncTarget: "localhost:5900", }; try { diff --git a/ui/src/ui/views/overview.ts b/ui/src/ui/views/overview.ts index 2b26181c034..d3829731ca2 100644 --- a/ui/src/ui/views/overview.ts +++ b/ui/src/ui/views/overview.ts @@ -347,7 +347,7 @@ export function renderOverview(props: OverviewProps) { const v = (e.target as HTMLInputElement).value; props.onSettingsChange({ ...props.settings, vncTarget: v }); }} - placeholder="10.75.171.25900" + placeholder="localhost:5900" />