Fix issue where popup window gets overwritten by background updates,

from Conor Taylor in GitHub issue 4920.
This commit is contained in:
nicm
2026-03-23 08:48:32 +00:00
parent d22ab85b84
commit d70edfa0a0
2 changed files with 54 additions and 16 deletions

View File

@@ -48,12 +48,19 @@ static void
tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx, tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx,
const struct grid_cell *defaults, u_int bg, int wrapped) const struct grid_cell *defaults, u_int bg, int wrapped)
{ {
struct visible_ranges *r;
struct visible_range *rr;
u_int i;
/* Nothing to clear. */ /* Nothing to clear. */
if (nx == 0) if (nx == 0)
return; return;
/* If genuine BCE is available, can try escape sequences. */ /* If genuine BCE is available, can try escape sequences. */
if (!wrapped && nx >= 10 && !tty_fake_bce(tty, defaults, bg)) { if (tty->client->overlay_check == NULL &&
!wrapped &&
nx >= 10 &&
!tty_fake_bce(tty, defaults, bg)) {
/* Off the end of the line, use EL if available. */ /* Off the end of the line, use EL if available. */
if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) {
tty_cursor(tty, px, py); tty_cursor(tty, px, py);
@@ -77,14 +84,20 @@ tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx,
} }
/* Couldn't use an escape sequence, use spaces. */ /* Couldn't use an escape sequence, use spaces. */
if (px != 0 || !wrapped) r = tty_check_overlay_range(tty, px, py, nx);
tty_cursor(tty, px, py); for (i = 0; i < r->used; i++) {
if (nx == 1) rr = &r->ranges[i];
if (rr->nx != 0) {
if (rr->px != 0 || !wrapped)
tty_cursor(tty, rr->px, py);
if (rr->nx == 1)
tty_putc(tty, ' '); tty_putc(tty, ' ');
else if (nx == 2) else if (rr->nx == 2)
tty_putn(tty, " ", 2, 2); tty_putn(tty, " ", 2, 2);
else else
tty_repeat_space(tty, nx); tty_repeat_space(tty, rr->nx);
}
}
} }
/* Is this cell empty? */ /* Is this cell empty? */

35
tty.c
View File

@@ -1157,6 +1157,9 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py,
u_int px, u_int nx, u_int bg) u_int px, u_int nx, u_int bg)
{ {
struct client *c = tty->client; struct client *c = tty->client;
struct visible_ranges *r;
struct visible_range *rr;
u_int i;
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py);
@@ -1192,8 +1195,14 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py,
* Couldn't use an escape sequence, use spaces. Clear only the visible * Couldn't use an escape sequence, use spaces. Clear only the visible
* bit if there is an overlay. * bit if there is an overlay.
*/ */
tty_cursor(tty, px, py); r = tty_check_overlay_range(tty, px, py, nx);
tty_repeat_space(tty, nx); for (i = 0; i < r->used; i++) {
rr = &r->ranges[i];
if (rr->nx != 0) {
tty_cursor(tty, rr->px, py);
tty_repeat_space(tty, rr->nx);
}
}
} }
/* Clear a line, adjusting to visible part of pane. */ /* Clear a line, adjusting to visible part of pane. */
@@ -1359,20 +1368,36 @@ static void
tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
u_int nx = ctx->sx, i, x, rx, ry; u_int nx = ctx->sx, i, x, rx, ry, j;
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 %d", __func__, tty->client->name, py, ctx->bigger);
if (!ctx->bigger) { if (!ctx->bigger) {
tty_draw_line(tty, s, 0, py, nx, ctx->xoff, ctx->yoff + py, r = tty_check_overlay_range(tty, ctx->xoff, ctx->yoff + py, nx);
for (j = 0; j < r->used; j++) {
rr = &r->ranges[j];
if (rr->nx != 0) {
tty_draw_line(tty, s, rr->px - ctx->xoff, py,
rr->nx, rr->px, ctx->yoff + py,
&ctx->defaults, ctx->palette); &ctx->defaults, ctx->palette);
}
}
return; return;
} }
if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) { if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) {
tty_draw_line(tty, s, i, py, rx, x, ry, &ctx->defaults, r = tty_check_overlay_range(tty, x, ry, rx);
for (j = 0; j < r->used; j++) {
rr = &r->ranges[j];
if (rr->nx != 0) {
tty_draw_line(tty, s, i + (rr->px - x), py,
rr->nx, rr->px, ry, &ctx->defaults,
ctx->palette); ctx->palette);
} }
} }
}
}
const struct grid_cell * const struct grid_cell *
tty_check_codeset(struct tty *tty, const struct grid_cell *gc) tty_check_codeset(struct tty *tty, const struct grid_cell *gc)