Repository navigation
Sync the clipboard on Ctrl+C / Ctrl+X / Ctrl+V in the web viewer (patch attached) #172
Description
Summary
In the web viewer, the clipboard can currently only be transferred with the Send Clipboard and Receive Clipboard buttons in the input popover. Keyboard shortcuts are forwarded as plain keys, so Ctrl+C copies to the remote clipboard and Ctrl+V pastes from it, but nothing ever reaches the viewer's own clipboard. Users coming from RDP expect copy and paste to just work.
I've implemented this and attached it as a patch (git am-ready), based on main at ece9542 (v0.28.2.0). I don't have a GitHub fork, so I'm sending it this way — feel free to take it as-is, change it, or use it only as a reference.
Behavior
Paste (Ctrl+V): the key-down is no longer prevented, so the browser raises a paste event carrying the local clipboard text. That text is sent to the remote device — but only if it changed since the last sync — and only then is the held key-down forwarded. Sending it unconditionally would overwrite text the user had just copied on the remote device with the mouse (context menu), and the paste would insert something else than expected. A "Clipboard sent" snackbar confirms the transfer after it succeeds.
Taking the text from the paste event rather than navigator.clipboard.readText() matters: readText() needs the clipboard-read permission and fails with NotAllowedError on every site where the user hasn't granted it, while the paste event needs no permission and never prompts.
Copy / cut (Ctrl+C, Ctrl+X): after the key is forwarded, the remote clipboard is requested following a short delay (300 ms), so the remote application has time to update it. The existing clipboard handler writes it locally and shows "Received clipboard text".
Both directions:
- record the same device access activities as the buttons (
send_clipboard_text/receive_clipboard_text), - respect view-only mode and the
CanReadClipboard/CanWriteClipboardpermissions, - ignore shortcuts combined with Alt or Meta (AltGr on many European layouts is Ctrl+Alt),
- show errors in a snackbar and never break key handling.
Settings
- New user preference
is-clipboard-shortcut-sync-enabled, enabled by default, with a checkbox on the Settings page. - A per-session switch in the input popover under "Clipboard", initialized from the preference — the same pattern as the keyboard input mode.
- Preferences are stored as name/value pairs, so no migration is needed.
ControlR.Web.Server_internal.jsonis regenerated by the build.
Key event ordering
Sending the clipboard before the Ctrl+V key-down is asynchronous. Key-down events were awaited but key-up events were not, so a key-up could reach the remote device before its key-down. Key events now go through a small promise queue in RemoteDisplay.razor.js. The Ctrl+V key-down is held until its paste event, or until its key-up if no paste event arrives.
Tests
- The logic lives in a new
ClipboardShortcutSyncservice with 20 new tests (27 cases) inControlR.Web.Client.Tests: copy shortcut detection, permissions, the per-session switch, unchanged/blank clipboard text, retry after a failed send, the copy delay (withFakeTimeProvider), cancellation, error handling and activity recording. Paste shortcut detection and the key queue live inRemoteDisplay.razor.js, which has no test harness, so they were verified manually. UserPreferencesManagerTestsupdated for the new preference.ControlR.Web.Client.Tests: 156 passed.ControlR.Web.Server.Tests: 903 passed.ControlR.Web.Serverbuilds with 0 warnings.
Manual testing: done on our own build of 0.27.6.0 with this change backported, in a Chromium-based browser, against a real remote device and without an RDP session to it (RDP syncs the clipboard on its own and would mask the result):
- Ctrl+C and Ctrl+X on the remote device put the text on the local clipboard.
- Ctrl+V pastes the local clipboard on the remote device, on a site where the clipboard-read permission was never granted.
- Text copied on the remote device with the mouse is still what Ctrl+V pastes there when the local clipboard hasn't changed.
- Typing, AltGr combinations and pasting into input fields on the ControlR page itself are unaffected.
- The per-session switch and the Settings default both work.
Known limitations
- The 300 ms copy delay is a heuristic. If a remote application updates its clipboard later, the previous text is received and the Receive Clipboard button still works as before. The viewer logs whether the received text changed, which helps tune this.
- Text only, same as the existing buttons.
- Web viewer only; the Avalonia viewer is untouched.
- Ctrl-based shortcuts only; Cmd on a macOS viewer isn't handled.
Applying the patch
Unzip the attachment and run:
git am 0001-*.patch
Contributor License Agreement
I have read and agree to the Contribution License Agreement in .github/pull_request_template.md, and it applies to this submission.
The change was written with the help of Claude Code (Anthropic), noted in the commit trailer.
Activity
mattish91 commentedon Sep 13, 2026
I want to remember that there is some sense behind the permissions that was originally set with reading clipboards, and if im correct there was something with SmartScreen in Windows Defender.
Correct me if im wrong, but i have seen that SmartScreen (red background) blocking pages for reading clipboard "without explicit" permission.
Hopefully it's nothing that this will be touched by? (I love the feature of "Type clipboard" and i get a small "Paste" popup 😂)
Opicka879 commentedon Sep 13, 2026
Thanks for looking at it! Type Clipboard isn't touched – the patch doesn't change interop.js or any readText/writeText call.
The "Paste" popup you get is how Firefox and Safari handle navigator.clipboard.readText(); Chrome and Edge show a clipboard permission prompt instead, and a site can be blocked there. I couldn't find SmartScreen blocking clipboard reads itself – could that have been the Edge prompt or its block list?
The shortcut sync doesn't use readText at all:
Both respect the device access clipboard permissions (CanReadClipboard / CanWriteClipboard) and can be turned off per session in the Input popover or by default in Settings.
I've only tested it in Chromium-based browsers. Firefox and Safari may be stricter about the delayed clipboard write after Ctrl+C, the same as with the Receive Clipboard button.
bitbound commentedon Sep 16, 2026
Thanks for your submission. 🙂 Some thoughts:
The current design was chosen for a couple reasons.
The first, the one that @mattish91 is probably thinking of, is due to Firefox and Safari's requirement for "transient user activation". I think some Chromium-based browsers also require this. Basically, a user must interact with the page via input event (e.g. mouse click, key press) shortly before the request to the clipboard APIs. Otherwise, the request fails. For more info, see: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API#security_considerations.
The other concern is from a security perspective. Since ControlR is primarily for support scenarios, where you're remoting into another user's machine, we can't assume that the remote environment is secure and uncompromised. I wouldn't want there to be any chance of accidentally transferring sensitive data. This is why I wouldn't have chosen Remotely's background sync design, even if it were still possible.
The proposed design satisfies the first concern, but not fully the second.
Personally, I'd prefer to keep it how it is for now, and maybe later implement it with customizable shortcut keys. But I'll run it by my sponsors to see if they have any strong opinions/requests.
Regarding the patch. I'm still not accepting PRs for the reasons mentioned in https://github.com/bitbound/ControlR/blob/main/.github/workflows/auto-close-external-prs.yml. I need to get a legally-binding CLA in place first. Then I need to find some people I trust who'd be willing to help with code reviews. Otherwise, accepting external PRs would only slow down velocity.
Also, any changes to remote control right now would be incompatible with the changes I need to do next after Permissions V2 is shipped.
I'll update when there's been a decision.
Opicka879 commentedon Sep 16, 2026
Thanks for the detailed reasoning – that all makes sense, and I appreciate you taking the time to look at it.
No pressure from my side on the decision. I'll keep it in my own build in the meantime, so I'm happy to wait for Permissions V2 and whatever comes after it before this is revisited. Customizable shortcut keys sound like a good direction if you do pick it up later.
Understood about external PRs and the CLA as well – feel free to use the patch as a reference or ignore it entirely, whichever helps.
Thanks again for ControlR, it's been working well for me.