mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-12 04:09:40 +00:00
terminal: make clipboard writes protocol neutral
#13182 Replace the OSC 52-specific kind and encoded payload callback with an atomic clipboard write containing a normalized destination and decoded MIME representations. This keeps protocol details out of embedders and lets iTerm2 Copy use the same semantic path. Represent clears with an empty content list, preserve binary payloads, and return a generic result for protocols that acknowledge writes. Add the C ABI descriptors, layout metadata, and effects example so future multipart protocols can reuse the callback without another API break.
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
# Example: `ghostty-vt` Terminal Effects
|
||||
|
||||
This contains a simple example of how to register and use terminal
|
||||
effect callbacks (`write_pty`, `bell`, `title_changed`) with the
|
||||
effect callbacks (`write_pty`, `bell`, `title_changed`, and
|
||||
`clipboard_write`) with the
|
||||
`ghostty-vt` C library.
|
||||
|
||||
The clipboard effect receives one atomic write with decoded, binary-safe
|
||||
MIME representations rather than protocol-specific OSC 52 data.
|
||||
|
||||
This uses a `build.zig` and `Zig` to build the C program so that we
|
||||
can reuse a lot of our build logic and depend directly on our source
|
||||
tree, but Ghostty emits a standard C library that can be used with any
|
||||
|
||||
@@ -39,6 +39,37 @@ void on_title_changed(GhosttyTerminal terminal, void* userdata) {
|
||||
}
|
||||
//! [effects-title-changed]
|
||||
|
||||
//! [effects-clipboard-write]
|
||||
GhosttyClipboardWriteResult on_clipboard_write(
|
||||
GhosttyTerminal terminal,
|
||||
void* userdata,
|
||||
const GhosttyClipboardWrite* write) {
|
||||
(void)terminal;
|
||||
(void)userdata;
|
||||
|
||||
printf(" clipboard write (location=%d, contents=%zu)\n",
|
||||
(int)write->location, write->contents_len);
|
||||
if (write->contents_len == 0) {
|
||||
printf(" clear\n");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < write->contents_len; i++) {
|
||||
const GhosttyClipboardContent* content = &write->contents[i];
|
||||
printf(" ");
|
||||
if (content->mime.len > 0) {
|
||||
fwrite(content->mime.ptr, 1, content->mime.len, stdout);
|
||||
}
|
||||
printf(" (%zu bytes): ", content->data.len);
|
||||
if (content->data.len > 0) {
|
||||
fwrite(content->data.ptr, 1, content->data.len, stdout);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS;
|
||||
}
|
||||
//! [effects-clipboard-write]
|
||||
|
||||
//! [effects-register]
|
||||
int main() {
|
||||
// Create a terminal
|
||||
@@ -64,6 +95,8 @@ int main() {
|
||||
(const void *)on_bell);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_TITLE_CHANGED,
|
||||
(const void *)on_title_changed);
|
||||
ghostty_terminal_set(terminal, GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE,
|
||||
(const void *)on_clipboard_write);
|
||||
|
||||
// Feed VT data that triggers effects:
|
||||
|
||||
@@ -85,7 +118,14 @@ int main() {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)decrqm,
|
||||
strlen(decrqm));
|
||||
|
||||
// 4. Another bell to show the counter increments
|
||||
// 4. Clipboard write (OSC 52 ; c ; <base64 data> ST)
|
||||
printf("Sending clipboard write:\n");
|
||||
const char* clipboard_seq =
|
||||
"\x1B]52;c;SGVsbG8gY2xpcGJvYXJk\x1B\\";
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t*)clipboard_seq,
|
||||
strlen(clipboard_seq));
|
||||
|
||||
// 5. Another bell to show the counter increments
|
||||
printf("Sending another BEL:\n");
|
||||
ghostty_terminal_vt_write(terminal, &bel, 1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user