Make OSC 52 work in popups, from gogongxt at 163 dot com in GitHub issue

4797.
This commit is contained in:
nicm
2026-02-03 09:07:44 +00:00
parent 588013bb44
commit 62944da74b
5 changed files with 62 additions and 35 deletions

73
input.c
View File

@@ -101,6 +101,7 @@ struct input_ctx {
struct bufferevent *event; struct bufferevent *event;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
struct colour_palette *palette; struct colour_palette *palette;
struct client *c;
struct input_cell cell; struct input_cell cell;
struct input_cell old_cell; struct input_cell old_cell;
@@ -854,7 +855,7 @@ input_restore_state(struct input_ctx *ictx)
/* Initialise input parser. */ /* Initialise input parser. */
struct input_ctx * struct input_ctx *
input_init(struct window_pane *wp, struct bufferevent *bev, input_init(struct window_pane *wp, struct bufferevent *bev,
struct colour_palette *palette) struct colour_palette *palette, struct client *c)
{ {
struct input_ctx *ictx; struct input_ctx *ictx;
@@ -862,6 +863,7 @@ input_init(struct window_pane *wp, struct bufferevent *bev,
ictx->wp = wp; ictx->wp = wp;
ictx->event = bev; ictx->event = bev;
ictx->palette = palette; ictx->palette = palette;
ictx->c = c;
ictx->input_space = INPUT_BUF_START; ictx->input_space = INPUT_BUF_START;
ictx->input_buf = xmalloc(INPUT_BUF_START); ictx->input_buf = xmalloc(INPUT_BUF_START);
@@ -3073,31 +3075,28 @@ input_osc_52_reply(struct input_ctx *ictx)
input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end); input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end);
} }
/* Handle the OSC 52 sequence for setting the clipboard. */ /*
static void * Parse and decode OSC 52 clipboard data. Returns 0 on failure or if handled
input_osc_52(struct input_ctx *ictx, const char *p) * as a query. On success, returns 1 and sets *out, *outlen, and *flags (caller
* must free *out).
*/
static int
input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
int *outlen, char *flags)
{ {
struct window_pane *wp = ictx->wp;
size_t len;
char *end; char *end;
u_char *out; size_t len;
int outlen, state; const char *allow = "cpqs01234567";
struct screen_write_ctx ctx;
const char* allow = "cpqs01234567";
char flags[sizeof "cpqs01234567"] = "";
u_int i, j = 0; u_int i, j = 0;
if (wp == NULL) if (options_get_number(global_options, "set-clipboard") != 2)
return; return (0);
state = options_get_number(global_options, "set-clipboard");
if (state != 2)
return;
if ((end = strchr(p, ';')) == NULL) if ((end = strchr(p, ';')) == NULL)
return; return (0);
end++; end++;
if (*end == '\0') if (*end == '\0')
return; return (0);
log_debug("%s: %s", __func__, end); log_debug("%s: %s", __func__, end);
for (i = 0; p + i != end; i++) { for (i = 0; p + i != end; i++) {
@@ -3108,25 +3107,53 @@ input_osc_52(struct input_ctx *ictx, const char *p)
if (strcmp(end, "?") == 0) { if (strcmp(end, "?") == 0) {
input_osc_52_reply(ictx); input_osc_52_reply(ictx);
return; return (0);
} }
len = (strlen(end) / 4) * 3; len = (strlen(end) / 4) * 3;
if (len == 0) if (len == 0)
return (0);
*out = xmalloc(len);
if ((*outlen = b64_pton(end, *out, len)) == -1) {
free(*out);
*out = NULL;
return (0);
}
return (1);
}
/* Handle the OSC 52 sequence for setting the clipboard. */
static void
input_osc_52(struct input_ctx *ictx, const char *p)
{
struct window_pane *wp = ictx->wp;
struct screen_write_ctx ctx;
u_char *out;
int outlen;
char flags[sizeof "cpqs01234567"] = "";
if (!input_osc_52_parse(ictx, p, &out, &outlen, flags))
return; return;
out = xmalloc(len); if (wp == NULL) {
if ((outlen = b64_pton(end, out, len)) == -1) { /* Popup window. */
if (ictx->c == NULL) {
free(out); free(out);
return; return;
} }
tty_set_selection(&ictx->c->tty, flags, out, outlen);
paste_add(NULL, out, outlen);
} else {
/* Normal window. */
screen_write_start_pane(&ctx, wp, NULL); screen_write_start_pane(&ctx, wp, NULL);
screen_write_setselection(&ctx, flags, out, outlen); screen_write_setselection(&ctx, flags, out, outlen);
screen_write_stop(&ctx); screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp); notify_pane("pane-set-clipboard", wp);
paste_add(NULL, out, outlen); paste_add(NULL, out, outlen);
}
free(out);
} }
/* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */ /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */

View File

@@ -851,7 +851,7 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
pd->job = job_run(shellcmd, argc, argv, env, s, cwd, pd->job = job_run(shellcmd, argc, argv, env, s, cwd,
popup_job_update_cb, popup_job_complete_cb, NULL, pd, popup_job_update_cb, popup_job_complete_cb, NULL, pd,
JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy); JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy);
pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette); pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette, c);
server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb,
popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd); popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd);

2
tmux.h
View File

@@ -3011,7 +3011,7 @@ void recalculate_sizes_now(int);
/* input.c */ /* input.c */
#define INPUT_BUF_DEFAULT_SIZE 1048576 #define INPUT_BUF_DEFAULT_SIZE 1048576
struct input_ctx *input_init(struct window_pane *, struct bufferevent *, struct input_ctx *input_init(struct window_pane *, struct bufferevent *,
struct colour_palette *); struct colour_palette *, struct client *);
void input_free(struct input_ctx *); void input_free(struct input_ctx *);
void input_reset(struct input_ctx *, int); void input_reset(struct input_ctx *, int);
struct evbuffer *input_pending(struct input_ctx *); struct evbuffer *input_pending(struct input_ctx *);

View File

@@ -494,7 +494,7 @@ window_copy_view_init(struct window_mode_entry *wme,
data->backing = xmalloc(sizeof *data->backing); data->backing = xmalloc(sizeof *data->backing);
screen_init(data->backing, sx, screen_size_y(base), UINT_MAX); screen_init(data->backing, sx, screen_size_y(base), UINT_MAX);
data->ictx = input_init(NULL, NULL, NULL); data->ictx = input_init(NULL, NULL, NULL, NULL);
data->mx = data->cx; data->mx = data->cx;
data->my = screen_hsize(data->backing) + data->cy - data->oy; data->my = screen_hsize(data->backing) + data->cy - data->oy;
data->showmark = 0; data->showmark = 0;

View File

@@ -1057,7 +1057,7 @@ window_pane_set_event(struct window_pane *wp)
NULL, window_pane_error_callback, wp); NULL, window_pane_error_callback, wp);
if (wp->event == NULL) if (wp->event == NULL)
fatalx("out of memory"); fatalx("out of memory");
wp->ictx = input_init(wp, wp->event, &wp->palette); wp->ictx = input_init(wp, wp->event, &wp->palette, NULL);
bufferevent_enable(wp->event, EV_READ|EV_WRITE); bufferevent_enable(wp->event, EV_READ|EV_WRITE);
} }