From 4ef743fc9016b51355a6a8709223494ff4c639ec Mon Sep 17 00:00:00 2001 From: rangoDJ <18576423+rangoDJ@users.noreply.github.com> Date: Thu, 1 Oct 2026 22:28:50 -0400 Subject: [PATCH] Turn off FreeRDP's file clipboard Copying a file in Windows Explorer froze the RDP session. FreeRDP offers copied files to Linux apps only through a FUSE mount, and the container has no /dev/fuse (the session log shows "fuse: device /dev/fuse not found"), so the file clipboard can't work here; Selkies asking FreeRDP for the copied files stalled its window. Start FreeRDP with /clipboard:files-to:off: text and images still sync, and files move through the shared folder. Co-Authored-By: Claude Opus 5.5 --- README.md | 4 +++- root/app/backend/session_manager.py | 5 ++++- tests/test_session_manager.py | 9 ++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 16bfa30..6b89a4d 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ flowchart TD end subgraph FreeRDPClient["FreeRDP 3 (xfreerdp)"] - RDPProcess["xfreerdp /v:host /sound /clipboard /drive:SharedFolder,/shared"] + RDPProcess["xfreerdp /v:host /sound /clipboard:files-to:off /drive:SharedFolder,/shared"] end end @@ -258,6 +258,8 @@ Over plain HTTP (port 8080) a paste still sends the image, but the keystroke can Images reach Windows as bitmaps: Ubuntu's FreeRDP build can't convert PNG itself, so the gateway adds a BMP copy of every pasted image. Transparent areas become white. +Files can't be copied through the clipboard: a browser has no way to put a file on your local clipboard, so FreeRDP's file clipboard is turned off. Move files through the shared folder instead (`\\tsclient\SharedFolder` in Windows, **Shared Files** in the WebUI; see [How File Sharing Works](#how-file-sharing-works)). + --- ## Windows Machine Setup diff --git a/root/app/backend/session_manager.py b/root/app/backend/session_manager.py index 7841b88..cb061cc 100644 --- a/root/app/backend/session_manager.py +++ b/root/app/backend/session_manager.py @@ -177,7 +177,10 @@ def _build_rdp(self, config: Dict[str, Any]) -> Launch: # Bidirectional Clipboard Synchronization if config.get("enable_clipboard", True): - args.append("+clipboard") + # Text and images only. FreeRDP can hand copied files to Linux apps only + # through a FUSE mount, and the container has no /dev/fuse; with files on, + # copying a file in Windows Explorer froze the session. + args.append("/clipboard:files-to:off") if clipboard_debug_enabled(): args.append(f"/log-filters:{CLIPBOARD_LOG_FILTERS}") diff --git a/tests/test_session_manager.py b/tests/test_session_manager.py index 7ccbfb3..3f040e8 100644 --- a/tests/test_session_manager.py +++ b/tests/test_session_manager.py @@ -58,11 +58,18 @@ def test_rdp_target_and_optional_flags(mgr): args = launch.stdin_text assert "/v:pc.local:3390" in args assert "/sound" not in args - assert "+clipboard" not in args + assert "clipboard" not in args assert "/drive" not in args assert "/cert:ignore" not in args +def test_rdp_clipboard_leaves_files_out(mgr): + """Copied files need a FUSE mount the container lacks; offering them froze the session.""" + args = mgr._build_rdp({"host": "pc.local", "port": 3389}).stdin_text.splitlines() + assert "/clipboard:files-to:off" in args + assert "+clipboard" not in args + + def test_rdp_resolution_modes(mgr): dynamic = mgr._build_rdp({"host": "h", "port": 1, "resolution": "dynamic"}) assert "/dynamic-resolution" in dynamic.stdin_text