From 57b18d8a18243f71348a8fa12b9e3ff881b45387 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 26 May 2026 11:20:28 +0100 Subject: [PATCH] Move redraw of overlapped panes into common functions. --- screen-write.c | 351 +++++++++++-------------------------------------- tmux.h | 1 + tty.c | 16 +-- 3 files changed, 87 insertions(+), 281 deletions(-) diff --git a/screen-write.c b/screen-write.c index 36bbcb28..dabdf58b 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1111,6 +1111,48 @@ 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, s->cy, &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) @@ -1118,9 +1160,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) struct screen *s = ctx->s; struct tty_ctx ttyctx; struct grid_cell gc; - u_int xx, yy, sx, xoff, yoff, cx, i, n; - struct visible_ranges *r; - struct visible_range *ri; + u_int xx, yy; memcpy(&gc, &grid_default_cell, sizeof gc); utf8_set(&gc.data, 'E'); @@ -1140,48 +1180,24 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) s->rupper = 0; s->rlower = screen_size_y(s) - 1; - screen_write_initctx(ctx, &ttyctx, 1, 1); - screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { tty_write(tty_cmd_alignmenttest, &ttyctx); return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (yy = 0; yy < screen_size_y(s); yy++) { - r = screen_redraw_get_visible_ranges(ctx->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++) { - ttyctx.ocx = cx; - ttyctx.ocy = yy; - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); } /* Insert nx characters. */ void screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) { - struct screen *s = ctx->s; - struct tty_ctx ttyctx; - u_int sx, xoff, yoff, cx, n, i; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; + struct screen *s = ctx->s; + struct tty_ctx ttyctx; if (nx == 0) nx = 1; @@ -1212,38 +1228,15 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) return; } - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - sx = screen_size_x(s); - - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff + s->cx, yoff + s->cy, sx - s->cx, 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, s->cy, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Delete nx characters. */ void screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) { - struct screen *s = ctx->s; - struct tty_ctx ttyctx; - u_int sx, xoff, yoff, cx, n, i; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; + struct screen *s = ctx->s; + struct tty_ctx ttyctx; if (nx == 0) nx = 1; @@ -1274,38 +1267,15 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) return; } - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - sx = screen_size_x(s); - - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff + s->cx, yoff + s->cy, sx - s->cx, 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, s->cy, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Clear nx characters. */ void screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) { - struct screen *s = ctx->s; - struct tty_ctx ttyctx; - u_int sx, xoff, yoff, cx, n, i; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; + struct screen *s = ctx->s; + struct tty_ctx ttyctx; if (nx == 0) nx = 1; @@ -1336,45 +1306,17 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) return; } - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - sx = screen_size_x(s); - - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff + s->cx, yoff + s->cy, sx - s->cx, 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, s->cy, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } + screen_write_redraw_line(ctx, &ttyctx, s->cy); } /* Insert ny lines. */ void 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 sx, sy, xoff, yoff, y, cx, i, n; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; - -#ifdef ENABLE_SIXEL - sy = screen_size_y(s); -#else - sy = screen_size_y(s); -#endif + 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; @@ -1385,8 +1327,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) #endif 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; @@ -1403,28 +1345,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (y = s->cy; y < sy; y++) { - screen_write_set_cursor(ctx, 0, y); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + y, 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(gd, cx, y, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); return; } @@ -1442,7 +1363,6 @@ 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; if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { @@ -1450,43 +1370,17 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (y = s->cy; y <= s->rlower; y++) { - screen_write_set_cursor(ctx, 0, y); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + y, 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(gd, cx, y, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); } /* Delete ny lines. */ void screen_write_deleteline(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 sx, sy, xoff, yoff, y, cx, i, n; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; - - sy = screen_size_y(s); + 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; @@ -1515,28 +1409,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (y = s->cy; y < sy; y++) { - screen_write_set_cursor(ctx, 0, y); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + y, 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(gd, cx, y, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); return; } @@ -1561,28 +1434,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (y = s->cy; y <= s->rlower; y++) { - screen_write_set_cursor(ctx, 0, y); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + y, 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(gd, cx, y, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); } /* Clear line at cursor. */ @@ -1720,12 +1572,8 @@ screen_write_cursormove(struct screen_write_ctx *ctx, int px, int py, void screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg) { - struct screen *s = ctx->s; - struct tty_ctx ttyctx; - u_int sx, xoff, yoff, cx, i, n; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; + struct screen *s = ctx->s; + struct tty_ctx ttyctx; if (s->cy == s->rupper) { #ifdef ENABLE_SIXEL @@ -1736,7 +1584,7 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg) 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; if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { @@ -1744,26 +1592,7 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - screen_write_set_cursor(ctx, 0, s->rupper); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + s->rupper, 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, s->rupper, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } + screen_write_redraw_pane(ctx, &ttyctx); } else if (s->cy > 0) screen_write_set_cursor(ctx, -1, s->cy - 1); } @@ -1865,13 +1694,10 @@ screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines, u_int bg) void screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) { - struct screen *s = ctx->s; - struct grid *gd = s->grid; - struct tty_ctx ttyctx; - u_int sx, xoff, yoff, y, cx, i, n; - struct visible_ranges *r; - struct visible_range *ri; - struct grid_cell gc; + struct screen *s = ctx->s; + struct grid *gd = s->grid; + struct tty_ctx ttyctx; + u_int i; screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; @@ -1897,28 +1723,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) return; } - sx = screen_size_x(s); - xoff = ctx->wp->xoff; - yoff = ctx->wp->yoff; - - for (y = s->rupper; y <= s->rlower; y++) { - screen_write_set_cursor(ctx, 0, y); - r = screen_redraw_get_visible_ranges(ctx->wp, - xoff, yoff + y, 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(gd, cx, y, &gc); - screen_write_set_cursor(ctx, cx, -1); - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - } - } - } + screen_write_redraw_pane(ctx, &ttyctx); } /* Carriage return (cursor to start of line). */ diff --git a/tmux.h b/tmux.h index 21afb60c..75cc6658 100644 --- a/tmux.h +++ b/tmux.h @@ -1264,6 +1264,7 @@ struct window_pane { int yoff; int flags; + int saved_flags; #define PANE_REDRAW 0x1 #define PANE_DROP 0x2 #define PANE_FOCUSED 0x4 diff --git a/tty.c b/tty.c index 0b5ae135..761bd27c 100644 --- a/tty.c +++ b/tty.c @@ -1661,7 +1661,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) && @@ -1684,7 +1684,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) && @@ -1716,7 +1716,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) || @@ -1744,7 +1744,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) || @@ -1804,7 +1804,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) || @@ -1879,7 +1879,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) || @@ -1918,7 +1918,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) || @@ -2021,7 +2021,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;