From 6db6a30ab508c4a924245e2d8ccb7bac39838d5c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 26 Nov 2025 10:41:17 +0000 Subject: [PATCH 01/16] Need signal.h for utempter, from Yasuhiro Kimura. --- server-fn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server-fn.c b/server-fn.c index 6ab7fa48..29802a60 100644 --- a/server-fn.c +++ b/server-fn.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include From ec4b5b52afa6e98f313896815018926911e39160 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 26 Nov 2025 19:00:17 +0000 Subject: [PATCH 02/16] Version and CHANGES. --- CHANGES | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index eb0080ec..4abece81 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +CHANGES FROM 3.6 TO 3.6a + +* Fix compile error on FreeBSD (from Yasuhiro Kimura, issue 4701). + CHANGES FROM 3.5a TO 3.6 * Add seconds options for clock mode (issue 4697). diff --git a/configure.ac b/configure.ac index 4be9e03a..200e82de 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], 3.6) +AC_INIT([tmux], 3.6a) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) From 0af04295f3cc622c711711e1d0b1befd06837493 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 26 Nov 2025 19:02:03 +0000 Subject: [PATCH 03/16] Newer libevents do not allow event_del on a zero'd event. --- tty.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tty.c b/tty.c index 889bee2c..71293f6b 100644 --- a/tty.c +++ b/tty.c @@ -35,6 +35,8 @@ static int tty_log_fd = -1; +static void tty_start_timer_callback(int, short, void *); +static void tty_clipboard_query_callback(int, short, void *); static void tty_set_italics(struct tty *); static int tty_try_colour(struct tty *, int, const char *); static void tty_force_cursor_colour(struct tty *, int); @@ -296,6 +298,8 @@ tty_open(struct tty *tty, char **cause) if (tty->out == NULL) fatal("out of memory"); + evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty); + evtimer_set(&tty->start_timer, tty_start_timer_callback, tty); evtimer_set(&tty->timer, tty_timer_callback, tty); tty_start_tty(tty); @@ -327,7 +331,6 @@ tty_start_start_timer(struct tty *tty) log_debug("%s: start timer started", c->name); evtimer_del(&tty->start_timer); - evtimer_set(&tty->start_timer, tty_start_timer_callback, tty); evtimer_add(&tty->start_timer, &tv); } @@ -445,6 +448,7 @@ tty_stop_tty(struct tty *tty) tty->flags &= ~TTY_STARTED; evtimer_del(&tty->start_timer); + evtimer_del(&tty->clipboard_timer); event_del(&tty->timer); tty->flags &= ~TTY_BLOCK; @@ -3228,6 +3232,5 @@ tty_clipboard_query(struct tty *tty) tty_putcode_ss(tty, TTYC_MS, "", "?"); tty->flags |= TTY_OSC52QUERY; - evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty); evtimer_add(&tty->clipboard_timer, &tv); } From 2a0b078e1519bd710cfee9975bd6b0f885063dac Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 26 Nov 2025 18:57:18 +0000 Subject: [PATCH 04/16] Place cursor on correct line if message-line is not 0, reported by Alexis Hildebrandt. --- server-client.c | 14 +++++++------- status.c | 13 +++++++++---- tmux.h | 1 + 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/server-client.c b/server-client.c index b67ae7c2..047365a1 100644 --- a/server-client.c +++ b/server-client.c @@ -2901,8 +2901,8 @@ server_client_reset_state(struct client *c) struct window_pane *wp = server_client_get_pane(c), *loop; struct screen *s = NULL; struct options *oo = c->session->options; - int mode = 0, cursor, flags, n; - u_int cx = 0, cy = 0, ox, oy, sx, sy; + int mode = 0, cursor, flags; + u_int cx = 0, cy = 0, ox, oy, sx, sy, n; if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) return; @@ -2934,13 +2934,13 @@ server_client_reset_state(struct client *c) if (c->prompt_string != NULL) { n = options_get_number(oo, "status-position"); if (n == 0) - cy = 0; + cy = status_prompt_line_at(c); else { - n = status_line_size(c); - if (n == 0) - cy = tty->sy - 1; - else + n = status_line_size(c) - status_prompt_line_at(c); + if (n <= tty->sy) cy = tty->sy - n; + else + cy = tty->sy - 1; } cx = c->prompt_cursor; } else if (c->overlay_draw == NULL) { diff --git a/status.c b/status.c index 2786db7e..0551b547 100644 --- a/status.c +++ b/status.c @@ -264,14 +264,19 @@ status_line_size(struct client *c) } /* Get the prompt line number for client's session. 1 means at the bottom. */ -static u_int +u_int status_prompt_line_at(struct client *c) { struct session *s = c->session; + u_int line, lines; - if (c->flags & (CLIENT_STATUSOFF|CLIENT_CONTROL)) - return (1); - return (options_get_number(s->options, "message-line")); + lines = status_line_size(c); + if (lines == 0) + return (0); + line = options_get_number(s->options, "message-line"); + if (line >= lines) + return (lines - 1); + return (line); } /* Get window at window list position. */ diff --git a/tmux.h b/tmux.h index b2f10ca7..2184e6c6 100644 --- a/tmux.h +++ b/tmux.h @@ -2943,6 +2943,7 @@ extern u_int status_prompt_hsize[]; void status_timer_start(struct client *); void status_timer_start_all(void); void status_update_cache(struct session *); +u_int status_prompt_line_at(struct client *); int status_at_line(struct client *); u_int status_line_size(struct client *); struct style_range *status_get_range(struct client *, u_int, u_int); From 640e1a76438317303aefcd8b76d35a11e59594f6 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 27 Nov 2025 07:26:09 +0000 Subject: [PATCH 05/16] Update CHANGES. --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 4abece81..d6b3013e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ CHANGES FROM 3.6 TO 3.6a +* Newer libevents do not allow event_del on a zero'd event (issue 4706). + +* Place cursor on correct line if message-line is not 0 (issue 4707)). + * Fix compile error on FreeBSD (from Yasuhiro Kimura, issue 4701). CHANGES FROM 3.5a TO 3.6 From bfecbb068594bfbbc7ad8782abab4f5b11f89779 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 1 Dec 2025 08:21:04 +0000 Subject: [PATCH 06/16] Fix combine-test.result, GitHub issue 4717. --- regress/combine-test.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regress/combine-test.result b/regress/combine-test.result index 0d2afb5e..a08539fb 100644 --- a/regress/combine-test.result +++ b/regress/combine-test.result @@ -4,7 +4,7 @@ Λ̊1 🏻2 👍🏻3 -👍🏻 👍🏻4 +👍🏻 👍🏻4 🤷‍♂️5 ♂️7 🤷‍♂️8 From 2c78a5acebe5adfd90ca9f890d24d5bf3ee5e293 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 1 Dec 2025 08:04:26 +0000 Subject: [PATCH 07/16] Add horizontal border case to server_client_check_mouse_in_pane to fix mouse resizing. GitHub issue 4720 from Michael Grant, reported by someone in GitHub issue 4715. --- server-client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-client.c b/server-client.c index 047365a1..2afec6a9 100644 --- a/server-client.c +++ b/server-client.c @@ -613,7 +613,8 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, line = wp->yoff + wp->sy; /* Check if point is within the pane or scrollbar. */ - if (((pane_status != PANE_STATUS_OFF && py != line) || + if (((pane_status != PANE_STATUS_OFF && + py != line && py != wp->yoff + wp->sy) || (wp->yoff == 0 && py < wp->sy) || (py >= wp->yoff && py < wp->yoff + wp->sy)) && ((sb_pos == PANE_SCROLLBARS_RIGHT && From a40f98df0ae80a04d57935b6e0a1913db8ad9bef Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 1 Dec 2025 08:14:29 +0000 Subject: [PATCH 08/16] Change noattr to be an explicit attribute in the style so that it works correctly and does not delete attributes set in the style itself, GitHub issue 4713. --- attributes.c | 5 +++-- screen.c | 6 +++++- style.c | 35 +++++++++++++++++++---------------- tmux.h | 1 + 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/attributes.c b/attributes.c index b839f06d..8eaa8897 100644 --- a/attributes.c +++ b/attributes.c @@ -31,7 +31,7 @@ attributes_tostring(int attr) if (attr == 0) return ("none"); - len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (attr & GRID_ATTR_CHARSET) ? "acs," : "", (attr & GRID_ATTR_BRIGHT) ? "bright," : "", (attr & GRID_ATTR_DIM) ? "dim," : "", @@ -45,7 +45,8 @@ attributes_tostring(int attr) (attr & GRID_ATTR_UNDERSCORE_3) ? "curly-underscore," : "", (attr & GRID_ATTR_UNDERSCORE_4) ? "dotted-underscore," : "", (attr & GRID_ATTR_UNDERSCORE_5) ? "dashed-underscore," : "", - (attr & GRID_ATTR_OVERLINE) ? "overline," : ""); + (attr & GRID_ATTR_OVERLINE) ? "overline," : "", + (attr & GRID_ATTR_NOATTR) ? "noattr," : ""); if (len > 0) buf[len - 1] = '\0'; diff --git a/screen.c b/screen.c index a7a13af2..d82784c5 100644 --- a/screen.c +++ b/screen.c @@ -594,8 +594,12 @@ screen_select_cell(struct screen *s, struct grid_cell *dst, if (COLOUR_DEFAULT(dst->bg)) dst->bg = src->bg; utf8_copy(&dst->data, &src->data); - dst->attr = src->attr; dst->flags = src->flags; + + if (dst->attr & GRID_ATTR_NOATTR) + dst->attr |= (src->attr & GRID_ATTR_CHARSET); + else + dst->attr |= src->attr; } /* Reflow wrapped lines. */ diff --git a/style.c b/style.c index ef3bb225..4acc17dd 100644 --- a/style.c +++ b/style.c @@ -218,20 +218,23 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in) sy->gc.attr = 0; else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) { if (strcmp(tmp + 2, "attr") == 0) - value = 0xffff & ~GRID_ATTR_CHARSET; - else if ((value = attributes_fromstring(tmp + 2)) == -1) - goto error; - sy->gc.attr &= ~value; + sy->gc.attr |= GRID_ATTR_NOATTR; + else { + value = attributes_fromstring(tmp + 2); + if (value == -1) + goto error; + sy->gc.attr &= ~value; + } } else if (end > 6 && strncasecmp(tmp, "width=", 6) == 0) { - n = strtonum(tmp + 6, 0, UINT_MAX, &errstr); - if (errstr != NULL) - goto error; - sy->width = (int)n; + n = strtonum(tmp + 6, 0, UINT_MAX, &errstr); + if (errstr != NULL) + goto error; + sy->width = (int)n; } else if (end > 4 && strncasecmp(tmp, "pad=", 4) == 0) { - n = strtonum(tmp + 4, 0, UINT_MAX, &errstr); - if (errstr != NULL) - goto error; - sy->pad = (int)n; + n = strtonum(tmp + 4, 0, UINT_MAX, &errstr); + if (errstr != NULL) + goto error; + sy->pad = (int)n; } else { if ((value = attributes_fromstring(tmp)) == -1) goto error; @@ -344,13 +347,13 @@ style_tostring(struct style *sy) attributes_tostring(gc->attr)); comma = ","; } - if (sy->width >= 0) { - xsnprintf(s + off, sizeof s - off, "%swidth=%u", comma, + if (sy->width >= 0) { + xsnprintf(s + off, sizeof s - off, "%swidth=%u", comma, sy->width); comma = ","; } - if (sy->pad >= 0) { - xsnprintf(s + off, sizeof s - off, "%spad=%u", comma, + if (sy->pad >= 0) { + xsnprintf(s + off, sizeof s - off, "%spad=%u", comma, sy->pad); comma = ","; } diff --git a/tmux.h b/tmux.h index 2184e6c6..dd62382e 100644 --- a/tmux.h +++ b/tmux.h @@ -727,6 +727,7 @@ struct colour_palette { #define GRID_ATTR_UNDERSCORE_4 0x800 #define GRID_ATTR_UNDERSCORE_5 0x1000 #define GRID_ATTR_OVERLINE 0x2000 +#define GRID_ATTR_NOATTR 0x4000 /* All underscore attributes. */ #define GRID_ATTR_ALL_UNDERSCORE \ From 52917abe21c1f3c930399946c3b0bccbcc604439 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 2 Dec 2025 14:26:30 +0000 Subject: [PATCH 09/16] Update CHANGES. --- CHANGES | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d6b3013e..d2b47190 100644 --- a/CHANGES +++ b/CHANGES @@ -1,8 +1,14 @@ CHANGES FROM 3.6 TO 3.6a +* Fix horizontal mouse resizing when pane status lines are on (from Michael + Grant, issue 4720). + +* Fix noattr so it does not delete attributes set in the style itself (issue + 4713). + * Newer libevents do not allow event_del on a zero'd event (issue 4706). -* Place cursor on correct line if message-line is not 0 (issue 4707)). +* Place cursor on correct line if message-line is not 0 (issue 4707). * Fix compile error on FreeBSD (from Yasuhiro Kimura, issue 4701). From 33c1ba154940461029eb45a9ba047bf8cf7307e7 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Dec 2025 06:02:27 +0000 Subject: [PATCH 10/16] Allow characters to be combined in either order, reported by Jake Stewart in GitHub issue 4726. --- screen-write.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/screen-write.c b/screen-write.c index 76beffbc..a2755d35 100644 --- a/screen-write.c +++ b/screen-write.c @@ -2152,6 +2152,8 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) case HANGULJAMO_STATE_NOT_HANGULJAMO: if (utf8_should_combine(&last.data, ud)) force_wide = 1; + else if (utf8_should_combine(ud, &last.data)) + force_wide = 1; else if (!utf8_has_zwj(&last.data)) return (0); break; From 3b57077d015a33ec9f7f4571f90f1cfd25132245 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Dec 2025 06:04:21 +0000 Subject: [PATCH 11/16] Add a missing skin tone, from Jake Stewart in GitHub issue 4736. --- utf8-combined.c | 1 + 1 file changed, 1 insertion(+) diff --git a/utf8-combined.c b/utf8-combined.c index 635ae92c..1eee3b82 100644 --- a/utf8-combined.c +++ b/utf8-combined.c @@ -122,6 +122,7 @@ utf8_should_combine(const struct utf8_data *with, const struct utf8_data *add) case 0x1F47C: case 0x1F481: case 0x1F482: + case 0x1F483: case 0x1F485: case 0x1F486: case 0x1F487: From 2fc123cf4a72d32f7b8bdbce1223cf583d808354 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 4 Dec 2025 20:54:44 +0000 Subject: [PATCH 12/16] Update CHANGES. --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index d2b47190..e4657965 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,10 @@ CHANGES FROM 3.6 TO 3.6a +* Add a missing skin tone (from Jake Stewart, issue 4736). + +* Allow characters to be combined in either order (issue 4726, reported by Jake + Stewart). + * Fix horizontal mouse resizing when pane status lines are on (from Michael Grant, issue 4720). From ff207eb5834515580694a4623f7d45233794f7f1 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Dec 2025 14:45:32 +0000 Subject: [PATCH 13/16] Fix y offset of mouse if status at top. GitHub issue 4738 from Michael Grant. --- screen-redraw.c | 5 +++++ server-client.c | 6 +++++- window-copy.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 96081839..1c1b8503 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1028,6 +1028,11 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx, int sx = ctx->sx, sy = ctx->sy, xoff = wp->xoff; int yoff = wp->yoff; + if (ctx->statustop) { + sb_y += ctx->statuslines; + sy += ctx->statuslines; + } + /* Set up style for slider. */ gc = sb_style->gc; memcpy(&slgc, &gc, sizeof slgc); diff --git a/server-client.c b/server-client.c index 2afec6a9..7f1942c7 100644 --- a/server-client.c +++ b/server-client.c @@ -1271,7 +1271,11 @@ have_event: if (c->tty.mouse_scrolling_flag == 0 && where == SCROLLBAR_SLIDER) { c->tty.mouse_scrolling_flag = 1; - c->tty.mouse_slider_mpos = sl_mpos; + if (m->statusat == 0) { + c->tty.mouse_slider_mpos = sl_mpos + + m->statuslines; + } else + c->tty.mouse_slider_mpos = sl_mpos; } break; case WHEEL: diff --git a/window-copy.c b/window-copy.c index f056cebb..2d528496 100644 --- a/window-copy.c +++ b/window-copy.c @@ -627,7 +627,7 @@ window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp, new_slider_y = sb_top - wp->yoff + (sb_height - slider_height); } else { /* Slider is somewhere in the middle. */ - new_slider_y = my - wp->yoff - sl_mpos + 1; + new_slider_y = my - wp->yoff - sl_mpos; } if (TAILQ_FIRST(&wp->modes) == NULL || From 01962e25dc25b732361fa0b94ce630651891cd33 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Dec 2025 22:50:34 +0000 Subject: [PATCH 14/16] Allow drag in alternate screen again, GitHub issue 4743 reported by Brad King. --- key-bindings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/key-bindings.c b/key-bindings.c index 7f8b20e0..a5e1f9c8 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -441,7 +441,7 @@ key_bindings_init(void) "bind -n MouseDown1Pane { select-pane -t=; send -M }", /* Mouse button 1 drag on pane. */ - "bind -n MouseDrag1Pane { if -F '#{||:#{alternate_on},#{pane_in_mode},#{mouse_any_flag}}' { send -M } { copy-mode -M } }", + "bind -n MouseDrag1Pane { if -F '#{||:#{pane_in_mode},#{mouse_any_flag}}' { send -M } { copy-mode -M } }", /* Mouse wheel up on pane. */ "bind -n WheelUpPane { if -F '#{||:#{alternate_on},#{pane_in_mode},#{mouse_any_flag}}' { send -M } { copy-mode -e } }", From faebe7a70a43958ea69a4ddfa1812da3f97bd621 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 4 Dec 2025 20:49:57 +0000 Subject: [PATCH 15/16] Do not read over buffer if format is a single #, and do not loop forever if UTF-8 is unfinished in a format. Reported by Giorgi Kobakhia im GitHub issue 4735. --- format-draw.c | 2 -- format.c | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/format-draw.c b/format-draw.c index efc6ab1a..c8cb74b6 100644 --- a/format-draw.c +++ b/format-draw.c @@ -1104,8 +1104,6 @@ format_width(const char *expanded) more = utf8_append(&ud, *cp); if (more == UTF8_DONE) width += ud.width; - else - cp -= ud.have; } else if (*cp > 0x1f && *cp < 0x7f) { width++; cp++; diff --git a/format.c b/format.c index 17a9dd53..3d498b34 100644 --- a/format.c +++ b/format.c @@ -5545,7 +5545,8 @@ format_expand1(struct format_expand_state *es, const char *fmt) buf[off++] = *fmt++; continue; } - fmt++; + if (*fmt++ == '\0') + break; ch = (u_char)*fmt++; switch (ch) { From cc117b5048f77a4842820f8ebbe3a86e5c077224 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 5 Dec 2025 05:39:46 +0000 Subject: [PATCH 16/16] Update CHANGES. --- CHANGES | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES b/CHANGES index e4657965..bcd1e1c6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,12 @@ CHANGES FROM 3.6 TO 3.6a +* Fix a buffer overread and an infinite loop in format processing (reported by + Giorgi Kobakhia, issue 4735). + +* Allow drag in alternate screen again (issue 4743 reported by Brad King). + +* Fix y offset of mouse if status at top (issue 4738 from Michael Grant). + * Add a missing skin tone (from Jake Stewart, issue 4736). * Allow characters to be combined in either order (issue 4726, reported by Jake