Work out if a pane is obscured by another one when drawing.

This commit is contained in:
nicm
2026-05-22 11:55:43 +00:00
parent 36bc351557
commit d45a9cad8c
2 changed files with 66 additions and 26 deletions

View File

@@ -172,10 +172,43 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
return (1); 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. */ /* Set up context for TTY command. */
static void static void
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, 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; struct screen *s = ctx->s;
@@ -190,6 +223,9 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
ttyctx->orlower = s->rlower; ttyctx->orlower = s->rlower;
ttyctx->orupper = s->rupper; 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); memcpy(&ttyctx->defaults, &grid_default_cell, sizeof ttyctx->defaults);
if (ctx->init_ctx_cb != NULL) { if (ctx->init_ctx_cb != NULL) {
ctx->init_ctx_cb(ctx, ttyctx); ctx->init_ctx_cb(ctx, ttyctx);
@@ -221,7 +257,7 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
else { else {
if (ctx->wp == NULL) if (ctx->wp == NULL)
ttyctx->flags |= TTY_CTX_OVERLAY_SYNC; ttyctx->flags |= TTY_CTX_OVERLAY_SYNC;
if (sync) if (is_sync)
ttyctx->flags |= TTY_CTX_SYNC; ttyctx->flags |= TTY_CTX_SYNC;
} }
tty_write(tty_cmd_syncstart, ttyctx); tty_write(tty_cmd_syncstart, ttyctx);
@@ -588,7 +624,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
break; break;
s->cx = cx; s->cx = cx;
if (wp != NULL) if (wp != NULL)
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
for (xx = px; xx < px + nx; xx++) { for (xx = px; xx < px + nx; xx++) {
gl = grid_get_line(gd, yy); gl = grid_get_line(gd, yy);
sgl = grid_get_line(ctx->s->grid, s->cy); sgl = grid_get_line(ctx->s->grid, s->cy);
@@ -1091,7 +1127,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
s->rupper = 0; s->rupper = 0;
s->rlower = screen_size_y(s) - 1; 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); screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1);
tty_write(tty_cmd_alignmenttest, &ttyctx); tty_write(tty_cmd_alignmenttest, &ttyctx);
@@ -1115,7 +1151,7 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
if (s->cx > screen_size_x(s) - 1) if (s->cx > screen_size_x(s) - 1)
return; return;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);
@@ -1143,7 +1179,7 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
if (s->cx > screen_size_x(s) - 1) if (s->cx > screen_size_x(s) - 1)
return; return;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg);
@@ -1171,7 +1207,7 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
if (s->cx > screen_size_x(s) - 1) if (s->cx > screen_size_x(s) - 1)
return; return;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.bg = bg; ttyctx.bg = bg;
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg); grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg);
@@ -1198,7 +1234,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0) if (ny == 0)
return; return;
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
grid_view_insert_lines(gd, s->cy, ny, bg); grid_view_insert_lines(gd, s->cy, ny, bg);
@@ -1214,7 +1250,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0) if (ny == 0)
return; return;
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
if (s->cy < s->rupper || s->cy > s->rlower) if (s->cy < s->rupper || s->cy > s->rlower)
@@ -1246,7 +1282,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0) if (ny == 0)
return; return;
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
grid_view_delete_lines(gd, s->cy, ny, bg); grid_view_delete_lines(gd, s->cy, ny, bg);
@@ -1262,7 +1298,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0) if (ny == 0)
return; return;
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
if (s->cy < s->rupper || s->cy > s->rlower) if (s->cy < s->rupper || s->cy > s->rlower)
@@ -1382,10 +1418,11 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
if (s->cy == s->rupper) { if (s->cy == s->rupper) {
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg); grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 0);
ttyctx.bg = bg; ttyctx.bg = bg;
tty_write(tty_cmd_reverseindex, &ttyctx); tty_write(tty_cmd_reverseindex, &ttyctx);
@@ -1480,7 +1517,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
u_int i; u_int i;
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
if (lines == 0) if (lines == 0)
@@ -1512,7 +1549,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
u_int sx = screen_size_x(s), sy = screen_size_y(s); u_int sx = screen_size_x(s), sy = screen_size_y(s);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
/* Scroll into history if it is enabled and clearing entire screen. */ /* Scroll into history if it is enabled and clearing entire screen. */
@@ -1541,7 +1578,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
u_int sx = screen_size_x(s); u_int sx = screen_size_x(s);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
if (s->cy > 0) if (s->cy > 0)
@@ -1564,7 +1601,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
u_int sx = screen_size_x(s), sy = screen_size_y(s); u_int sx = screen_size_x(s), sy = screen_size_y(s);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
/* Scroll into history if it is enabled. */ /* Scroll into history if it is enabled. */
@@ -1594,7 +1631,7 @@ screen_write_fullredraw(struct screen_write_ctx *ctx)
screen_write_collect_flush(ctx, 0, __func__); 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) if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx); ttyctx.redraw_cb(&ttyctx);
} }
@@ -1756,7 +1793,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
if (ctx->scrolled > s->rlower - s->rupper + 1) if (ctx->scrolled > s->rlower - s->rupper + 1)
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);
ttyctx.n = ctx->scrolled; ttyctx.n = ctx->scrolled;
ttyctx.bg = ctx->bg; ttyctx.bg = ctx->bg;
tty_write(tty_cmd_scrollup, &ttyctx); tty_write(tty_cmd_scrollup, &ttyctx);
@@ -1783,12 +1820,12 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
} }
screen_write_set_cursor(ctx, ci->x, y); screen_write_set_cursor(ctx, ci->x, y);
if (ci->type == CLEAR) { if (ci->type == CLEAR) {
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 0);
ttyctx.bg = ci->bg; ttyctx.bg = ci->bg;
ttyctx.n = ci->used; ttyctx.n = ci->used;
tty_write(tty_cmd_clearcharacter, &ttyctx); tty_write(tty_cmd_clearcharacter, &ttyctx);
} else { } else {
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.cell = &ci->gc; ttyctx.cell = &ci->gc;
if (ci->wrapped) if (ci->wrapped)
ttyctx.flags |= TTY_CTX_WRAPPED; ttyctx.flags |= TTY_CTX_WRAPPED;
@@ -2006,7 +2043,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Sanity check cursor position. */ /* Sanity check cursor position. */
if (s->cx > sx - width || s->cy > sy - 1) if (s->cx > sx - width || s->cy > sy - 1)
return; return;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
/* Handle overwriting of UTF-8 characters. */ /* Handle overwriting of UTF-8 characters. */
gl = grid_get_line(s->grid, s->grid->hsize + s->cy); gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
@@ -2203,7 +2240,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* and what it is going to do now. * and what it is going to do now.
*/ */
screen_write_set_cursor(ctx, cx - n, cy); screen_write_set_cursor(ctx, cx - n, cy);
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.cell = &last; ttyctx.cell = &last;
if (force_wide) if (force_wide)
ttyctx.flags |= TTY_CTX_CELL_INVALIDATE; ttyctx.flags |= TTY_CTX_CELL_INVALIDATE;
@@ -2292,7 +2329,7 @@ screen_write_setselection(struct screen_write_ctx *ctx, const char *clip,
{ {
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.sel.clip = clip; ttyctx.sel.clip = clip;
ttyctx.sel.data = str; ttyctx.sel.data = str;
ttyctx.sel.size = len; ttyctx.sel.size = len;
@@ -2307,7 +2344,7 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
{ {
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0); screen_write_initctx(ctx, &ttyctx, 0, 0);
if (allow_invisible_panes) if (allow_invisible_panes)
ttyctx.flags |= TTY_CTX_INVISIBLE_PANES; ttyctx.flags |= TTY_CTX_INVISIBLE_PANES;
ttyctx.data.data = str; ttyctx.data.data = str;
@@ -2335,7 +2372,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
server_redraw_window_borders(wp->window); server_redraw_window_borders(wp->window);
} }
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 0);
if (ttyctx.redraw_cb != NULL) if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx); ttyctx.redraw_cb(&ttyctx);
} }
@@ -2359,7 +2396,7 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
server_redraw_window_borders(wp->window); server_redraw_window_borders(wp->window);
} }
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1, 0);
if (ttyctx.redraw_cb != NULL) if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx); ttyctx.redraw_cb(&ttyctx);
} }

3
tmux.h
View File

@@ -1021,6 +1021,8 @@ struct screen_write_ctx {
int flags; int flags;
#define SCREEN_WRITE_SYNC 0x1 #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; screen_write_init_ctx_cb init_ctx_cb;
void *arg; void *arg;
@@ -1703,6 +1705,7 @@ struct tty_ctx {
#define TTY_CTX_OVERLAY_SYNC 0x10 #define TTY_CTX_OVERLAY_SYNC 0x10
#define TTY_CTX_CELL_DRAW_LINE 0x20 #define TTY_CTX_CELL_DRAW_LINE 0x20
#define TTY_CTX_CELL_INVALIDATE 0x40 #define TTY_CTX_CELL_INVALIDATE 0x40
#define TTY_CTX_PANE_OBSCURED 0x80
union { union {
u_int n; u_int n;