Copy and paste clipboard types other than text #23

Closed
opened 2026-10-15 22:01:52 -05:00 by jeff · 1 comment
Owner

Map for copying and pasting Clipboard types other than text, through kitty's clipboard protocol (OSC 5522), on Wayland.

Tickets

  • #24 Answer a clipboard read with any clipboard types and listing
  • #25 Remember the clipboard's types, and list them without reading it (blocked by #24)
  • #26 Read any clipboard type for a program, off the window thread (blocked by #24, #25)
  • #27 Write every clipboard type a program gives, each served its own bytes
  • #28 Name clipboard types and sizes in the confirmation (blocked by #26, #27)

Outside this map: #29 Windows, #30 image previews in the confirmation, #31 a write that asks first being answered "done" too early.

Decisions so far

  • Any type, opaquely. harrier passes through whatever MIME type the clipboard offers or the program writes. There is no list of known types.
  • Wayland only here. win32 stays text-only until #29.
  • One setting. clipboard.read / clipboard.write (and a profile's) cover every type alike. A screenshot is as private as a password.
  • Primary selection stays text.
  • Reads and serving writes never wait on the window thread. The window thread starts a transfer; its pipes join the main loop's poll and move a bounded chunk a turn, as drag and drop's do (Dnd.handles/pump), in their own ClipboardTransfers. A transfer whose pane has gone simply stops. (Changed from a worker thread, which would have held a Session that can be destroyed under it.) Keyboard paste keeps its synchronous text read.
  • Several types in one read are asked for together, each on its own pipe, read as each is ready; the answer goes when the last finishes.
  • A source silent for 3 s loses that type from the answer, logged, and what came of it is discarded.
  • 64 MiB per type, both ways. Over that, a read leaves the type out of its answer (kitty's protocol has no per-type error) and logs it; never truncated data.
  • The listing comes from the advertised types. It doesn't read the contents and is still answered without a Confirmation. Names that aren't MIME types (UTF8_STRING, TEXT, STRING, TARGETS) are left out. A paste event's listing is the same.
  • A write offers exactly the types written, plus the text aliases when text is among them.
  • The Confirmation names types and sizes. A read names the types asked for, because nothing is read before the answer. Previews are #30.
  • No Ghostty fork change is needed for reads: its read result already takes (type, bytes) pairs and a caller-supplied listing. Any later fork change goes on zig-0.17-jeff.
  • Glossary: Clipboard type (c783bc5).
  • #28 done (04ca104): the confirmation names types and sizes when anything isn't text.
  • #27 done (9a9ae8b): writes keep every type; the platform's reference-counted Offered holds them, and ClipboardTransfers serves each request without blocking.
  • #26 done (3a587f1): ClipboardTransfers reads every type at once over non-blocking pipes in the main loop; #27 serves writes from the same place.
  • #25 done (0a4b0ba): the platform has clipboardTypes; listings and paste events come from it and read nothing.
  • #24 done (59714c2): ClipboardAnswer carries (type, bytes) pairs and the listing; a text type is served from text read under any name.

Fog

  • None.

Notes

The original description:

Copying and pasting go through the clipboard as text only. Programs can now ask for more with kitty's clipboard protocol (OSC 5522), but harrier still hands over text alone.

Reading (#18). An OSC 5522 read or paste event is answered with text, under each text type the program asked for. The targets listing reports only text/plain. A program asking for image/png, text/html or anything else gets no data for it, which the protocol reads as "not available", even when the clipboard has it.

Writing. An OSC 5522 write commits every type it was given, but Session.clipboardWrite keeps only the first text type and drops the rest. So kitten clipboard copying an image puts nothing on the clipboard.

What it would take:

  • The platform layer. The Wayland Platform remembers only whether an offer has_text, and readClipboard asks for text_mime alone. It would need to record every MIME type an offer advertises, and read any one of them. Writing would need a data source offering several types, each served its own bytes. The win32 platform needs the same, through clipboard formats, or a decision to stay text-only there.
  • Size. Reads cap at 64 MiB today. An image is larger than any paste, and the read happens on the window thread, so it may want to move off it.
  • The confirmation. It would need to say what is being read or written when it isn't text. Ghostty's gtk-kitty-clipboard branch previews images in its dialog (ba50c6387, d6a4294f6), which is prior art.
  • The settings. Decide whether clipboard.read / clipboard.write cover every type alike, or whether non-text should be asked about separately.
  • Pasting from the keyboard. A paste event's listing would report every available type, not just text/plain, so a program can choose.
Map for copying and pasting Clipboard types other than text, through kitty's clipboard protocol (OSC 5522), on Wayland. ## Tickets - [x] #24 Answer a clipboard read with any clipboard types and listing - [x] #25 Remember the clipboard's types, and list them without reading it (blocked by #24) - [x] #26 Read any clipboard type for a program, off the window thread (blocked by #24, #25) - [x] #27 Write every clipboard type a program gives, each served its own bytes - [x] #28 Name clipboard types and sizes in the confirmation (blocked by #26, #27) Outside this map: #29 Windows, #30 image previews in the confirmation, #31 a write that asks first being answered "done" too early. ## Decisions so far - **Any type, opaquely.** harrier passes through whatever MIME type the clipboard offers or the program writes. There is no list of known types. - **Wayland only here.** win32 stays text-only until #29. - **One setting.** `clipboard.read` / `clipboard.write` (and a profile's) cover every type alike. A screenshot is as private as a password. - **Primary selection stays text.** - **Reads and serving writes never wait on the window thread.** The window thread starts a transfer; its pipes join the main loop's poll and move a bounded chunk a turn, as drag and drop's do (`Dnd.handles`/`pump`), in their own `ClipboardTransfers`. A transfer whose pane has gone simply stops. (Changed from a worker thread, which would have held a `Session` that can be destroyed under it.) Keyboard paste keeps its synchronous text read. - **Several types in one read are asked for together**, each on its own pipe, read as each is ready; the answer goes when the last finishes. - **A source silent for 3 s** loses that type from the answer, logged, and what came of it is discarded. - **64 MiB per type, both ways.** Over that, a read leaves the type out of its answer (kitty's protocol has no per-type error) and logs it; never truncated data. - **The listing comes from the advertised types.** It doesn't read the contents and is still answered without a Confirmation. Names that aren't MIME types (`UTF8_STRING`, `TEXT`, `STRING`, `TARGETS`) are left out. A paste event's listing is the same. - **A write offers exactly the types written**, plus the text aliases when text is among them. - **The Confirmation names types and sizes.** A read names the types asked for, because nothing is read before the answer. Previews are #30. - **No Ghostty fork change is needed for reads**: its read result already takes (type, bytes) pairs and a caller-supplied listing. Any later fork change goes on `zig-0.17-jeff`. - **Glossary:** **Clipboard type** (c783bc5). - **#28 done (04ca104):** the confirmation names types and sizes when anything isn't text. - **#27 done (9a9ae8b):** writes keep every type; the platform's reference-counted `Offered` holds them, and `ClipboardTransfers` serves each request without blocking. - **#26 done (3a587f1):** `ClipboardTransfers` reads every type at once over non-blocking pipes in the main loop; #27 serves writes from the same place. - **#25 done (0a4b0ba):** the platform has `clipboardTypes`; listings and paste events come from it and read nothing. - **#24 done (59714c2):** `ClipboardAnswer` carries (type, bytes) pairs and the listing; a text type is served from text read under any name. ## Fog - None. ## Notes The original description: > Copying and pasting go through the clipboard as text only. Programs can now ask for more with kitty's clipboard protocol (OSC 5522), but harrier still hands over text alone. > > **Reading** (#18). An OSC 5522 read or paste event is answered with text, under each text type the program asked for. The targets listing reports only `text/plain`. A program asking for `image/png`, `text/html` or anything else gets no data for it, which the protocol reads as "not available", even when the clipboard has it. > > **Writing.** An OSC 5522 write commits every type it was given, but `Session.clipboardWrite` keeps only the first text type and drops the rest. So `kitten clipboard` copying an image puts nothing on the clipboard. > > What it would take: > > - **The platform layer.** The Wayland `Platform` remembers only whether an offer `has_text`, and `readClipboard` asks for `text_mime` alone. It would need to record every MIME type an offer advertises, and read any one of them. Writing would need a data source offering several types, each served its own bytes. The win32 platform needs the same, through clipboard formats, or a decision to stay text-only there. > - **Size.** Reads cap at 64 MiB today. An image is larger than any paste, and the read happens on the window thread, so it may want to move off it. > - **The confirmation.** It would need to say what is being read or written when it isn't text. Ghostty's `gtk-kitty-clipboard` branch previews images in its dialog (ba50c6387, d6a4294f6), which is prior art. > - **The settings.** Decide whether `clipboard.read` / `clipboard.write` cover every type alike, or whether non-text should be asked about separately. > - **Pasting from the keyboard.** A paste event's listing would report every available type, not just `text/plain`, so a program can choose. >
Author
Owner

Every ticket on the map is done: #24, #25, #26, #27 and #28. On Wayland, programs can now copy and paste any clipboard type through kitty's clipboard protocol. Still open outside the map: #29 (Windows), #30 (image previews in the confirmation) and #31 (a write that asks first is answered "done" too early).

Every ticket on the map is done: #24, #25, #26, #27 and #28. On Wayland, programs can now copy and paste any clipboard type through kitty's clipboard protocol. Still open outside the map: #29 (Windows), #30 (image previews in the confirmation) and #31 (a write that asks first is answered "done" too early).
jeff closed this issue 2026-10-16 17:22:00 -05:00
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.

Dependencies

No dependencies set

Reference
jeff/harrier#23
No description provided.