Skip to content

Fix two clipboard bugs: echoed rich copies, local Office copies sent as pictures - #35

Merged
rangoDJ merged 1 commit into
mainfrom
fix/clipboard-echo
Oct 2, 2026
Merged

rangoDJ merged 1 commit into
mainfrom
fix/clipboard-echo

Conversation

@rangoDJ

@rangoDJ rangoDJ commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Two clipboard bugs found while reviewing the copy/paste paths.

1. The browser hands the session's own copy back over it (server patches 4–5)

A copy with markup (Excel cells, Word/Outlook/web text) reaches the browser as HTML plus text. The client later reads its local clipboard back and sends it as a new copy — on every window focus in Chromium, and on Ctrl+V via our read-on-keydown patch. Its echo check fingerprints only the text it received, but the HTML+text bundle it sends, so they never match; the server has no echo check for incoming writes either.

Result: the browser's sanitized HTML replaced Windows' clipboard. Pasting in the remote Excel gave values instead of cells/formulas, and Excel's copy was cancelled.

Fix: write_clipboard skips an incoming copy whose plain text (CRLF and trailing whitespace normalized) matches what the session clipboard already holds. Images are always written (browsers re-encode them; the client has its own check).

2. Local Office copies reached the session as a picture (client patches 8–9)

Chromium exposes the picture Office adds beside copied cells/text as image/png, and both the clipboard read (rt) and the paste handler (te) took any image first — the client-side mirror of #34. A copy with non-blank text now goes as text/markup; picture-only copies still go as images.

Testing

  • pytest: 223 passed, 3 skipped. The stand-ins now carry Selkies' real rt(), te() and envelope helpers verbatim; new tests cover the echo (rich and plain), new local copies, images, brace-leading text, Office copies via read and paste, and picture-only copies. The new tests fail without the patches.
  • All patches applied to the input_handler.py and selkies-core.js from the deployed container: the server file compiles, the bundle parses (node --check).

🤖 Generated with Claude Code

A copy with markup (Excel cells, Word or web text) reaches the browser as
markup plus text. The client later reads its clipboard back (on window focus
in Chromium, and on Ctrl+V) and sends it as a new copy: it fingerprints the
text it received but the markup-and-text bundle it sends, so the two never
match, and the server wrote every incoming copy. The browser's sanitized
markup then replaced the copying app's own formats -- Excel pasted values
instead of cells and formulas -- and cancelled the copy in that app.

The server now skips an incoming copy whose plain text matches what the
session clipboard already holds. Images are always written.

Local Office copies also reached the session as a picture: Chromium exposes
the picture Office adds beside the text as image/png, and both the clipboard
read and the paste handler took any image first. A copy with real text now
goes as text; picture-only copies still go as images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rangoDJ
rangoDJ merged commit a32020b into main Oct 2, 2026
4 checks passed
@rangoDJ
rangoDJ deleted the fix/clipboard-echo branch October 2, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant