From 00c59041ea20faacc62fb2766f12f665b07e04cd Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 May 2026 11:54:28 +0000 Subject: [PATCH 1/3] Bring in some more floating panes changes - obscured panes need to be handled specially in screen_write_* rather than dropping into the client redraw (tty.c). --- screen-write.c | 259 ++++++++++++++++++++++++++++++++++--------------- tty.c | 16 +-- 2 files changed, 191 insertions(+), 84 deletions(-) diff --git a/screen-write.c b/screen-write.c index c9a3fad7..f23a47d2 100644 --- a/screen-write.c +++ b/screen-write.c @@ -176,11 +176,10 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c) static int screen_write_pane_is_obscured(struct screen_write_ctx *ctx) { - struct window_pane *wp = ctx->wp; - - if (ctx->wp == NULL) - return (0); + struct window_pane *wp = ctx->wp; + if (ctx->wp == NULL) + return (0); if (ctx->flags & SCREEN_WRITE_CHECKED_IF_OBSCURED) { if (ctx->flags & SCREEN_WRITE_OBSCURED) return (1); @@ -188,21 +187,21 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx) } ctx->flags |= SCREEN_WRITE_CHECKED_IF_OBSCURED; - while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) { - if ((wp->flags & PANE_FLOATING) && - ((wp->yoff >= ctx->wp->yoff && - wp->yoff <= ctx->wp->yoff + (int)ctx->wp->sy) || - (wp->yoff + (int)wp->sy >= ctx->wp->yoff && - wp->yoff + wp->sy <= ctx->wp->yoff + ctx->wp->sy)) && - ((wp->xoff >= ctx->wp->xoff && - wp->xoff <= ctx->wp->xoff + (int)ctx->wp->sx) || - (wp->xoff + (int)wp->sx >= ctx->wp->xoff && - wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) { + while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) { + if ((wp->flags & PANE_FLOATING) && + ((wp->yoff >= ctx->wp->yoff && + wp->yoff <= ctx->wp->yoff + (int)ctx->wp->sy) || + (wp->yoff + (int)wp->sy >= ctx->wp->yoff && + wp->yoff + wp->sy <= ctx->wp->yoff + ctx->wp->sy)) && + ((wp->xoff >= ctx->wp->xoff && + wp->xoff <= ctx->wp->xoff + (int)ctx->wp->sx) || + (wp->xoff + (int)wp->sx >= ctx->wp->xoff && + wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) { ctx->flags |= SCREEN_WRITE_OBSCURED; - return (1); + return (1); } - } - return (0); + } + return (0); } /* Set up context for TTY command. */ @@ -394,9 +393,9 @@ size_t screen_write_strlen(const char *fmt, ...) { va_list ap; - char *msg; + char *msg; struct utf8_data ud; - u_char *ptr; + u_char *ptr; size_t left, size = 0; enum utf8_state more; @@ -549,9 +548,9 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, { struct grid_cell gc; struct utf8_data *ud = &gc.data; - char *msg; - u_char *ptr; - size_t left, size = 0; + char *msg; + u_char *ptr; + size_t left, size = 0; enum utf8_state more; memcpy(&gc, gcp, sizeof gc); @@ -610,11 +609,11 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, { struct screen *s = ctx->s; struct window_pane *wp = ctx->wp; - struct tty_ctx ttyctx; + struct tty_ctx ttyctx; struct grid *gd = src->grid; struct grid_line *gl, *sgl; struct grid_cell gc; - u_int xx, yy, cx = s->cx, cy = s->cy; + u_int xx, yy, cx = s->cx, cy = s->cy; if (nx == 0 || ny == 0) return; @@ -657,28 +656,28 @@ screen_write_box_border_set(enum box_lines lines, int cell_type, struct grid_cell *gc) { switch (lines) { - case BOX_LINES_NONE: + case BOX_LINES_NONE: break; - case BOX_LINES_DOUBLE: - gc->attr &= ~GRID_ATTR_CHARSET; - utf8_copy(&gc->data, tty_acs_double_borders(cell_type)); + case BOX_LINES_DOUBLE: + gc->attr &= ~GRID_ATTR_CHARSET; + utf8_copy(&gc->data, tty_acs_double_borders(cell_type)); break; - case BOX_LINES_HEAVY: - gc->attr &= ~GRID_ATTR_CHARSET; - utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type)); + case BOX_LINES_HEAVY: + gc->attr &= ~GRID_ATTR_CHARSET; + utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type)); break; - case BOX_LINES_ROUNDED: - gc->attr &= ~GRID_ATTR_CHARSET; - utf8_copy(&gc->data, tty_acs_rounded_borders(cell_type)); + case BOX_LINES_ROUNDED: + gc->attr &= ~GRID_ATTR_CHARSET; + utf8_copy(&gc->data, tty_acs_rounded_borders(cell_type)); + break; + case BOX_LINES_SIMPLE: + gc->attr &= ~GRID_ATTR_CHARSET; + utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]); + break; + case BOX_LINES_PADDED: + gc->attr &= ~GRID_ATTR_CHARSET; + utf8_set(&gc->data, PADDED_BORDERS[cell_type]); break; - case BOX_LINES_SIMPLE: - gc->attr &= ~GRID_ATTR_CHARSET; - utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]); - break; - case BOX_LINES_PADDED: - gc->attr &= ~GRID_ATTR_CHARSET; - utf8_set(&gc->data, PADDED_BORDERS[cell_type]); - break; case BOX_LINES_SINGLE: case BOX_LINES_DEFAULT: gc->attr |= GRID_ATTR_CHARSET; @@ -806,7 +805,7 @@ screen_write_box(struct screen_write_ctx *ctx, u_int nx, u_int ny, enum box_lines lines, const struct grid_cell *gcp, const char *title) { struct screen *s = ctx->s; - struct grid_cell gc; + struct grid_cell gc; u_int cx, cy, i; cx = s->cx; @@ -1105,13 +1104,54 @@ screen_write_backspace(struct screen_write_ctx *ctx) screen_write_set_cursor(ctx, cx, cy); } +/* Redraw all visible cells on a line. */ +static void +screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, + u_int yy) +{ + struct window_pane *wp = ctx->wp; + struct screen *s = ctx->s; + struct grid_cell gc; + u_int sx = screen_size_x(s),cx, i, n; + u_int xoff = wp->xoff, yoff = wp->yoff; + struct visible_ranges *r; + struct visible_range *ri; + + r = screen_redraw_get_visible_ranges(wp, xoff, yoff + yy, sx, NULL); + for (i = 0; i < r->used; i++) { + ri = &r->ranges[i]; + if (ri->nx == 0) + continue; + + cx = ri->px - xoff; + for (n = 0; n < ri->nx && cx < sx; n++, cx++) { + grid_view_get_cell(s->grid, cx, yy, &gc); + ttyctx->ocx = cx; + ttyctx->ocy = yy; + ttyctx->cell = &gc; + tty_write(tty_cmd_cell, ttyctx); + } + } +} + +/* Redraw all visible cells in a pane. */ +static void +screen_write_redraw_pane(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) +{ + struct screen *s = ctx->s; + u_int yy; + + for (yy = 0; yy < screen_size_y(s); yy++) + screen_write_redraw_line(ctx, ttyctx, yy); +} + /* VT100 alignment test. */ void screen_write_alignmenttest(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - struct tty_ctx ttyctx; - struct grid_cell gc; + struct tty_ctx ttyctx; + struct grid_cell gc; u_int xx, yy; memcpy(&gc, &grid_default_cell, sizeof gc); @@ -1127,10 +1167,16 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) s->rupper = 0; s->rlower = screen_size_y(s) - 1; + screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); - screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1); - tty_write(tty_cmd_alignmenttest, &ttyctx); + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_alignmenttest, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); } /* Insert nx characters. */ @@ -1158,7 +1204,13 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = nx; - tty_write(tty_cmd_insertcharacter, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_insertcharacter, &ttyctx); + return; + } + + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Delete nx characters. */ @@ -1186,7 +1238,13 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = nx; - tty_write(tty_cmd_deletecharacter, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_deletecharacter, &ttyctx); + return; + } + + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Clear nx characters. */ @@ -1207,14 +1265,20 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) if (s->cx > screen_size_x(s) - 1) return; - screen_write_initctx(ctx, &ttyctx, 0, 0); + screen_write_initctx(ctx, &ttyctx, 0, 1); ttyctx.bg = bg; grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg); screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = nx; - tty_write(tty_cmd_clearcharacter, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_clearcharacter, &ttyctx); + return; + } + + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Insert ny lines. */ @@ -1224,13 +1288,14 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) struct screen *s = ctx->s; struct grid *gd = s->grid; struct tty_ctx ttyctx; + u_int sy = screen_size_y(s); if (ny == 0) ny = 1; if (s->cy < s->rupper || s->cy > s->rlower) { - if (ny > screen_size_y(s) - s->cy) - ny = screen_size_y(s) - s->cy; + if (ny > sy - s->cy) + ny = sy - s->cy; if (ny == 0) return; @@ -1241,7 +1306,13 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = ny; - tty_write(tty_cmd_insertline, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_insertline, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); return; } @@ -1259,9 +1330,14 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) grid_view_insert_lines_region(gd, s->rlower, s->cy, ny, bg); screen_write_collect_flush(ctx, 0, __func__); - ttyctx.n = ny; - tty_write(tty_cmd_insertline, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_insertline, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); } /* Delete ny lines. */ @@ -1289,7 +1365,13 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = ny; - tty_write(tty_cmd_deleteline, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_deleteline, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); return; } @@ -1308,7 +1390,13 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = ny; - tty_write(tty_cmd_deleteline, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_deleteline, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); } /* Clear line at cursor. */ @@ -1418,17 +1506,20 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg) struct tty_ctx ttyctx; if (s->cy == s->rupper) { - grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg); screen_write_collect_flush(ctx, 0, __func__); - screen_write_initctx(ctx, &ttyctx, 1, 0); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - tty_write(tty_cmd_reverseindex, &ttyctx); + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_reverseindex, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); } else if (s->cy > 0) screen_write_set_cursor(ctx, -1, s->cy - 1); - } /* Set scroll region. */ @@ -1530,7 +1621,13 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) screen_write_collect_flush(ctx, 0, __func__); ttyctx.n = lines; - tty_write(tty_cmd_scrolldown, &ttyctx); + + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { + tty_write(tty_cmd_scrolldown, &ttyctx); + return; + } + + screen_write_redraw_pane(ctx, &ttyctx); } /* Carriage return (cursor to start of line). */ @@ -1770,36 +1867,34 @@ static void screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, const char *from) { + struct window_pane *wp = ctx->wp; struct screen *s = ctx->s; struct screen_write_citem *ci, *tmp; struct screen_write_cline *cl; u_int y, cx, cy, last, items = 0; struct tty_ctx ttyctx; - if (s->mode & MODE_SYNC) { - for (y = 0; y < screen_size_y(s); y++) { - cl = &ctx->s->write_list[y]; - TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { - TAILQ_REMOVE(&cl->items, ci, entry); - screen_write_free_citem(ci); - } - } - return; - } + if (s->mode & MODE_SYNC) + goto discard; if (ctx->scrolled != 0) { + screen_write_initctx(ctx, &ttyctx, 1, 1); + if (ttyctx.flags & TTY_CTX_PANE_OBSCURED && wp != NULL) { + screen_write_redraw_pane(ctx, &ttyctx); + goto discard; + } + log_debug("%s: scrolled %u (region %u-%u)", __func__, ctx->scrolled, s->rupper, s->rlower); if (ctx->scrolled > s->rlower - s->rupper + 1) ctx->scrolled = s->rlower - s->rupper + 1; - screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.n = ctx->scrolled; ttyctx.bg = ctx->bg; tty_write(tty_cmd_scrollup, &ttyctx); - if (ctx->wp != NULL) - ctx->wp->flags |= PANE_REDRAWSCROLLBAR; + if (wp != NULL) + wp->flags |= PANE_REDRAWSCROLLBAR; } ctx->scrolled = 0; ctx->bg = 8; @@ -1843,6 +1938,18 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, s->cx = cx; s->cy = cy; log_debug("%s: flushed %u items (%s)", __func__, items, from); + return; + +discard: + for (y = 0; y < screen_size_y(s); y++) { + cl = &ctx->s->write_list[y]; + TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { + TAILQ_REMOVE(&cl->items, ci, entry); + screen_write_free_citem(ci); + } + } + ctx->scrolled = 0; + ctx->bg = 8; } /* Insert an item on current line. */ diff --git a/tty.c b/tty.c index 9746d6b7..4fab57ae 100644 --- a/tty.c +++ b/tty.c @@ -1559,7 +1559,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED)) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_ICH) && @@ -1582,7 +1582,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_DCH) && @@ -1614,7 +1614,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED)) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1642,7 +1642,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1702,7 +1702,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orupper) return; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1777,7 +1777,7 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) struct client *c = tty->client; u_int i; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1816,7 +1816,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) u_int i; struct client *c = tty->client; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1919,7 +1919,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) struct client *c = tty->client; u_int i, j; - if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || c->overlay_check != NULL) { ctx->redraw_cb(ctx); return; From bff68fa0798ea0302bc99b543b992beb3203d29d Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 May 2026 12:52:47 +0000 Subject: [PATCH 2/3] Remove reference to an option that hasn't been added yet. --- screen-redraw.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 6a795527..45760f86 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -614,8 +614,10 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp, else width = wp->sx + sb_w - 2; max_width = (int)w->sx - (wp->xoff + 2) - sb_w; - if (max_width < 0) max_width = 0; - if (width > (u_int)max_width) width = (u_int)max_width; + if (max_width < 0) + max_width = 0; + if (width > (u_int)max_width) + width = (u_int)max_width; wp->status_size = width; memcpy(&old, &wp->status_screen, sizeof old); @@ -873,7 +875,7 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x, struct window *w = s->curw->window; struct window_pane *active = server_client_get_pane(c); struct options *wo = w->options; - const char *border_opt; + const char *border_option; struct format_tree *ft; if (wp->border_gc_set) @@ -882,19 +884,13 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x, ft = format_create_defaults(NULL, c, s, s->curw, wp); - border_opt = screen_redraw_check_is(ctx, x, y, active) ? - "pane-active-border-style" : "pane-border-style"; - - /* Window-level baseline. */ - style_apply(&wp->border_gc, wo, border_opt, ft); - - /* Floating pane window default overrides window baseline. */ - if (wp->flags & PANE_FLOATING) - style_add(&wp->border_gc, wo, "floating-pane-border-style", ft); - - /* Per-pane override (set via new-pane -S or set-option -p). */ - if (options_get_only(wp->options, border_opt) != NULL) - style_add(&wp->border_gc, wp->options, border_opt, ft); + if (screen_redraw_check_is(ctx, x, y, active)) + border_option = "pane-active-border-style"; + else + border_option = "pane-border-style"; + style_apply(&wp->border_gc, wo, border_option, ft); + if (options_get_only(wp->options, border_option) != NULL) + style_add(&wp->border_gc, wp->options, border_option, ft); format_free(ft); return (&wp->border_gc); From 9cc8947a43f1e7aab61eb9dfa7e5b6cab2d211fc Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 May 2026 13:41:20 +0000 Subject: [PATCH 3/3] Cache border and active border style separately, fixes problem reported by Marcel Partap in GitHub issue 5125. --- screen-redraw.c | 53 ++++++++++++++++++++++++++----------------------- tmux.h | 2 ++ 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 45760f86..b12fa510 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -866,34 +866,40 @@ screen_redraw_pane(struct client *c, struct window_pane *wp, } /* Get border cell style. */ -static const struct grid_cell * +static void screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x, - u_int y, struct window_pane *wp) + u_int y, struct window_pane *wp, struct grid_cell *ngc) { struct client *c = ctx->c; struct session *s = c->session; struct window *w = s->curw->window; struct window_pane *active = server_client_get_pane(c); - struct options *wo = w->options; + struct grid_cell *gc; const char *border_option; struct format_tree *ft; + int *flag; - if (wp->border_gc_set) - return (&wp->border_gc); - wp->border_gc_set = 1; - - ft = format_create_defaults(NULL, c, s, s->curw, wp); - - if (screen_redraw_check_is(ctx, x, y, active)) + if (screen_redraw_check_is(ctx, x, y, active)) { + flag = &wp->active_border_gc_set; + gc = &wp->active_border_gc; border_option = "pane-active-border-style"; - else + } else { + flag = &wp->border_gc_set; + gc = &wp->border_gc; border_option = "pane-border-style"; - style_apply(&wp->border_gc, wo, border_option, ft); - if (options_get_only(wp->options, border_option) != NULL) - style_add(&wp->border_gc, wp->options, border_option, ft); + } - format_free(ft); - return (&wp->border_gc); + if (!*flag) { + ft = format_create_defaults(NULL, c, s, s->curw, wp); + + style_apply(gc, w->options, border_option, ft); + if (options_get_only(wp->options, border_option) != NULL) + style_add(gc, wp->options, border_option, ft); + + format_free(ft); + *flag = 1; + } + memcpy(ngc, gc, sizeof *ngc); } /* Draw arrow indicator if enabled. */ @@ -981,7 +987,6 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) struct format_tree *ft; struct window_pane *wp, *active = server_client_get_pane(c); struct grid_cell gc; - const struct grid_cell *tmp; u_int cell_type; u_int x = ctx->ox + i, y = ctx->oy + j; int isolates; @@ -1008,11 +1013,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) } memcpy(&gc, &ctx->no_pane_gc, sizeof gc); } else { - tmp = screen_redraw_draw_borders_style(ctx, x, y, wp); - if (tmp == NULL) - return; - memcpy(&gc, tmp, sizeof gc); - + screen_redraw_draw_borders_style(ctx, x, y, wp, &gc); if (server_is_marked(s, s->curw, marked_pane.wp) && screen_redraw_check_is(ctx, x, y, marked_pane.wp)) gc.attr ^= GRID_ATTR_REVERSE; @@ -1052,8 +1053,10 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx) log_debug("%s: %s @%u", __func__, c->name, w->id); - TAILQ_FOREACH(wp, &w->panes, entry) + TAILQ_FOREACH(wp, &w->panes, entry) { wp->border_gc_set = 0; + wp->active_border_gc_set = 0; + } for (j = 0; j < c->tty.sy - ctx->statuslines; j++) { for (i = 0; i < c->tty.sx; i++) @@ -1318,7 +1321,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) if (wp->yoff + (int)j < (int)ctx->oy || wp->yoff + (int)j >= (int)ctx->oy + (int)ctx->sy) continue; - wy = wp->yoff + j; /* y line within window w */ + wy = wp->yoff + j; /* y line within window w */ py = woy + wy - ctx->oy; /* y line within tty */ if (py > tty->sy) { /* Continue if this line is off of tty. */ @@ -1391,7 +1394,7 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx, int sb_w = wp->scrollbar_style.width; int sb_pad = wp->scrollbar_style.pad; int cm_y, cm_size, xoff = wp->xoff; - int sb_x, sb_y = (int)(wp->yoff); /* sb top */ + int sb_x, sb_y = (int)wp->yoff; /* sb top */ if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) { if (sb == PANE_SCROLLBARS_MODAL) diff --git a/tmux.h b/tmux.h index c20286c2..609e8e7c 100644 --- a/tmux.h +++ b/tmux.h @@ -1296,6 +1296,8 @@ struct window_pane { int border_gc_set; struct grid_cell border_gc; + int active_border_gc_set; + struct grid_cell active_border_gc; int control_bg; int control_fg;