feat(rdp): text clipboard sharing in both directions

A CLIPRDR channel with a text-only backend (CF_UNICODETEXT): text copied
on the remote desktop is fetched and goes through the app's remote-
clipboard preference like VNC and OSC 52; local text is offered to the
remote when the desktop gains focus, on Ctrl+V and with Paste Clipboard
(which no longer types the text). Backend callbacks run inside the
active stage, so they queue requests that the session loop sends.

Verified against xrdp: the remote X clipboard read back the offered
text, and a remote copy arrived through on_clipboard.
This commit is contained in:
Andy Dixon
2026-10-12 17:47:22 +01:00
parent 4256d45633
commit 6476ccff28
9 changed files with 152 additions and 21 deletions
+3 -1
View File
@@ -241,7 +241,7 @@ impl Manager {
let cb = self.terminal_callbacks(id, epoch);
let (me, sid) = (self.clone(), id.to_string());
let (me2, sid2) = (self.clone(), id.to_string());
let clip: clients::vnc::ClipboardFn = Arc::new(move |text| me2.emit(Event::VncClipboard { session: sid2.clone(), text }));
let clip: clients::vnc::ClipboardFn = Arc::new(move |text| me2.emit(Event::DesktopClipboard { session: sid2.clone(), text }));
let c = connect_vnc_client(
&host,
port,
@@ -345,6 +345,7 @@ impl Manager {
let password = self.secret_fn(id, &p.id, SecretKind::RdpPassword, rc.secret_mode, prompt)()?;
let cb = self.terminal_callbacks(id, epoch);
let (me, sid) = (self.clone(), id.to_string());
let (me2, sid2) = (self.clone(), id.to_string());
let c = clients::rdp::Client::new(clients::rdp::Config {
host,
username: p.username.clone(),
@@ -357,6 +358,7 @@ impl Manager {
check_cert,
connect_timeout: timeout,
on_frame: Arc::new(move || me.emit(Event::DesktopFrame { session: sid.clone() })),
on_clipboard: Arc::new(move |text| me2.emit(Event::DesktopClipboard { session: sid2.clone(), text })),
on_error: cb.on_error,
on_close: cb.on_close,
});