foot/selection.h
Daniel Eklöf c366e322eb
osc: implement OSC-5522, kitty's extended version of OSC-52
OSC-5522[^1] gives the terminal application access to all offered
mime-types when reading the clipboard, and allows setting multiple
mime-types when writing to the clipboard (with different contents, if
it so wishes).

In addition to the base protocol, we also implement the _event
extension_[^2], where a paste action (e.g. ctrl+shift+v) results in an
unsolicited mime-type listing being sent to the terminal
application (as if it had issued a mime-type query itself), instead of
the clipboard content being pasted directly. The application follows
up with an explicit read request (or chooses to ignore the event).

The protocol supports "passwords", as a way of bypassing terminal
popups asking the user for approval, after the first popup has been
approved by the user. Foot doesn't implement this kind of user
approval, but all read and write requests are denied with EPERM if the
user has disabled OSC copy/pasting with the security.osc52
configuration option. In addition, if disabled, event reporting cannot
be enabled at all (i.e. 'CSI ? 5522 h' is ignored).

[^1]: https://sw.kovidgoyal.net/kitty/clipboard/
[^2]: https://rockorager.dev/misc/bracketed-paste-mime/
2026-05-22 11:58:54 +02:00

89 lines
3.4 KiB
C

#pragma once
#include <stdbool.h>
#include <wayland-client.h>
#include "terminal.h"
extern const struct wl_data_device_listener data_device_listener;
extern const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener;
void selection_start(
struct terminal *term, int col, int row,
enum selection_kind new_kind, bool spaces_only);
void selection_update(struct terminal *term, int col, int row);
void selection_finalize(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_dirty_cells(struct terminal *term);
void selection_cancel(struct terminal *term);
void selection_extend(
struct seat *seat, struct terminal *term,
int col, int row, enum selection_kind kind);
bool selection_on_rows(const struct terminal *term, int start, int end);
void selection_scroll_up(struct terminal *term, int rows);
void selection_scroll_down(struct terminal *term, int rows);
void selection_view_up(struct terminal *term, int new_view);
void selection_view_down(struct terminal *term, int new_view);
void selection_clipboard_unset(struct seat *seat);
void selection_primary_unset(struct seat *seat);
bool selection_clipboard_has_data(const struct seat *seat);
bool selection_primary_has_data(const struct seat *seat);
char *selection_to_text(const struct terminal *term);
void selection_to_clipboard(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_from_clipboard(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_to_primary(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_from_primary(struct seat *seat, struct terminal *term);
/* Copy text *to* primary/clipboard */
bool text_to_clipboard(
struct seat *seat, struct terminal *term, char *text,
struct kitty_clipboard_offer *kitty_data, uint32_t serial);
bool text_to_primary(
struct seat *seat, struct terminal *term, char *text,
struct kitty_clipboard_offer *kitty_data, uint32_t serial);
/*
* Copy text *from* primary/clipboard
*
* Note that these are asynchronous; they *will* return
* immediately. The 'cb' callback will be called 0..n times with
* clipboard data. When done (or on error), the 'done' callback is
* called.
*
* As such, keep this in mind:
* - The 'user' context must not be stack allocated
* - Don't expect clipboard data to have been received when these
* functions return (it will *never* have been received at this
* point).
*/
void text_from_clipboard(
struct seat *seat, struct terminal *term, bool no_strip,
void (*cb)(char *data, size_t size, void *user),
void (*done)(void *user), void *user, const char *custom_mime_type);
void text_from_primary(
struct seat *seat, struct terminal *term, bool no_strip,
void (*cb)(char *data, size_t size, void *user),
void (*dont)(void *user), void *user, const char *custom_mime_type);
void selection_start_scroll_timer(
struct terminal *term, int interval_ns,
enum selection_scroll_direction direction, int col);
void selection_stop_scroll_timer(struct terminal *term);
void selection_find_word_boundary_left(
const struct terminal *term, struct coord *pos, bool spaces_only);
void selection_find_word_boundary_right(
const struct terminal *term, struct coord *pos, bool spaces_only,
bool stop_on_space_to_word_boundary);
struct coord selection_get_start(const struct terminal *term);
struct coord selection_get_end(const struct terminal *term);