Read any clipboard type for a program, off the window thread #26

Closed
opened 2026-10-16 15:11:19 -05:00 by jeff · 1 comment
Owner

Part of #23

A program's read (OSC 52 or 5522) is answered by Window.answerRead. It calls platform.readClipboard, which is synchronous on the window thread, always asks for the text type, polls up to 3 s at a time, and silently truncates at 64 MiB. A request for image/png gets nothing even when the clipboard has one.

What done looks like

  • A read that answers a program can ask for any Clipboard type the clipboard offers.
  • The window thread only starts it: a pipe and offer.receive(type, fd) for each type asked for, all at once. The read ends join the main loop's poll and are read a bounded chunk a turn, without blocking, as Dnd reads a drop, in a ClipboardTransfers of their own. The deferred read is answered when the last type finishes. A large image from a slow source freezes no pane, and a read whose pane has gone simply stops.
  • A type whose source is silent for 3 s is left out of the answer and logged; what came of it is discarded.
  • Each type is read up to 64 MiB. A larger one is left out of the answer and logged; the other types are still served. kitty's protocol has no per-type error (an error replaces the whole reply's status=OK), and a type with no data is how it says "not available". Never truncated data.
  • When harrier owns the clipboard, its own bytes for each type are answered without a round trip.
  • Keyboard paste keeps its synchronous text read.
  • The stale doc comments on readClipboard (that it "dispatches while it reads", "a second at a time") are corrected or gone.
  • Tests: the sway VM test copies a PNG with wl-copy -t image/png, reads it with 5522, and compares the bytes.
Part of #23 A program's read (OSC 52 or 5522) is answered by `Window.answerRead`. It calls `platform.readClipboard`, which is synchronous on the window thread, always asks for the text type, polls up to 3 s at a time, and silently truncates at 64 MiB. A request for `image/png` gets nothing even when the clipboard has one. ## What done looks like - A read that answers a program can ask for any Clipboard type the clipboard offers. - The window thread only starts it: a pipe and `offer.receive(type, fd)` for each type asked for, all at once. The read ends join the main loop's poll and are read a bounded chunk a turn, without blocking, as `Dnd` reads a drop, in a `ClipboardTransfers` of their own. The deferred read is answered when the last type finishes. A large image from a slow source freezes no pane, and a read whose pane has gone simply stops. - A type whose source is silent for 3 s is left out of the answer and logged; what came of it is discarded. - Each type is read up to 64 MiB. A larger one is left out of the answer and logged; the other types are still served. kitty's protocol has no per-type error (an error replaces the whole reply's `status=OK`), and a type with no data is how it says "not available". Never truncated data. - When harrier owns the clipboard, its own bytes for each type are answered without a round trip. - Keyboard paste keeps its synchronous text read. - The stale doc comments on `readClipboard` (that it "dispatches while it reads", "a second at a time") are corrected or gone. - Tests: the sway VM test copies a PNG with `wl-copy -t image/png`, reads it with 5522, and compares the bytes.
jeff self-assigned this 2026-10-16 15:46:27 -05:00
jeff closed this issue 2026-10-16 16:30:19 -05:00
Author
Owner

Done in 3a587f1. The new src/ClipboardTransfers.zig asks for every requested type at once over non-blocking pipes in the main loop's poll, reading up to 1 MiB of each type per turn. The sway VM test copies 1 MiB with wl-copy -t image/png, reads image/png text/plain, and gets the image back byte for byte, in 256 packets, with no text. Found along the way: receiveClipboard must flush before closing the pipe's write end, because the flush is what sends the fd.

Done in 3a587f1. The new `src/ClipboardTransfers.zig` asks for every requested type at once over non-blocking pipes in the main loop's poll, reading up to 1 MiB of each type per turn. The sway VM test copies 1 MiB with `wl-copy -t image/png`, reads `image/png text/plain`, and gets the image back byte for byte, in 256 packets, with no text. Found along the way: `receiveClipboard` must flush before closing the pipe's write end, because the flush is what sends the fd.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
jeff/harrier#26
No description provided.