From 8d2286b76917debc4f6c3b0903ad2807ae254bb5 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 1 Nov 2021 09:34:49 +0000 Subject: Add a cursor-colour option, from Alexis Hildebrandt in GitHub issue 2959. --- input.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'input.c') diff --git a/input.c b/input.c index 8a16281c..b2769e31 100644 --- a/input.c +++ b/input.c @@ -137,10 +137,12 @@ static void input_reset_cell(struct input_ctx *); static void input_osc_4(struct input_ctx *, const char *); static void input_osc_10(struct input_ctx *, const char *); static void input_osc_11(struct input_ctx *, const char *); +static void input_osc_12(struct input_ctx *, const char *); static void input_osc_52(struct input_ctx *, const char *); static void input_osc_104(struct input_ctx *, const char *); static void input_osc_110(struct input_ctx *, const char *); static void input_osc_111(struct input_ctx *, const char *); +static void input_osc_112(struct input_ctx *, const char *); /* Transition entry/exit handlers. */ static void input_clear(struct input_ctx *); @@ -2310,8 +2312,7 @@ input_exit_osc(struct input_ctx *ictx) input_osc_11(ictx, p); break; case 12: - if (utf8_isvalid(p) && *p != '?') /* ? is colour request */ - screen_set_cursor_colour(sctx->s, p); + input_osc_12(ictx, p); break; case 52: input_osc_52(ictx, p); @@ -2326,8 +2327,7 @@ input_exit_osc(struct input_ctx *ictx) input_osc_111(ictx, p); break; case 112: - if (*p == '\0') /* no arguments allowed */ - screen_set_cursor_colour(sctx->s, ""); + input_osc_112(ictx, p); break; default: log_debug("%s: unknown '%u'", __func__, option); @@ -2489,7 +2489,9 @@ input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c) u_char r, g, b; const char *end; - if (c == 8 || (~c & COLOUR_FLAG_RGB)) + if (c != -1) + c = colour_force_rgb(c); + if (c == -1) return; colour_split_rgb(c, &r, &g, &b); @@ -2564,7 +2566,7 @@ input_osc_10(struct input_ctx *ictx, const char *p) } } -/* Handle the OSC 110 sequence for resetting background colour. */ +/* Handle the OSC 110 sequence for resetting foreground colour. */ static void input_osc_110(struct input_ctx *ictx, const char *p) { @@ -2624,6 +2626,39 @@ input_osc_111(struct input_ctx *ictx, const char *p) } } +/* Handle the OSC 12 sequence for setting and querying cursor colour. */ +static void +input_osc_12(struct input_ctx *ictx, const char *p) +{ + struct window_pane *wp = ictx->wp; + int c; + + if (strcmp(p, "?") == 0) { + if (wp != NULL) { + c = ictx->ctx.s->ccolour; + if (c == -1) + c = ictx->ctx.s->default_ccolour; + input_osc_colour_reply(ictx, 12, c); + } + return; + } + + if ((c = input_osc_parse_colour(p)) == -1) { + log_debug("bad OSC 12: %s", p); + return; + } + screen_set_cursor_colour(ictx->ctx.s, c); +} + +/* Handle the OSC 112 sequence for resetting cursor colour. */ +static void +input_osc_112(struct input_ctx *ictx, const char *p) +{ + if (*p == '\0') /* no arguments allowed */ + screen_set_cursor_colour(ictx->ctx.s, -1); +} + + /* Handle the OSC 52 sequence for setting the clipboard. */ static void input_osc_52(struct input_ctx *ictx, const char *p) -- cgit From 57100376cc70739f53a1f8a4bacf192b8cdcd124 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 3 Nov 2021 13:37:17 +0000 Subject: Add a cursor-style option, from Alexis Hildebrandt in GitHub issue 2960. --- input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'input.c') diff --git a/input.c b/input.c index b2769e31..3626c4b2 100644 --- a/input.c +++ b/input.c @@ -1619,7 +1619,7 @@ input_csi_dispatch(struct input_ctx *ictx) case INPUT_CSI_DECSCUSR: n = input_get(ictx, 0, 0, 0); if (n != -1) - screen_set_cursor_style(s, n); + screen_set_cursor_style(n, &s->cstyle, &s->mode); break; case INPUT_CSI_XDA: n = input_get(ictx, 0, 0, 0); @@ -1685,6 +1685,7 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx) break; case 12: screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING); + screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET); break; case 25: /* TCEM */ screen_write_mode_clear(sctx, MODE_CURSOR); @@ -1774,6 +1775,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx) break; case 12: screen_write_mode_set(sctx, MODE_CURSOR_BLINKING); + screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET); break; case 25: /* TCEM */ screen_write_mode_set(sctx, MODE_CURSOR); -- cgit From cb8a0d83fbaa2ae49c06105cb94d247ef20ed91e Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 11 Nov 2021 09:31:16 +0000 Subject: If automatic-rename is off, allow the escape sequence to set an empty window name, GitHub issue 2964. --- input.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'input.c') diff --git a/input.c b/input.c index 3626c4b2..73a58890 100644 --- a/input.c +++ b/input.c @@ -2382,6 +2382,7 @@ static void input_exit_rename(struct input_ctx *ictx) { struct window_pane *wp = ictx->wp; + struct window *w; struct options_entry *o; if (wp == NULL) @@ -2394,17 +2395,20 @@ input_exit_rename(struct input_ctx *ictx) if (!utf8_isvalid(ictx->input_buf)) return; + w = wp->window; if (ictx->input_len == 0) { - o = options_get_only(wp->window->options, "automatic-rename"); + o = options_get_only(w->options, "automatic-rename"); if (o != NULL) options_remove_or_default(o, -1, NULL); - return; + if (!options_get_number(w->options, "automatic-rename")) + window_set_name(w, ""); + } else { + options_set_number(w->options, "automatic-rename", 0); + window_set_name(w, ictx->input_buf); } - window_set_name(wp->window, ictx->input_buf); - options_set_number(wp->window->options, "automatic-rename", 0); - server_redraw_window_borders(wp->window); - server_status_window(wp->window); + server_redraw_window_borders(w); + server_status_window(w); } /* Open UTF-8 character. */ -- cgit From d721fb2a9fd70c157abb8540d4c50fca654f9f4d Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 7 Dec 2021 07:28:44 +0000 Subject: Respond to OSC 4 query. --- input.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'input.c') diff --git a/input.c b/input.c index 73a58890..16f31ad7 100644 --- a/input.c +++ b/input.c @@ -2505,7 +2505,8 @@ input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c) end = "\007"; else end = "\033\\"; - input_reply(ictx, "\033]%u;rgb:%02hhx/%02hhx/%02hhx%s", n, r, g, b, end); + input_reply(ictx, "\033]%u;rgb:%02hhx%02hhx/%02hhx%02hhx/%02hhx%02hhx%s", + n, r, r, g, g, b, b, end); } /* Handle the OSC 4 sequence for setting (multiple) palette entries. */ @@ -2529,6 +2530,12 @@ input_osc_4(struct input_ctx *ictx, const char *p) } s = strsep(&next, ";"); + if (strcmp(s, "?") == 0) { + c = colour_palette_get(ictx->palette, idx); + if (c != -1) + input_osc_colour_reply(ictx, 4, c); + continue; + } if ((c = input_osc_parse_colour(s)) == -1) { s = next; continue; -- cgit From 5076beb009f761999a3b218a1a8d7cbfbc80ee03 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 15 Feb 2022 13:11:29 +0000 Subject: Add an option (default off) to control the passthrough escape sequence. Like set-clipboard and allow-rename it is safer to forbid this by default. --- input.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'input.c') diff --git a/input.c b/input.c index 16f31ad7..5adc694d 100644 --- a/input.c +++ b/input.c @@ -2235,15 +2235,19 @@ input_enter_dcs(struct input_ctx *ictx) static int input_dcs_dispatch(struct input_ctx *ictx) { + struct window_pane *wp = ictx->wp; struct screen_write_ctx *sctx = &ictx->ctx; u_char *buf = ictx->input_buf; size_t len = ictx->input_len; const char prefix[] = "tmux;"; const u_int prefixlen = (sizeof prefix) - 1; + if (wp == NULL) + return (0); if (ictx->flags & INPUT_DISCARD) return (0); - + if (!options_get_number(ictx->wp->options, "allow-passthrough")) + return (0); log_debug("%s: \"%s\"", __func__, buf); if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0) -- cgit From ad9b8059836d424f70a8579d28e28e0186cdbaa6 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 8 Mar 2022 12:01:19 +0000 Subject: Add argument to refresh-client -l to forward clipboard to a pane. GitHub issue 3068. --- input.c | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'input.c') diff --git a/input.c b/input.c index 5adc694d..b1856538 100644 --- a/input.c +++ b/input.c @@ -2682,8 +2682,8 @@ input_osc_52(struct input_ctx *ictx, const char *p) { struct window_pane *wp = ictx->wp; char *end; - const char *buf; - size_t len; + const char *buf = NULL; + size_t len = 0; u_char *out; int outlen, state; struct screen_write_ctx ctx; @@ -2703,26 +2703,12 @@ input_osc_52(struct input_ctx *ictx, const char *p) log_debug("%s: %s", __func__, end); if (strcmp(end, "?") == 0) { - if ((pb = paste_get_top(NULL)) != NULL) { + if ((pb = paste_get_top(NULL)) != NULL) buf = paste_buffer_data(pb, &len); - outlen = 4 * ((len + 2) / 3) + 1; - out = xmalloc(outlen); - if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) { - free(out); - return; - } - } else { - outlen = 0; - out = NULL; - } - bufferevent_write(ictx->event, "\033]52;;", 6); - if (outlen != 0) - bufferevent_write(ictx->event, out, outlen); if (ictx->input_end == INPUT_END_BEL) - bufferevent_write(ictx->event, "\007", 1); + input_reply_clipboard(ictx->event, buf, len, "\007"); else - bufferevent_write(ictx->event, "\033\\", 2); - free(out); + input_reply_clipboard(ictx->event, buf, len, "\033\\"); return; } @@ -2780,3 +2766,26 @@ input_osc_104(struct input_ctx *ictx, const char *p) screen_write_fullredraw(&ictx->ctx); free(copy); } + +void +input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len, + const char *end) +{ + char *out = NULL; + size_t outlen = 0; + + if (buf != NULL && len != 0) { + outlen = 4 * ((len + 2) / 3) + 1; + out = xmalloc(outlen); + if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) { + free(out); + return; + } + } + + bufferevent_write(bev, "\033]52;;", 6); + if (outlen != 0) + bufferevent_write(bev, out, outlen); + bufferevent_write(bev, end, strlen(end)); + free(out); +} -- cgit From cd89000c1d75d0cfec28cf7e81b06f80a43ea093 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 30 May 2022 13:00:18 +0000 Subject: Add a way for lines added to copy mode to be passed through the parser to handle escape sequences and use it for run-shell, GitHub issue 3156. --- input.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'input.c') diff --git a/input.c b/input.c index b1856538..693b6f32 100644 --- a/input.c +++ b/input.c @@ -1078,6 +1078,9 @@ input_reply(struct input_ctx *ictx, const char *fmt, ...) va_list ap; char *reply; + if (bev == NULL) + return; + va_start(ap, fmt); xvasprintf(&reply, fmt, ap); va_end(ap); @@ -1798,6 +1801,8 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx) screen_write_mode_set(sctx, MODE_FOCUSON); if (wp == NULL) break; + if (!options_get_number(global_options, "focus-events")) + break; if (wp->flags & PANE_FOCUSED) bufferevent_write(wp->event, "\033[I", 3); else -- cgit From ccc9dc3bb49ac258c856d8478346b4ce829b188e Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jun 2022 09:12:55 +0000 Subject: If an application gives the first parameter to OSC 52, validate and pass on to outside terminal. GitHub issue 3192. --- input.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'input.c') diff --git a/input.c b/input.c index 693b6f32..fa9dfcdf 100644 --- a/input.c +++ b/input.c @@ -2693,6 +2693,9 @@ input_osc_52(struct input_ctx *ictx, const char *p) int outlen, state; struct screen_write_ctx ctx; struct paste_buffer *pb; + const char* allow = "cpqs01234567"; + char flags[sizeof allow] = ""; + u_int i, j = 0; if (wp == NULL) return; @@ -2707,6 +2710,12 @@ input_osc_52(struct input_ctx *ictx, const char *p) return; log_debug("%s: %s", __func__, end); + for (i = 0; p + i != end; i++) { + if (strchr(allow, p[i]) != NULL && strchr(flags, p[i]) == NULL) + flags[j++] = p[i]; + } + log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, flags); + if (strcmp(end, "?") == 0) { if ((pb = paste_get_top(NULL)) != NULL) buf = paste_buffer_data(pb, &len); @@ -2728,7 +2737,7 @@ input_osc_52(struct input_ctx *ictx, const char *p) } screen_write_start_pane(&ctx, wp, NULL); - screen_write_setselection(&ctx, out, outlen); + screen_write_setselection(&ctx, flags, out, outlen); screen_write_stop(&ctx); notify_pane("pane-set-clipboard", wp); -- cgit From 18a5835affc3fef58f673a8feeb128cf4132525e Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 10 Jun 2022 11:55:30 +0000 Subject: Ignore OSC if the first argument is not properly terminated. --- input.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'input.c') diff --git a/input.c b/input.c index fa9dfcdf..05654124 100644 --- a/input.c +++ b/input.c @@ -2292,6 +2292,8 @@ input_exit_osc(struct input_ctx *ictx) option = 0; while (*p >= '0' && *p <= '9') option = option * 10 + *p++ - '0'; + if (*p != ';' && *p != '\0') + return; if (*p == ';') p++; -- cgit From 42ddf02ffce2002ed5ded5e03e1a51516fc2d710 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 11 Jun 2022 16:59:33 +0000 Subject: Fix size of flags output buffer. --- input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'input.c') diff --git a/input.c b/input.c index 05654124..d4ffe784 100644 --- a/input.c +++ b/input.c @@ -2696,7 +2696,7 @@ input_osc_52(struct input_ctx *ictx, const char *p) struct screen_write_ctx ctx; struct paste_buffer *pb; const char* allow = "cpqs01234567"; - char flags[sizeof allow] = ""; + char flags[sizeof "cpqs01234567"] = ""; u_int i, j = 0; if (wp == NULL) -- cgit From cdacc12ce305ad2f3e65e2a01328a988e3200b51 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 30 Jun 2022 09:55:53 +0000 Subject: Add support for OSC 8 hyperlinks (a VTE extension now supported by other terminals such as iTerm2). Originally written by me then extended and completed by first Will Noble and later Jeff Chiang. GitHub issues 911, 2621, 2890, 3240. --- input.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'input.c') diff --git a/input.c b/input.c index d4ffe784..4252428b 100644 --- a/input.c +++ b/input.c @@ -135,6 +135,7 @@ static void input_set_state(struct input_ctx *, static void input_reset_cell(struct input_ctx *); static void input_osc_4(struct input_ctx *, const char *); +static void input_osc_8(struct input_ctx *, const char *); static void input_osc_10(struct input_ctx *, const char *); static void input_osc_11(struct input_ctx *, const char *); static void input_osc_12(struct input_ctx *, const char *); @@ -2318,6 +2319,9 @@ input_exit_osc(struct input_ctx *ictx) } } break; + case 8: + input_osc_8(ictx, p); + break; case 10: input_osc_10(ictx, p); break; @@ -2562,6 +2566,47 @@ input_osc_4(struct input_ctx *ictx, const char *p) free(copy); } +/* Handle the OSC 8 sequence for embedding hyperlinks. */ +static void +input_osc_8(struct input_ctx *ictx, const char *p) +{ + struct hyperlinks *hl = ictx->ctx.s->hyperlinks; + struct grid_cell *gc = &ictx->cell.cell; + const char *start, *end, *uri; + char *id = NULL; + + for (start = p; (end = strpbrk(start, ":;")) != NULL; start = end + 1) { + if (end - start >= 4 && strncmp(start, "id=", 3) == 0) { + if (id != NULL) + goto bad; + id = xstrndup(start + 3, end - start - 3); + } + + /* The first ; is the end of parameters and start of the URI. */ + if (*end == ';') + break; + } + if (end == NULL || *end != ';') + goto bad; + uri = end + 1; + if (*uri == '\0') { + gc->link = 0; + free(id); + return; + } + gc->link = hyperlinks_put(hl, uri, id); + if (id == NULL) + log_debug("hyperlink (anonymous) %s = %u", uri, gc->link); + else + log_debug("hyperlink (id=%s) %s = %u", id, uri, gc->link); + free(id); + return; + +bad: + log_debug("bad OSC 8 %s", p); + free(id); +} + /* Handle the OSC 10 sequence for setting and querying foreground colour. */ static void input_osc_10(struct input_ctx *ictx, const char *p) -- cgit