From 0e1f6ed80d7c5447b159304aa0323a0b59acdd7b Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 22 Sep 2026 06:46:50 +0000 Subject: [PATCH 1/4] Do not leak waiting clients (in wait-for) if they are killed, GitHub issue 5614. --- cmd-queue.c | 5 ++++- cmd-wait-for.c | 36 +++++++++++++++++++++++++++++++++++- server-client.c | 5 ++++- tmux.h | 3 ++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/cmd-queue.c b/cmd-queue.c index 4ecec8f7d..f96edd2dc 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-queue.c,v 1.123 2026/08/24 20:34:26 nicm Exp $ */ +/* $OpenBSD: cmd-queue.c,v 1.124 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott @@ -581,6 +581,9 @@ cmdq_fire_command(struct cmdq_item *item) int flags, quiet = 0; char *tmp; + if (item->client != NULL && (item->client->flags & CLIENT_DEAD)) + return (CMD_RETURN_ERROR); + if (cfg_finished) cmdq_add_message(item); if (log_get_level() > 1) { diff --git a/cmd-wait-for.c b/cmd-wait-for.c index 0e4130fcd..7326c7519 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-wait-for.c,v 1.23 2026/07/10 13:38:45 nicm Exp $ */ +/* $OpenBSD: cmd-wait-for.c,v 1.24 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott @@ -480,6 +480,40 @@ cmd_wait_for_unlock(struct cmdq_item *item, const char *name, return (CMD_RETURN_NORMAL); } +void +cmd_wait_for_client_lost(struct client *c) +{ + struct wait_channel *wc, *wc1; + struct wait_item *wi, *wi1; + struct wait_event_item *wei, *wei1; + + TAILQ_FOREACH_SAFE(wei, &wait_event_items, entry, wei1) { + if (cmdq_get_client(wei->item) == c) { + TAILQ_REMOVE(&wait_event_items, wei, entry); + cmdq_continue(wei->item); + cmd_wait_for_event_free(wei); + } + } + + RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) { + TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) { + if (cmdq_get_client(wi->item) == c) { + cmdq_continue(wi->item); + TAILQ_REMOVE(&wc->waiters, wi, entry); + free(wi); + } + } + TAILQ_FOREACH_SAFE(wi, &wc->lockers, entry, wi1) { + if (cmdq_get_client(wi->item) == c) { + cmdq_continue(wi->item); + TAILQ_REMOVE(&wc->lockers, wi, entry); + free(wi); + } + } + cmd_wait_for_remove_empty(wc); + } +} + void cmd_wait_for_flush(void) { diff --git a/server-client.c b/server-client.c index e5041e24c..7eac47087 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.513 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.514 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -389,6 +389,9 @@ server_client_lost(struct client *c) TAILQ_REMOVE(&clients, c, entry); log_debug("lost client %p", c); + cmd_wait_for_client_lost(c); + cmdq_next(c); + if (c->flags & CLIENT_ATTACHED) { server_client_attached_lost(c); events_fire_client("client-detached", c); diff --git a/tmux.h b/tmux.h index c292ade9d..086b49559 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1444 2026/09/21 12:14:32 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1445 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3160,6 +3160,7 @@ void cmdq_print_data(struct cmdq_item *, struct evbuffer *); void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...); /* cmd-wait-for.c */ +void cmd_wait_for_client_lost(struct client *); void cmd_wait_for_flush(void); /* client.c */ From 4624bc2129c5e723a5386d36003599eb3f2e6bb7 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 22 Sep 2026 06:48:01 +0000 Subject: [PATCH 2/4] Correctly write Z indexes to v2 layouts if zoomed, GitHub issue 5624. --- layout-custom.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/layout-custom.c b/layout-custom.c index 59bfeb075..514db1369 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout-custom.c,v 1.42 2026/09/20 08:37:47 nicm Exp $ */ +/* $OpenBSD: layout-custom.c,v 1.43 2026/09/22 06:48:01 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott @@ -307,6 +307,37 @@ bad: return (xstrdup("0000,")); } +/* Get a floating pane cell's z-index in the layout being dumped. */ +static u_int +layout_cell_zindex(struct layout_cell *lc) +{ + struct window_pane *wp = lc->wp, *wq; + struct window *w = wp->window; + struct layout_cell *other; + int saved = (lc == wp->saved_layout_cell); + u_int i = 0; + + if (saved && + w->active != NULL && + (w->active->flags & PANE_ZOOMED) && + (w->active->saved_layout_cell->flags & LAYOUT_CELL_FLOATING)) { + if (wp == w->active) + return (0); + i++; + } + TAILQ_FOREACH(wq, &w->z_index, zentry) { + if (wq == wp) + break; + if (saved) + other = wq->saved_layout_cell; + else + other = wq->layout_cell; + if (other != NULL && (other->flags & LAYOUT_CELL_FLOATING)) + i++; + } + return (i); +} + /* Append information for a single cell in a JSON (v2) format. */ static int layout_append_v2(struct layout_cell *lc, struct layout_string *ls) @@ -315,7 +346,7 @@ layout_append_v2(struct layout_cell *lc, struct layout_string *ls) struct window_pane *wp; enum layout_type type; char c; - u_int i, n; + u_int i, n, z; if (lc == NULL) return (-1); @@ -356,9 +387,10 @@ layout_append_v2(struct layout_cell *lc, struct layout_string *ls) if (window_pane_index(wp, &i) != 0) return (-1); layout_string_write(ls, ",\"i\":%u", i); - if ((lc->flags & LAYOUT_CELL_FLOATING) && - window_pane_zindex(wp, &i) == 0) - layout_string_write(ls, ",\"z\":%u", i); + if (lc->flags & LAYOUT_CELL_FLOATING) { + z = layout_cell_zindex(lc); + layout_string_write(ls, ",\"z\":%u", z); + } layout_string_write(ls, ",\"I\":\"%%%u\"", wp->id); } From 19b766077827885d91a9d3a6af253f179499f47e Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 22 Sep 2026 06:49:47 +0000 Subject: [PATCH 3/4] Only rely on the previous line wrapping when the cursor is actually on it, GitHub issue 5625 from Ben Maurer. --- tty-draw.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tty-draw.c b/tty-draw.c index cc190f821..d707d1bf3 100644 --- a/tty-draw.c +++ b/tty-draw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-draw.c,v 1.16 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: tty-draw.c,v 1.17 2026/09/22 06:49:47 nicm Exp $ */ /* * Copyright (c) 2026 Nicholas Marriott @@ -218,7 +218,12 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, } /* Did the previous line wrap on to this one? */ - if (py != 0 && atx == 0 && tty->cx >= tty->sx && nx == tty->sx) { + if (py != 0 && + atx == 0 && + tty->cx >= tty->sx && + tty->cy != UINT_MAX && + tty->cy + 1 == aty && + nx == tty->sx) { gl = grid_get_line(gd, gd->hsize + py - 1); if (gl->flags & GRID_LINE_WRAPPED) wrapped = 1; From 83f62d0acc548e6d58fec8a7332b48d913ce9bd6 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 22 Sep 2026 06:58:05 +0000 Subject: [PATCH 4/4] Add a feature for mintty's application escape to avoid dodgy terminals whinging about not supporting it, GitHub issue 5626 from Pete Dietl. --- tmux.1 | 9 +++++++-- tmux.h | 4 +++- tty-features.c | 16 +++++++++++++++- tty-term.c | 4 +++- tty.c | 8 +++----- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tmux.1 b/tmux.1 index 1d5ef7344..3487b8831 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.1171 2026/09/21 10:22:31 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.1172 2026/09/22 06:58:05 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 21 2026 $ +.Dd $Mdocdate: September 22 2026 $ .Dt TMUX 1 .Os .Sh NAME @@ -5083,6 +5083,9 @@ The available features are: .Bl -tag -width Ds .It 256 Supports 256 colours with the SGR escape sequences. +.It appesc +Supports application escape key mode, where the Escape key sends a sequence +that cannot be mistaken for the start of another key. .It clipboard Allows setting the system clipboard. .It ccolour @@ -8831,6 +8834,8 @@ These are set automatically if the capability is present. .It Em \&Dseks , \&Eneks Disable and enable extended keys. +.It Em \&Dsesc , \&Enesc +Disable and enable application escape key mode. .It Em \&Dsfcs , \&Enfcs Disable and enable focus reporting. These are set automatically if the diff --git a/tmux.h b/tmux.h index 086b49559..f739014a2 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1445 2026/09/22 06:46:50 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1446 2026/09/22 06:58:06 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -455,6 +455,7 @@ enum tty_code_code { TTYC_DL1, TTYC_DSBP, TTYC_DSEKS, + TTYC_DSESC, TTYC_DSFCS, TTYC_DSMG, TTYC_E3, @@ -465,6 +466,7 @@ enum tty_code_code { TTYC_ENACS, TTYC_ENBP, TTYC_ENEKS, + TTYC_ENESC, TTYC_ENFCS, TTYC_ENMG, TTYC_FSL, diff --git a/tty-features.c b/tty-features.c index 56c692083..04ec4269b 100644 --- a/tty-features.c +++ b/tty-features.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-features.c,v 1.43 2026/08/31 12:41:03 kirill Exp $ */ +/* $OpenBSD: tty-features.c,v 1.44 2026/09/22 06:58:06 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -179,6 +179,18 @@ static const struct tty_feature tty_feature_focus = { 0 }; +/* Terminal supports application escape key mode. */ +static const char *const tty_feature_appesc_capabilities[] = { + "Enesc=\\E[?7727h", + "Dsesc=\\E[?7727l", + NULL +}; +static const struct tty_feature tty_feature_appesc = { + "appesc", + tty_feature_appesc_capabilities, + 0 +}; + /* Terminal supports cursor styles. */ static const char *const tty_feature_cstyle_capabilities[] = { "Ss=\\E[%p1%d q", @@ -368,6 +380,7 @@ static const struct tty_feature tty_feature_utf8 = { /* Available terminal features. */ static const struct tty_feature *const tty_features[] = { &tty_feature_256, + &tty_feature_appesc, &tty_feature_bpaste, &tty_feature_ccolour, &tty_feature_clipboard, @@ -558,6 +571,7 @@ tty_default_features(struct client *c, const char *name, u_int version) "256,RGB,bpaste,clipboard,mouse,strikethrough,title" { .name = "mintty", .features = TTY_FEATURES_BASE_MODERN_XTERM "," + "appesc," "ccolour," "cstyle," "extkeys," diff --git a/tty-term.c b/tty-term.c index 3f3bc9c8d..95bc76189 100644 --- a/tty-term.c +++ b/tty-term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.109 2026/08/25 08:37:08 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.110 2026/09/22 06:58:06 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -87,6 +87,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_DL1] = { TTYCODE_STRING, "dl1" }, [TTYC_DL] = { TTYCODE_STRING, "dl" }, [TTYC_DSEKS] = { TTYCODE_STRING, "Dseks" }, + [TTYC_DSESC] = { TTYCODE_STRING, "Dsesc" }, [TTYC_DSFCS] = { TTYCODE_STRING, "Dsfcs" }, [TTYC_DSBP] = { TTYCODE_STRING, "Dsbp" }, [TTYC_DSMG] = { TTYCODE_STRING, "Dsmg" }, @@ -98,6 +99,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_ENACS] = { TTYCODE_STRING, "enacs" }, [TTYC_ENBP] = { TTYCODE_STRING, "Enbp" }, [TTYC_ENEKS] = { TTYCODE_STRING, "Eneks" }, + [TTYC_ENESC] = { TTYCODE_STRING, "Enesc" }, [TTYC_ENFCS] = { TTYCODE_STRING, "Enfcs" }, [TTYC_ENMG] = { TTYCODE_STRING, "Enmg" }, [TTYC_FSL] = { TTYCODE_STRING, "fsl" }, diff --git a/tty.c b/tty.c index bf9eb884f..3190bd8b0 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.481 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.482 2026/09/22 06:58:06 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -497,8 +497,7 @@ tty_stop_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_DSBP)) tty_raw(tty, tty_term_string(tty->term, TTYC_DSBP)); - if (tty->term->flags & TERM_VT100LIKE) - tty_raw(tty, "\033[?7727l"); + tty_raw(tty, tty_term_string(tty->term, TTYC_DSESC)); tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS)); tty_raw(tty, tty_term_string(tty->term, TTYC_DSEKS)); @@ -555,8 +554,7 @@ tty_update_features(struct tty *tty) tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS)); if (options_get_number(global_options, "focus-events")) tty_puts(tty, tty_term_string(tty->term, TTYC_ENFCS)); - if (tty->term->flags & TERM_VT100LIKE) - tty_puts(tty, "\033[?7727h"); + tty_puts(tty, tty_term_string(tty->term, TTYC_ENESC)); /* * Features might have changed since the first draw during attach. For