From e5abcd217c79c417fcb6672bf2ea971f4357ec70 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 22 May 2026 08:58:48 +0100 Subject: [PATCH 1/5] Start at the current pane in the zindex list for working out if a pane is obscured. --- screen-write.c | 74 ++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/screen-write.c b/screen-write.c index 6e081fe6..b0c79b79 100644 --- a/screen-write.c +++ b/screen-write.c @@ -36,7 +36,7 @@ static int screen_write_overwrite(struct screen_write_ctx *, struct grid_cell *, u_int); static int screen_write_combine(struct screen_write_ctx *, const struct grid_cell *); -static int screen_write_pane_obscured(struct window_pane *); +static int screen_write_pane_is_obscured(struct window_pane *); struct screen_write_citem { u_int x; @@ -604,7 +604,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, break; grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc); if (wp != NULL) { - if (! screen_redraw_is_visible(r, px)) + if (!screen_redraw_is_visible(r, px)) break; ttyctx.cell = &gc; tty_write(tty_cmd_cell, &ttyctx); @@ -1131,7 +1131,7 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_initctx(ctx, &ttyctx, 0); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1165,7 +1165,7 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_initctx(ctx, &ttyctx, 0); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1235,7 +1235,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); grid_view_insert_lines(gd, s->cy, ny, bg); @@ -1252,7 +1252,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); @@ -1292,7 +1292,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); grid_view_delete_lines(gd, s->cy, ny, bg); @@ -1309,7 +1309,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); @@ -1583,7 +1583,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); if (lines == 0) lines = 1; @@ -1646,7 +1646,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1)); screen_write_collect_flush(ctx, 0, __func__); - if (! screen_write_pane_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx->wp)) { tty_write(tty_cmd_clearendofscreen, &ttyctx); return; } @@ -1722,7 +1722,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, s->cy); screen_write_collect_flush(ctx, 0, __func__); - if (! screen_write_pane_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx->wp)) { tty_write(tty_cmd_clearstartofscreen, &ttyctx); return; } @@ -1796,7 +1796,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, sy); - if (! screen_write_pane_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx->wp)) { tty_write(tty_cmd_clearscreen, &ttyctx); return; } @@ -1983,39 +1983,25 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg) /* Return 1 if there is a floating window pane overlapping this pane. */ static int -screen_write_pane_obscured(struct window_pane *base_wp) +screen_write_pane_is_obscured(struct window_pane *base_wp) { - struct window_pane *wp; - struct window *w; - int found_self = 0; + struct window_pane *wp = base_wp; - if (base_wp == NULL) - return(0); - w = base_wp->window; - - TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) { - if (wp == base_wp) { - found_self = 1; - continue; - } - if (found_self && wp->flags & PANE_FLOATING && - ! (wp->flags & PANE_HIDDEN) && - ((wp->yoff >= base_wp->yoff && - wp->yoff <= base_wp->yoff + (int)base_wp->sy) || - (wp->yoff + (int)wp->sy >= base_wp->yoff && - wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) && - ((wp->xoff >= base_wp->xoff && - wp->xoff <= base_wp->xoff + (int)base_wp->sx) || - (wp->xoff + (int)wp->sx >= base_wp->xoff && - wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx))) { - log_debug("%s: base %%%u obscured by %%%u " - "(xoff=%u sx=%u vs base xoff=%u sx=%u)", __func__, - base_wp->id, wp->id, - wp->xoff, wp->sx, base_wp->xoff, base_wp->sx); - return (1); - } - } - return (0); + if (base_wp == NULL) + return (0); + while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) { + if ((wp->flags & PANE_FLOATING) && + ((wp->yoff >= base_wp->yoff && + wp->yoff <= base_wp->yoff + (int)base_wp->sy) || + (wp->yoff + (int)wp->sy >= base_wp->yoff && + wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) && + ((wp->xoff >= base_wp->xoff && + wp->xoff <= base_wp->xoff + (int)base_wp->sx) || + (wp->xoff + (int)wp->sx >= base_wp->xoff && + wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx))) + return (1); + } + return (0); } /* Flush collected lines. */ @@ -2058,7 +2044,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); ttyctx.num = ctx->scrolled; ttyctx.bg = ctx->bg; - ttyctx.obscured = screen_write_pane_obscured(wp); + ttyctx.obscured = screen_write_pane_is_obscured(wp); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, wp != NULL ? wp->id : 0); tty_write(tty_cmd_scrollup, &ttyctx); From 52ad3c8425e24bf693c63c773c3bffadc1845a5c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 22 May 2026 09:03:51 +0100 Subject: [PATCH 2/5] Change pane_is_obscured to take the context since it always uses its pane. --- screen-write.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/screen-write.c b/screen-write.c index b0c79b79..f955c07c 100644 --- a/screen-write.c +++ b/screen-write.c @@ -36,7 +36,7 @@ static int screen_write_overwrite(struct screen_write_ctx *, struct grid_cell *, u_int); static int screen_write_combine(struct screen_write_ctx *, const struct grid_cell *); -static int screen_write_pane_is_obscured(struct window_pane *); +static int screen_write_pane_is_obscured(struct screen_write_ctx *); struct screen_write_citem { u_int x; @@ -1131,7 +1131,7 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_initctx(ctx, &ttyctx, 0); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1165,7 +1165,7 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) screen_write_initctx(ctx, &ttyctx, 0); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1235,7 +1235,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_insert_lines(gd, s->cy, ny, bg); @@ -1252,7 +1252,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); @@ -1292,7 +1292,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_delete_lines(gd, s->cy, ny, bg); @@ -1309,7 +1309,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); @@ -1583,7 +1583,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx->wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); if (lines == 0) lines = 1; @@ -1646,7 +1646,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1)); screen_write_collect_flush(ctx, 0, __func__); - if (!screen_write_pane_is_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx)) { tty_write(tty_cmd_clearendofscreen, &ttyctx); return; } @@ -1722,7 +1722,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, s->cy); screen_write_collect_flush(ctx, 0, __func__); - if (!screen_write_pane_is_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx)) { tty_write(tty_cmd_clearstartofscreen, &ttyctx); return; } @@ -1796,7 +1796,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, sy); - if (!screen_write_pane_is_obscured(ctx->wp)) { + if (!screen_write_pane_is_obscured(ctx)) { tty_write(tty_cmd_clearscreen, &ttyctx); return; } @@ -1983,22 +1983,22 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg) /* Return 1 if there is a floating window pane overlapping this pane. */ static int -screen_write_pane_is_obscured(struct window_pane *base_wp) +screen_write_pane_is_obscured(struct screen_write_ctx *ctx) { - struct window_pane *wp = base_wp; + struct window_pane *wp = ctx->wp; - if (base_wp == NULL) + if (ctx->wp == NULL) return (0); while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) { if ((wp->flags & PANE_FLOATING) && - ((wp->yoff >= base_wp->yoff && - wp->yoff <= base_wp->yoff + (int)base_wp->sy) || - (wp->yoff + (int)wp->sy >= base_wp->yoff && - wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) && - ((wp->xoff >= base_wp->xoff && - wp->xoff <= base_wp->xoff + (int)base_wp->sx) || - (wp->xoff + (int)wp->sx >= base_wp->xoff && - wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx))) + ((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))) return (1); } return (0); @@ -2044,7 +2044,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); ttyctx.num = ctx->scrolled; ttyctx.bg = ctx->bg; - ttyctx.obscured = screen_write_pane_is_obscured(wp); + ttyctx.obscured = screen_write_pane_is_obscured(ctx); log_debug("%s: obscured=%d for pane %%%u", __func__, ttyctx.obscured, wp != NULL ? wp->id : 0); tty_write(tty_cmd_scrollup, &ttyctx); From 8fa822207df9066174c749fff962bb88fecd5ff9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 22 May 2026 09:07:38 +0100 Subject: [PATCH 3/5] Cache obscure flag in screen_write_ctx. --- screen-write.c | 12 +++++++++++- tmux.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/screen-write.c b/screen-write.c index f955c07c..e83767a2 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1989,6 +1989,14 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx) if (ctx->wp == NULL) return (0); + + if (ctx->flags & SCREEN_WRITE_CHECKED_IF_OBSCURED) { + if (ctx->flags & SCREEN_WRITE_OBSCURED) + return (1); + return (0); + } + 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 && @@ -1998,8 +2006,10 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx) ((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))) + wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) { + ctx->flags |= SCREEN_WRITE_OBSCURED; return (1); + } } return (0); } diff --git a/tmux.h b/tmux.h index 49cf3847..c8864496 100644 --- a/tmux.h +++ b/tmux.h @@ -1055,6 +1055,8 @@ struct screen_write_ctx { int flags; #define SCREEN_WRITE_SYNC 0x1 +#define SCREEN_WRITE_OBSCURED 0x2 +#define SCREEN_WRITE_CHECKED_IF_OBSCURED 0x4 screen_write_init_ctx_cb init_ctx_cb; void *arg; From d5ee330d20176fd127e3f7b9d14126771487cee7 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 22 May 2026 09:05:16 +0000 Subject: [PATCH 4/5] Tidy up a load of different flags and special values in the tty_ctx into a single bitmask. --- popup.c | 2 +- screen-write.c | 55 +++++++++++++++++++++++++---------------- tmux.h | 23 +++++++++-------- tty.c | 67 ++++++++++++++++++++++++++------------------------ 4 files changed, 81 insertions(+), 66 deletions(-) diff --git a/popup.c b/popup.c index c31977ba..7c29af62 100644 --- a/popup.c +++ b/popup.c @@ -186,7 +186,6 @@ popup_set_client_cb(struct tty_ctx *ttyctx, struct client *c) if (pd->c->flags & CLIENT_REDRAWOVERLAY) return (0); - ttyctx->bigger = 0; ttyctx->wox = 0; ttyctx->woy = 0; ttyctx->wsx = c->tty.sx; @@ -209,6 +208,7 @@ popup_init_ctx_cb(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) struct popup_data *pd = ctx->arg; memcpy(&ttyctx->defaults, &pd->defaults, sizeof ttyctx->defaults); + ttyctx->flags &= ~TTY_CTX_WINDOW_BIGGER; ttyctx->palette = &pd->palette; ttyctx->redraw_cb = popup_redraw_cb; ttyctx->set_client_cb = popup_set_client_cb; diff --git a/screen-write.c b/screen-write.c index 61b81ad3..c5ae0d36 100644 --- a/screen-write.c +++ b/screen-write.c @@ -133,7 +133,7 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c) { struct window_pane *wp = ttyctx->arg; - if (ttyctx->allow_invisible_panes) { + if (ttyctx->flags & TTY_CTX_INVISIBLE_PANES) { if (session_has(c->session, wp->window)) return (1); return (0); @@ -157,8 +157,11 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c) return (-1); } - ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy, - &ttyctx->wsx, &ttyctx->wsy); + if (tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy, &ttyctx->wsx, + &ttyctx->wsy)) + ttyctx->flags |= TTY_CTX_WINDOW_BIGGER; + else + ttyctx->flags &= ~TTY_CTX_WINDOW_BIGGER; ttyctx->xoff = ttyctx->rxoff = wp->xoff; ttyctx->yoff = ttyctx->ryoff = wp->yoff; @@ -213,13 +216,14 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, * move the cursor); for other panes, always use it, since the * cursor will have to move. */ - if (ctx->wp != NULL) { - if (ctx->wp != ctx->wp->window->active) - ttyctx->num = 1; - else - ttyctx->num = sync; - } else - ttyctx->num = 0x10|sync; + if (ctx->wp != NULL && ctx->wp != ctx->wp->window->active) + ttyctx->flags |= TTY_CTX_SYNC; + else { + if (ctx->wp == NULL) + ttyctx->flags |= TTY_CTX_OVERLAY_SYNC; + if (sync) + ttyctx->flags |= TTY_CTX_SYNC; + } tty_write(tty_cmd_syncstart, ttyctx); ctx->flags |= SCREEN_WRITE_SYNC; } @@ -572,6 +576,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, struct window_pane *wp = ctx->wp; 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; @@ -585,18 +590,22 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, if (wp != NULL) screen_write_initctx(ctx, &ttyctx, 0); for (xx = px; xx < px + nx; xx++) { - if (xx >= grid_get_line(gd, yy)->cellsize && - s->cx >= grid_get_line(ctx->s->grid, s->cy)->cellsize) + gl = grid_get_line(gd, yy); + sgl = grid_get_line(ctx->s->grid, s->cy); + if (xx >= gl->cellsize && s->cx >= sgl->cellsize) break; grid_get_cell(gd, xx, yy, &gc); if (xx + gc.data.width > px + nx) break; grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc); - if (wp != NULL) { - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - ttyctx.ocx++; + if (wp == NULL) { + s->cx++; + continue; } + ttyctx.cell = &gc; + ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC); + tty_write(tty_cmd_cell, &ttyctx); + ttyctx.ocx++; s->cx++; } s->cy++; @@ -1781,7 +1790,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, } else { screen_write_initctx(ctx, &ttyctx, 0); ttyctx.cell = &ci->gc; - ttyctx.wrapped = ci->wrapped; + if (ci->wrapped) + ttyctx.flags |= TTY_CTX_WRAPPED; ttyctx.ptr = cl->data + ci->x; ttyctx.num = ci->used; tty_write(tty_cmd_cells, &ttyctx); @@ -2082,7 +2092,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) ttyctx.cell = &tmp_gc; } else ttyctx.cell = gc; - ttyctx.num = redraw ? 2 : 0; + if (redraw) + ttyctx.flags |= TTY_CTX_CELL_DRAW_LINE; tty_write(tty_cmd_cell, &ttyctx); } } @@ -2150,7 +2161,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) if (utf8_should_combine(&last.data, ud)) force_wide = 1; else if (utf8_should_combine(ud, &last.data)) - force_wide = 1; + force_wide = 1; else if (!utf8_has_zwj(&last.data)) return (0); break; @@ -2194,7 +2205,8 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) screen_write_set_cursor(ctx, cx - n, cy); screen_write_initctx(ctx, &ttyctx, 0); ttyctx.cell = &last; - ttyctx.num = force_wide; /* reset cached cursor position */ + if (force_wide) + ttyctx.flags |= TTY_CTX_CELL_INVALIDATE; tty_write(tty_cmd_cell, &ttyctx); screen_write_set_cursor(ctx, cx, cy); @@ -2296,9 +2308,10 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len, struct tty_ctx ttyctx; screen_write_initctx(ctx, &ttyctx, 0); + if (allow_invisible_panes) + ttyctx.flags |= TTY_CTX_INVISIBLE_PANES; ttyctx.ptr = str; ttyctx.num = len; - ttyctx.allow_invisible_panes = allow_invisible_panes; tty_write(tty_cmd_rawstring, &ttyctx); } diff --git a/tmux.h b/tmux.h index 941bf27d..bba8beaa 100644 --- a/tmux.h +++ b/tmux.h @@ -1695,18 +1695,18 @@ struct tty_ctx { void *arg; const struct grid_cell *cell; - int wrapped; + int flags; +#define TTY_CTX_WRAPPED 0x1 +#define TTY_CTX_INVISIBLE_PANES 0x2 +#define TTY_CTX_WINDOW_BIGGER 0x4 +#define TTY_CTX_SYNC 0x8 +#define TTY_CTX_OVERLAY_SYNC 0x10 +#define TTY_CTX_CELL_DRAW_LINE 0x20 +#define TTY_CTX_CELL_INVALIDATE 0x40 - u_int num; - void *ptr; - void *ptr2; - - /* - * Whether this command should be sent even when the pane is not - * visible (used for a passthrough sequence when allow-passthrough is - * "all"). - */ - int allow_invisible_panes; + u_int num; + void *ptr; + void *ptr2; /* * Cursor and region position before the screen was updated - this is @@ -1735,7 +1735,6 @@ struct tty_ctx { struct colour_palette *palette; /* Containing region (usually window) offset and size. */ - int bigger; u_int wox; u_int woy; u_int wsx; diff --git a/tty.c b/tty.c index 34acbd83..883bea60 100644 --- a/tty.c +++ b/tty.c @@ -1104,7 +1104,7 @@ tty_is_visible(__unused struct tty *tty, const struct tty_ctx *ctx, u_int px, { u_int xoff = ctx->rxoff + px, yoff = ctx->ryoff + py; - if (!ctx->bigger) + if (~ctx->flags & TTY_CTX_WINDOW_BIGGER) return (1); if (xoff + nx <= ctx->wox || xoff >= ctx->wox + ctx->wsx || @@ -1372,9 +1372,9 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) struct visible_ranges *r; struct visible_range *rr; - log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger); + log_debug("%s: %s %u", __func__, tty->client->name, py); - if (!ctx->bigger) { + if (~ctx->flags & TTY_CTX_WINDOW_BIGGER) { r = tty_check_overlay_range(tty, ctx->xoff, ctx->yoff + py, nx); for (j = 0; j < r->used; j++) { rr = &r->ranges[j]; @@ -1504,7 +1504,7 @@ tty_client_ready(const struct tty_ctx *ctx, struct client *c) * If invisible panes are allowed (used for passthrough), don't care if * redrawing or frozen. */ - if (ctx->allow_invisible_panes) + if (ctx->flags & TTY_CTX_INVISIBLE_PANES) return (1); if (c->flags & CLIENT_REDRAWWINDOW) @@ -1540,7 +1540,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->bigger || + 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) && @@ -1563,7 +1563,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->bigger || + 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) && @@ -1595,7 +1595,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->bigger || + 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) || @@ -1623,7 +1623,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if (ctx->bigger || + 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) || @@ -1683,7 +1683,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orupper) return; - if (ctx->bigger || + 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) || @@ -1717,7 +1717,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orlower) return; - if (ctx->bigger || + 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) || @@ -1758,7 +1758,7 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) struct client *c = tty->client; u_int i; - if (ctx->bigger || + 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) || @@ -1797,7 +1797,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) u_int i; struct client *c = tty->client; - if (ctx->bigger || + 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) || @@ -1899,7 +1899,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { u_int i, j; - if (ctx->bigger) { + if (ctx->flags & TTY_CTX_WINDOW_BIGGER) { ctx->redraw_cb(ctx); return; } @@ -1931,7 +1931,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) (gcp->data.width == 1 && !tty_check_overlay(tty, px, py))) return; - if (ctx->num == 2) { + if (ctx->flags & TTY_CTX_CELL_DRAW_LINE) { tty_draw_line(tty, s, 0, s->cy, screen_size_x(s), ctx->xoff - ctx->wox, py, &ctx->defaults, ctx->palette); return; @@ -1960,7 +1960,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette, ctx->s->hyperlinks); - if (ctx->num == 1) + if (ctx->flags & TTY_CTX_CELL_INVALIDATE) tty_invalidate(tty); } @@ -1975,10 +1975,10 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) return; - if (ctx->bigger && + if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) && (ctx->xoff + ctx->ocx < ctx->wox || ctx->xoff + ctx->ocx + ctx->num > ctx->wox + ctx->wsx)) { - if (!ctx->wrapped || + if ((~ctx->flags & TTY_CTX_WRAPPED) || !tty_full_width(tty, ctx) || (tty->term->flags & TERM_NOAM) || ctx->xoff + ctx->ocx != 0 || @@ -2050,20 +2050,23 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx) { - if (ctx->num == 0x11) { - /* - * This is an overlay and a command that moves the cursor so - * start synchronized updates. - */ - tty_sync_start(tty); - } else if (~ctx->num & 0x10) { - /* - * This is a pane. If there is an overlay, always start; - * otherwise, only if requested. - */ - if (ctx->num || tty->client->overlay_draw != NULL) - tty_sync_start(tty); - } + struct client *c = tty->client; + + if ((ctx->flags & TTY_CTX_OVERLAY_SYNC) && + (ctx->flags & TTY_CTX_SYNC)) { + /* + * This is an overlay and a command that moves the cursor so + * start synchronized updates. + */ + tty_sync_start(tty); + } else if (~ctx->flags & TTY_CTX_OVERLAY_SYNC) { + /* + * This is a pane. If there is an overlay, always start; + * otherwise, only if requested. + */ + if ((ctx->flags & TTY_CTX_SYNC) || c->overlay_draw != NULL) + tty_sync_start(tty); + } } void @@ -2229,7 +2232,7 @@ static void tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) { - if (!ctx->wrapped || + if ((~ctx->flags & TTY_CTX_WRAPPED) || !tty_full_width(tty, ctx) || (tty->term->flags & TERM_NOAM) || ctx->xoff + cx != 0 || From d3e8dd3623c07b2ef98b0b894cecf45896ab5023 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 22 May 2026 10:58:37 +0100 Subject: [PATCH 5/5] Use a flags bit for obscured rather than an int. --- screen-write.c | 148 +++++++++++++++++++++++-------------------------- tmux.h | 4 +- tty.c | 36 +++++------- 3 files changed, 84 insertions(+), 104 deletions(-) diff --git a/screen-write.c b/screen-write.c index dd178d94..61c460da 100644 --- a/screen-write.c +++ b/screen-write.c @@ -36,7 +36,6 @@ static int screen_write_overwrite(struct screen_write_ctx *, struct grid_cell *, u_int); static int screen_write_combine(struct screen_write_ctx *, const struct grid_cell *); -static int screen_write_pane_is_obscured(struct screen_write_ctx *); struct screen_write_citem { u_int x; @@ -176,10 +175,43 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c) return (1); } +/* Return 1 if there is a floating window pane overlapping this pane. */ +static int +screen_write_pane_is_obscured(struct screen_write_ctx *ctx) +{ + 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); + return (0); + } + 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))) { + ctx->flags |= SCREEN_WRITE_OBSCURED; + return (1); + } + } + return (0); +} + /* Set up context for TTY command. */ static void screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, - int sync) + int is_sync, int check_obscured) { struct screen *s = ctx->s; @@ -194,6 +226,9 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, ttyctx->orlower = s->rlower; ttyctx->orupper = s->rupper; + if (check_obscured && screen_write_pane_is_obscured(ctx)) + ttyctx->flags |= TTY_CTX_PANE_OBSCURED; + memcpy(&ttyctx->defaults, &grid_default_cell, sizeof ttyctx->defaults); if (ctx->init_ctx_cb != NULL) { ctx->init_ctx_cb(ctx, ttyctx); @@ -225,7 +260,7 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, else { if (ctx->wp == NULL) ttyctx->flags |= TTY_CTX_OVERLAY_SYNC; - if (sync) + if (is_sync) ttyctx->flags |= TTY_CTX_SYNC; } tty_write(tty_cmd_syncstart, ttyctx); @@ -593,10 +628,9 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, if (yy >= gd->hsize + gd->sy) break; s->cx = cx; - screen_write_initctx(ctx, &ttyctx, 0); - if (wp != NULL) { + screen_write_initctx(ctx, &ttyctx, 0, 0); + if (wp != NULL) yoff = wp->yoff; - } r = screen_redraw_get_visible_ranges(wp, px, s->cy + yoff, nx, NULL); for (xx = px; xx < px + nx; xx++) { @@ -1104,7 +1138,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) s->rupper = 0; s->rlower = screen_size_y(s) - 1; - screen_write_initctx(ctx, &ttyctx, 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); @@ -1133,9 +1167,8 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1167,9 +1200,8 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); @@ -1201,7 +1233,7 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); ttyctx.bg = bg; grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg); @@ -1237,9 +1269,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) if (ny == 0) return; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_insert_lines(gd, s->cy, ny, bg); @@ -1254,11 +1285,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) if (ny == 0) return; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); - log_debug("%s: obscured=%d for pane %%%u", __func__, - ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); if (s->cy < s->rupper || s->cy > s->rlower) grid_view_insert_lines(gd, s->cy, ny, bg); @@ -1294,9 +1322,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) if (ny == 0) return; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); grid_view_delete_lines(gd, s->cy, ny, bg); @@ -1311,11 +1338,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) if (ny == 0) return; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); - log_debug("%s: obscured=%d for pane %%%u", __func__, - ttyctx.obscured, ctx->wp != NULL ? ctx->wp->id : 0); if (s->cy < s->rupper || s->cy > s->rlower) grid_view_delete_lines(gd, s->cy, ny, bg); @@ -1474,7 +1498,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); + screen_write_initctx(ctx, &ttyctx, 1, 0); ttyctx.bg = bg; tty_write(tty_cmd_reverseindex, &ttyctx); @@ -1585,9 +1609,8 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg) struct tty_ctx ttyctx; u_int i; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); if (lines == 0) lines = 1; @@ -1631,7 +1654,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; /* Scroll into history if it is enabled and clearing entire screen. */ @@ -1650,7 +1673,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1)); screen_write_collect_flush(ctx, 0, __func__); - if (!screen_write_pane_is_obscured(ctx)) { + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { tty_write(tty_cmd_clearendofscreen, &ttyctx); return; } @@ -1713,7 +1736,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; if (s->cy > 0) @@ -1726,7 +1749,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, s->cy); screen_write_collect_flush(ctx, 0, __func__); - if (!screen_write_pane_is_obscured(ctx)) { + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { tty_write(tty_cmd_clearstartofscreen, &ttyctx); return; } @@ -1787,7 +1810,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg) ctx->wp->flags |= PANE_REDRAW; #endif - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); ttyctx.bg = bg; /* Scroll into history if it is enabled. */ @@ -1800,7 +1823,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg) screen_write_collect_clear(ctx, 0, sy); - if (!screen_write_pane_is_obscured(ctx)) { + if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { tty_write(tty_cmd_clearscreen, &ttyctx); return; } @@ -1848,7 +1871,7 @@ screen_write_fullredraw(struct screen_write_ctx *ctx) screen_write_collect_flush(ctx, 0, __func__); - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 0); if (ttyctx.redraw_cb != NULL) ttyctx.redraw_cb(&ttyctx); } @@ -1985,39 +2008,6 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg) TAILQ_INSERT_TAIL(&ctx->s->write_list[s->rlower].items, ci, entry); } -/* Return 1 if there is a floating window pane overlapping this pane. */ -static int -screen_write_pane_is_obscured(struct screen_write_ctx *ctx) -{ - 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); - return (0); - } - 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))) { - ctx->flags |= SCREEN_WRITE_OBSCURED; - return (1); - } - } - return (0); -} - /* Flush collected lines. */ static void screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, @@ -2053,14 +2043,11 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, if (ctx->scrolled > s->rlower - s->rupper + 1) ctx->scrolled = s->rlower - s->rupper + 1; - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 1); if (wp != NULL && wp->yoff + wp->sy > wp->window->sy) ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); ttyctx.num = ctx->scrolled; ttyctx.bg = ctx->bg; - ttyctx.obscured = screen_write_pane_is_obscured(ctx); - log_debug("%s: obscured=%d for pane %%%u", __func__, - ttyctx.obscured, wp != NULL ? wp->id : 0); tty_write(tty_cmd_scrollup, &ttyctx); if (wp != NULL) log_debug("%s: after scrollup, PANE_REDRAW=%d for %%%u", @@ -2147,15 +2134,16 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, continue; screen_write_set_cursor(ctx, wr_start, y); if (ci->type == CLEAR) { - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 0); ttyctx.bg = ci->bg; ttyctx.num = wr_length; tty_write(tty_cmd_clearcharacter, &ttyctx); } else { - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); ttyctx.cell = &ci->gc; - ttyctx.wrapped = ci->wrapped; + if (ci->wrapped) + ttyctx.flags |= TTY_CTX_WRAPPED; ttyctx.ptr = cl->data + wr_start; ttyctx.num = wr_length; tty_write(tty_cmd_cells, &ttyctx); @@ -2382,7 +2370,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) /* Sanity check cursor position. */ if (s->cx > sx - width || s->cy > sy - 1) return; - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); /* Handle overwriting of UTF-8 characters. */ gl = grid_get_line(s->grid, s->grid->hsize + s->cy); @@ -2622,7 +2610,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) * and what it is going to do now. */ screen_write_set_cursor(ctx, cx - n, cy); - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); ttyctx.cell = &last; if (force_wide) ttyctx.flags |= TTY_CTX_CELL_INVALIDATE; @@ -2711,7 +2699,7 @@ screen_write_setselection(struct screen_write_ctx *ctx, const char *clip, { struct tty_ctx ttyctx; - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); ttyctx.ptr = str; ttyctx.ptr2 = (void *)clip; ttyctx.num = len; @@ -2726,7 +2714,7 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len, { struct tty_ctx ttyctx; - screen_write_initctx(ctx, &ttyctx, 0); + screen_write_initctx(ctx, &ttyctx, 0, 0); if (allow_invisible_panes) ttyctx.flags |= TTY_CTX_INVISIBLE_PANES; ttyctx.ptr = str; @@ -2814,7 +2802,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc, server_redraw_window_borders(wp->window); } - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 0); if (ttyctx.redraw_cb != NULL) ttyctx.redraw_cb(&ttyctx); } @@ -2838,7 +2826,7 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc, server_redraw_window_borders(wp->window); } - screen_write_initctx(ctx, &ttyctx, 1); + screen_write_initctx(ctx, &ttyctx, 1, 0); if (ttyctx.redraw_cb != NULL) ttyctx.redraw_cb(&ttyctx); } diff --git a/tmux.h b/tmux.h index c7bc244a..ac7894ad 100644 --- a/tmux.h +++ b/tmux.h @@ -1751,6 +1751,7 @@ struct tty_ctx { #define TTY_CTX_OVERLAY_SYNC 0x10 #define TTY_CTX_CELL_DRAW_LINE 0x20 #define TTY_CTX_CELL_INVALIDATE 0x40 +#define TTY_CTX_PANE_OBSCURED 0x80 u_int num; void *ptr; @@ -1787,9 +1788,6 @@ struct tty_ctx { u_int woy; u_int wsx; u_int wsy; - - /* tty partly obscured, it will need to be surgically scrolled. */ - u_int obscured; }; /* Saved message entry. */ diff --git a/tty.c b/tty.c index 946aad5c..121e3b85 100644 --- a/tty.c +++ b/tty.c @@ -1099,7 +1099,7 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) log_debug("%s: %s orlower=%u orupper=%u sy=%u large=%d", __func__, c->name, ctx->orlower, ctx->orupper, ctx->sy, tty_large_region(tty, ctx)); - if (tty_large_region(tty, ctx) && !ctx->obscured) { + if (tty_large_region(tty, ctx) && ~ctx->flags & TTY_CTX_PANE_OBSCURED) { log_debug("%s: %s large region redraw", __func__, c->name); ctx->redraw_cb(ctx); return; @@ -1433,7 +1433,7 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) if (~ctx->flags & TTY_CTX_WINDOW_BIGGER) { if (wp) { - if (ctx->obscured) { + if (ctx->flags & TTY_CTX_PANE_OBSCURED) { /* * Floating pane is present: use physical * coordinates and clip to visible ranges to @@ -1693,13 +1693,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || + if ((ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED)) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_ICH) && !tty_term_has(tty->term, TTYC_ICH1)) || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_draw_pane(tty, ctx, ctx->ocy); return; } @@ -1717,13 +1716,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || + if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1)) || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_draw_pane(tty, ctx, ctx->ocy); return; } @@ -1750,15 +1748,14 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || + if ((ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED)) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1) || ctx->sx == 1 || ctx->sy == 1 || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_redraw_region(tty, ctx); return; } @@ -1779,15 +1776,14 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) || + if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || !tty_full_width(tty, ctx) || tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1) || ctx->sx == 1 || ctx->sy == 1 || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_redraw_region(tty, ctx); return; } @@ -1915,14 +1911,13 @@ 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) || + if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || ctx->sx == 1 || ctx->sy == 1 || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_redraw_region(tty, ctx); return; } @@ -1955,7 +1950,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) || + if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED) || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || @@ -1963,8 +1958,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_RIN)) || ctx->sx == 1 || ctx->sy == 1 || - c->overlay_check != NULL || - ctx->obscured) { + c->overlay_check != NULL) { tty_redraw_region(tty, ctx); return; } @@ -2058,7 +2052,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { u_int i, j; - if (ctx->flags & TTY_CTX_WINDOW_BIGGER) { + if (ctx->flags & (TTY_CTX_WINDOW_BIGGER|TTY_CTX_PANE_OBSCURED)) { ctx->redraw_cb(ctx); return; }