libghostty: implement Kitty clipboard protocol write only

This implements only the clipboard _write_ side of the Kitty clipboard
protocol for libghostty-vt. libghostty users don't need to do anything,
this all automatically works since it just piggy-backs on the previous
clipboard write effect.

Clipboard reading is far more complicated because we don't have anything
designed yet for libghostty-vt that does async requests (e.g. to ask the
user for permission). I need to think about that more.
This commit is contained in:
Mitchell Hashimoto
2026-08-21 14:41:07 -07:00
parent 36676c5728
commit 6959fd46c6
4 changed files with 812 additions and 25 deletions

View File

@@ -95,8 +95,8 @@ extern "C" {
* | `GHOSTTY_TERMINAL_OPT_SIZE` | `GhosttyTerminalSizeFn` | XTWINOPS query (CSI 14/16/18 t) or mode 2048 enable |
* | `GHOSTTY_TERMINAL_OPT_COLOR_SCHEME` | `GhosttyTerminalColorSchemeFn` | Color scheme query (CSI ? 996 n) |
* | `GHOSTTY_TERMINAL_OPT_DEVICE_ATTRIBUTES`| `GhosttyTerminalDeviceAttributesFn`| Device attributes query (CSI c / > c / = c)|
* | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE` | `GhosttyTerminalClipboardWriteFn` | Clipboard write via OSC 52 / OSC 1337 |
* | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ` | `GhosttyTerminalClipboardReadFn` | Clipboard read via OSC 52 "?" |
* | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE` | `GhosttyTerminalClipboardWriteFn` | Clipboard write via OSC 52 / OSC 1337 / OSC 5522 |
* | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ` | `GhosttyTerminalClipboardReadFn` | Clipboard read via OSC 52 "?" / OSC 5522 |
* | `GHOSTTY_TERMINAL_OPT_DESKTOP_NOTIFICATION`| `GhosttyTerminalDesktopNotificationFn` | Desktop notification via OSC 9 / OSC 777 |
* | `GHOSTTY_TERMINAL_OPT_PROGRESS_REPORT` | `GhosttyTerminalProgressReportFn` | Progress report via OSC 9;4 |
* | `GHOSTTY_TERMINAL_OPT_UNKNOWN_SEQUENCE` | `GhosttyTerminalUnknownSequenceFn` | Unsupported sequence identifier |
@@ -494,7 +494,10 @@ typedef struct {
* Result of a clipboard write callback.
*
* Protocols without write acknowledgements, including OSC 52 and iTerm2
* OSC 1337 Copy, ignore this result.
* OSC 1337 Copy, ignore this result. The Kitty clipboard protocol
* (OSC 5522) acknowledges writes: each result maps to the corresponding
* protocol status (DONE, EPERM, ENOSYS, EBUSY, EINVAL, EIO) and is
* reported back to the running program through the write_pty callback.
*
* @ingroup terminal
*/
@@ -525,9 +528,18 @@ typedef enum GHOSTTY_ENUM_TYPED {
* Called synchronously for a complete logical clipboard write. Protocol
* details such as OSC 52 selectors, base64 encoding, multipart chunks,
* aliases, and terminators are normalized before this callback is invoked.
* OSC 52 and iTerm2 OSC 1337 Copy writes therefore use the same callback
* shape. OSC 52 clipboard read requests ("?") are delivered to
* GhosttyTerminalClipboardReadFn instead.
* OSC 52, iTerm2 OSC 1337 Copy, and Kitty clipboard (OSC 5522) writes
* therefore use the same callback shape.
*
* Every invocation is one complete write: the contents replace whatever
* the destination previously held, so there is never a partial update to
* detect or a reset to perform. A Kitty clipboard write transaction
* results in exactly one invocation, at commit, carrying all of the
* transaction's MIME representations together; its protocol response is
* generated automatically from the returned result.
*
* Clipboard read requests (OSC 52 "?" and OSC 5522 reads) are delivered
* to GhosttyTerminalClipboardReadFn instead.
*
* @param terminal The terminal handle
* @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA
@@ -1243,9 +1255,10 @@ typedef enum GHOSTTY_ENUM_TYPED {
/**
* Callback invoked when the running program performs a clipboard write.
* OSC 52 and iTerm2 OSC 1337 Copy writes are normalized to an atomic set
* of decoded MIME representations. Set to NULL to ignore clipboard writes.
* Clipboard read requests are delivered to
* OSC 52, iTerm2 OSC 1337 Copy, and Kitty clipboard (OSC 5522) writes
* are normalized to an atomic set of decoded MIME representations. Set
* to NULL to ignore clipboard writes (Kitty clipboard writes are then
* refused with ENOSYS). Clipboard read requests are delivered to
* GHOSTTY_TERMINAL_OPT_CLIPBOARD_READ instead.
*
* Input type: GhosttyTerminalClipboardWriteFn