From 800837ff3f21799281525af3d8537f362e5cb43e Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 May 2026 09:27:28 +0000 Subject: [PATCH 1/7] Fix control mode teardown ordering for queued pane output, GitHub issue 5064 from Aaron Campbell. --- control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control.c b/control.c index 4a7201ef..ab461ff1 100644 --- a/control.c +++ b/control.c @@ -847,9 +847,9 @@ control_stop(struct client *c) if (evtimer_initialized(&cs->subs_timer)) evtimer_del(&cs->subs_timer); + control_reset_offsets(c); TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1) control_free_block(cs, cb); - control_reset_offsets(c); c->control_state = NULL; free(cs); From 27a00d1bfd1270d6d0f927d2ec5fc530301a5d91 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 May 2026 09:32:49 +0000 Subject: [PATCH 2/7] Fix infinite loop due to underflow when redrawing scrollbar, from Pavel Lavrukhin in GitHub issue 4932. --- screen-redraw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 3238c1f4..3adf85c3 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1108,11 +1108,17 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx, if (sb_x >= sx || sb_y >= sy) return; imax = sb_w + sb_pad; - if ((int)imax + sb_x > sx) + if ((int)imax + sb_x > sx) { + if (sb_x >= sx) + return; imax = sx - sb_x; + } jmax = sb_h; - if ((int)jmax + sb_y > sy) + if ((int)jmax + sb_y > sy) { + if (sb_y >= sy) + return; jmax = sy - sb_y; + } for (j = 0; j < jmax; j++) { py = sb_y + j; From 9e3653a6127269204b923d5f75fbb174add45ebe Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 May 2026 09:37:25 +0000 Subject: [PATCH 3/7] Check FIONREAD for all panes not just piped panes, fixes issues with tests, GitHub issue 4807. --- utf8-combined.c | 2 +- utf8.c | 2 +- window.c | 10 ++++------ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/utf8-combined.c b/utf8-combined.c index 1eee3b82..65ecf9cd 100644 --- a/utf8-combined.c +++ b/utf8-combined.c @@ -175,7 +175,7 @@ utf8_should_combine(const struct utf8_data *with, const struct utf8_data *add) return (1); break; } - return 0; + return (0); } static enum hanguljamo_subclass diff --git a/utf8.c b/utf8.c index 4df8ccd5..4d6ebcbd 100644 --- a/utf8.c +++ b/utf8.c @@ -590,7 +590,7 @@ utf8_towc(const struct utf8_data *ud, wchar_t *wc) case 0: return (UTF8_ERROR); } - log_debug("UTF-8 %.*s is %05X", (int)ud->size, ud->data, (u_int)*wc); + log_debug("UTF-8 %.*s is U+%06X", (int)ud->size, ud->data, (u_int)*wc); return (UTF8_DONE); } diff --git a/window.c b/window.c index a3b602fd..57f3c972 100644 --- a/window.c +++ b/window.c @@ -376,12 +376,10 @@ window_pane_destroy_ready(struct window_pane *wp) { int n; - if (wp->pipe_fd != -1) { - if (EVBUFFER_LENGTH(wp->pipe_event->output) != 0) - return (0); - if (ioctl(wp->fd, FIONREAD, &n) != -1 && n > 0) - return (0); - } + if (wp->pipe_fd != -1 && EVBUFFER_LENGTH(wp->pipe_event->output) != 0) + return (0); + if (ioctl(wp->fd, FIONREAD, &n) != -1 && n > 0) + return (0); if (~wp->flags & PANE_EXITED) return (0); From 3d6c542e3484e38ce9efdc233c1b3eb3d3daea86 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 May 2026 10:28:09 +0000 Subject: [PATCH 4/7] Turn off the "is this a paste" guessing if the terminal supports bracket pasting instead, GitHub issue 5031. --- server-client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-client.c b/server-client.c index ae12390c..e64ea259 100644 --- a/server-client.c +++ b/server-client.c @@ -1062,6 +1062,8 @@ server_client_is_assume_paste(struct client *c) return (0); if ((t = options_get_number(s->options, "assume-paste-time")) == 0) return (0); + if (tty_term_has(c->tty.term, TTYC_ENBP)) + return (0); timersub(&c->activity_time, &c->last_activity_time, &tv); if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) { From 18fced7e7f9d5362faf3fa79bb9671714ee82ac3 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 May 2026 12:05:41 +0000 Subject: [PATCH 5/7] Make pane offsets signed, needed for floating panes. --- cmd-display-panes.c | 8 +++--- cmd.c | 4 +-- screen-redraw.c | 69 ++++++++++++++++++++++++++------------------- server-client.c | 2 +- tmux.h | 34 +++++++++++----------- 5 files changed, 64 insertions(+), 53 deletions(-) diff --git a/cmd-display-panes.c b/cmd-display-panes.c index 25556f3d..cd688081 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -70,10 +70,10 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, char buf[16], lbuf[16], rbuf[16], *ptr; size_t len, llen, rlen; - if (wp->xoff + wp->sx <= ctx->ox || - wp->xoff >= ctx->ox + ctx->sx || - wp->yoff + wp->sy <= ctx->oy || - wp->yoff >= ctx->oy + ctx->sy) + if (wp->xoff + (int)wp->sx <= ctx->ox || + wp->xoff >= ctx->ox + (int)ctx->sx || + wp->yoff + (int)wp->sy <= ctx->oy || + wp->yoff >= ctx->oy + (int)ctx->sy) return; if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) { diff --git a/cmd.c b/cmd.c index 04a4caf0..cd64a3ea 100644 --- a/cmd.c +++ b/cmd.c @@ -775,9 +775,9 @@ cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp, if (m->statusat == 0 && y >= m->statuslines) y -= m->statuslines; - if (x < wp->xoff || x >= wp->xoff + wp->sx) + if ((int)x < wp->xoff || (int)x >= wp->xoff + (int)wp->sx) return (-1); - if (y < wp->yoff || y >= wp->yoff + wp->sy) + if ((int)y < wp->yoff || (int)y >= wp->yoff + (int)wp->sy) return (-1); if (xp != NULL) diff --git a/screen-redraw.c b/screen-redraw.c index 3adf85c3..c176c4a2 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -122,7 +122,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, u_int px, u_int py) { struct options *oo = wp->window->options; - u_int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy; + int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy; int hsplit = 0, vsplit = 0, pane_status = ctx->pane_status; int pane_scrollbars = ctx->pane_scrollbars, sb_w = 0; int sb_pos; @@ -133,7 +133,8 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, sb_pos = 0; /* Inside pane. */ - if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey) + if ((int)px >= wp->xoff && (int)px < ex && + (int)py >= wp->yoff && (int)py < ey) return (SCREEN_REDRAW_INSIDE); /* Get pane indicator. */ @@ -153,16 +154,17 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, * Left/right borders. The wp->sy / 2 test is to colour only half the * active window's border when there are two panes. */ - if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) { + if ((wp->yoff == 0 || (int)py >= wp->yoff - 1) && (int)py <= ey) { if (sb_pos == PANE_SCROLLBARS_LEFT) { if (wp->xoff - sb_w == 0 && px == wp->sx + sb_w) if (!hsplit || (hsplit && py <= wp->sy / 2)) return (SCREEN_REDRAW_BORDER_RIGHT); if (wp->xoff - sb_w != 0) { - if (px == wp->xoff - sb_w - 1 && + if ((int)px == wp->xoff - sb_w - 1 && (!hsplit || (hsplit && py > wp->sy / 2))) return (SCREEN_REDRAW_BORDER_LEFT); - if (px == wp->xoff + wp->sx + sb_w - 1) + if ((int)px == wp->xoff + + (int)wp->sx + sb_w - 1) return (SCREEN_REDRAW_BORDER_RIGHT); } } else { /* sb_pos == PANE_SCROLLBARS_RIGHT or disabled */ @@ -170,7 +172,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, if (!hsplit || (hsplit && py <= wp->sy / 2)) return (SCREEN_REDRAW_BORDER_RIGHT); if (wp->xoff != 0) { - if (px == wp->xoff - 1 && + if ((int)px == wp->xoff - 1 && (!hsplit || (hsplit && py > wp->sy / 2))) return (SCREEN_REDRAW_BORDER_LEFT); if (px == wp->xoff + wp->sx + sb_w) @@ -183,25 +185,29 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, if (vsplit && pane_status == PANE_STATUS_OFF && sb_w == 0) { if (wp->yoff == 0 && py == wp->sy && px <= wp->sx / 2) return (SCREEN_REDRAW_BORDER_BOTTOM); - if (wp->yoff != 0 && py == wp->yoff - 1 && px > wp->sx / 2) + if (wp->yoff != 0 && (int)py == wp->yoff - 1 && px > wp->sx / 2) return (SCREEN_REDRAW_BORDER_TOP); } else { if (sb_pos == PANE_SCROLLBARS_LEFT) { - if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) && - (px <= ex || (sb_w != 0 && px < ex + sb_w))) { - if (wp->yoff != 0 && py == wp->yoff - 1) + if ((wp->xoff - sb_w == 0 || + (int)px >= wp->xoff - sb_w) && + ((int)px <= ex || (sb_w != 0 && + (int)px < ex + sb_w))) { + if (wp->yoff != 0 && (int)py == wp->yoff - 1) return (SCREEN_REDRAW_BORDER_TOP); - if (py == ey) + if ((int)py == ey) return (SCREEN_REDRAW_BORDER_BOTTOM); } } else { /* sb_pos == PANE_SCROLLBARS_RIGHT */ - if ((wp->xoff == 0 || px >= wp->xoff) && - (px <= ex || (sb_w != 0 && px < ex + sb_w))) { + if ((wp->xoff == 0 || (int)px >= wp->xoff) && + ((int)px <= ex || + (sb_w != 0 && (int)px < ex + sb_w))) { if (pane_status != PANE_STATUS_BOTTOM && wp->yoff != 0 && - py == wp->yoff - 1) + (int)py == wp->yoff - 1) return (SCREEN_REDRAW_BORDER_TOP); - if (pane_status != PANE_STATUS_TOP && py == ey) + if (pane_status != PANE_STATUS_TOP && + (int)py == ey) return (SCREEN_REDRAW_BORDER_BOTTOM); } } @@ -364,7 +370,9 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py, line = wp->yoff + sy; right = wp->xoff + 2 + wp->status_size - 1; - if (py == line && px >= wp->xoff + 2 && px <= right) + if (py == line && + (int)px >= wp->xoff + 2 && + px <= right) return (CELL_INSIDE); next1: @@ -396,14 +404,14 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py, wp->scrollbar_style.pad; if ((pane_status && py != line) || (wp->yoff == 0 && py < wp->sy) || - (py >= wp->yoff && py < wp->yoff + wp->sy)) { + ((int)py >= wp->yoff && py < wp->yoff + wp->sy)) { /* Check if px lies within a scrollbar. */ if ((sb_pos == PANE_SCROLLBARS_RIGHT && - (px >= wp->xoff + wp->sx && - px < wp->xoff + wp->sx + sb_w)) || + (px >= wp->xoff + wp->sx && + px < wp->xoff + wp->sx + sb_w)) || (sb_pos == PANE_SCROLLBARS_LEFT && - (px >= wp->xoff - sb_w && - px < wp->xoff))) + ((int)px >= wp->xoff - sb_w && + (int)px < wp->xoff))) return (CELL_SCROLLBAR); } } @@ -521,7 +529,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx) struct tty *tty = &c->tty; struct window_pane *wp; struct screen *s; - u_int i, x, width, xoff, yoff, size; + u_int i, x, width, size; + int xoff, yoff; log_debug("%s: %s @%u", __func__, c->name, w->id); @@ -537,10 +546,10 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx) yoff = wp->yoff + wp->sy; xoff = wp->xoff + 2; - if (xoff + size <= ctx->ox || - xoff >= ctx->ox + ctx->sx || + if (xoff + (int)size <= ctx->ox || + xoff >= ctx->ox + (int)ctx->sx || yoff < ctx->oy || - yoff >= ctx->oy + ctx->sy) + yoff >= ctx->oy + (int)ctx->sy) continue; if (xoff >= ctx->ox && xoff + size <= ctx->ox + ctx->sx) { @@ -738,8 +747,8 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x, /* Draw arrow indicator if enabled. */ static void -screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, u_int i, - u_int j, u_int cell_type, struct window_pane *wp, +screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, int i, + int j, u_int cell_type, struct window_pane *wp, struct window_pane *active, struct grid_cell *gc) { struct client *c = ctx->c; @@ -957,14 +966,16 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id); - if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) + if (wp->xoff + (int)wp->sx <= ctx->ox || + wp->xoff >= (int)ctx->ox + (int)ctx->sx) return; if (ctx->statustop) top = ctx->statuslines; else top = 0; for (j = 0; j < wp->sy; j++) { - if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy) + if (wp->yoff + (int)j < ctx->oy || + wp->yoff + j >= ctx->oy + ctx->sy) continue; y = top + wp->yoff + j - ctx->oy; diff --git a/server-client.c b/server-client.c index e64ea259..8279f109 100644 --- a/server-client.c +++ b/server-client.c @@ -636,7 +636,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, if (((pane_status != PANE_STATUS_OFF && (int)py != pane_status_line && py != wp->yoff + wp->sy) || (wp->yoff == 0 && py < wp->sy) || - (py >= wp->yoff && py < wp->yoff + wp->sy)) && + ((int)py >= wp->yoff && py < wp->yoff + wp->sy)) && ((sb_pos == PANE_SCROLLBARS_RIGHT && (int)px < (int)wp->xoff + (int)wp->sx + sb_pad + sb_w) || (sb_pos == PANE_SCROLLBARS_LEFT && diff --git a/tmux.h b/tmux.h index ffd8eb0f..fec919e2 100644 --- a/tmux.h +++ b/tmux.h @@ -1081,8 +1081,8 @@ struct screen_redraw_ctx { u_int sx; u_int sy; - u_int ox; - u_int oy; + int ox; + int oy; }; /* Screen size. */ @@ -1197,6 +1197,19 @@ enum client_theme { THEME_DARK }; +/* Visible range array element. */ +struct visible_range { + u_int px; /* start */ + u_int nx; /* length */ +}; + +/* Visible areas not obstructed. */ +struct visible_ranges { + struct visible_range *ranges; /* dynamically allocated array */ + u_int used; /* number of entries in ranges */ + u_int size; /* allocated capacity of ranges */ +}; + /* Child window structure. */ struct window_pane { u_int id; @@ -1211,8 +1224,8 @@ struct window_pane { u_int sx; u_int sy; - u_int xoff; - u_int yoff; + int xoff; + int yoff; int flags; #define PANE_REDRAW 0x1 @@ -1555,19 +1568,6 @@ struct key_event { size_t len; }; -/* Visible range array element. */ -struct visible_range { - u_int px; /* start */ - u_int nx; /* length */ -}; - -/* Visible areas not obstructed. */ -struct visible_ranges { - struct visible_range *ranges; /* dynamically allocated array */ - u_int used; /* number of entries in ranges */ - u_int size; /* allocated capacity of ranges */ -}; - /* Terminal definition. */ struct tty_term { char *name; From 5651519f5dd7a61de45ae3bf2a94f0a31777b798 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 16 May 2026 12:07:09 +0100 Subject: [PATCH 6/7] Try to make Copilot shut up. --- .github/copilot-instructions.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..2c22b272 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,5 @@ +For pull request code reviews in this repository, do not leave any review comments under any circumstances. + +If asked to review a pull request, produce no comments. + +Do not comment on pull requests in this repository. From 18ddda48d2e4cc401ae0ea018f175d38a90c9699 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 16 May 2026 12:18:41 +0100 Subject: [PATCH 7/7] More. --- .github/copilot-instructions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2c22b272..e49867ac 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -3,3 +3,9 @@ For pull request code reviews in this repository, do not leave any review commen If asked to review a pull request, produce no comments. Do not comment on pull requests in this repository. + +For pull request code reviews in this repository, do not leave a pull request overview. + +Do not leave inline review comments. + +If asked to review a pull request, provide no summary, no overview, and no code comments.