Correct redrawing of wide characters when overwritten. Reported by Jake

Stewart in GitHub issue 4737.
This commit is contained in:
nicm
2026-01-07 18:29:15 +00:00
parent 583f12ea71
commit e2afaaea75
2 changed files with 39 additions and 7 deletions

View File

@@ -61,9 +61,9 @@ screen_write_get_citem(void)
ci = TAILQ_FIRST(&screen_write_citem_freelist);
if (ci != NULL) {
TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
memset(ci, 0, sizeof *ci);
return (ci);
TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
memset(ci, 0, sizeof *ci);
return (ci);
}
return (xcalloc(1, sizeof *ci));
}
@@ -71,7 +71,7 @@ screen_write_get_citem(void)
static void
screen_write_free_citem(struct screen_write_citem *ci)
{
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
}
static void
@@ -1809,7 +1809,7 @@ void
screen_write_collect_end(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
struct screen_write_citem *ci = ctx->item, *before;
struct screen_write_citem *ci = ctx->item, *nci, *before;
struct screen_write_cline *cl = &s->write_list[s->cy];
struct grid_cell gc;
u_int xx;
@@ -1838,6 +1838,8 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
break;
grid_view_set_cell(s->grid, xx, s->cy,
&grid_default_cell);
log_debug("%s: padding erased (before) at %u",
__func__, xx);
}
if (xx != s->cx) {
if (xx == 0)
@@ -1845,8 +1847,19 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
if (gc.data.width > 1) {
grid_view_set_cell(s->grid, xx, s->cy,
&grid_default_cell);
log_debug("%s: padding erased (before) at %u",
__func__, xx);
}
}
if (xx != s->cx) {
nci = ctx->item;
nci->type = CLEAR;
nci->x = xx;
nci->bg = 8;
nci->used = s->cx - xx;
TAILQ_INSERT_BEFORE(ci, nci, entry);
ctx->item = screen_write_get_citem();
}
}
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, cl->data + ci->x,
@@ -1858,6 +1871,16 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
if (~gc.flags & GRID_FLAG_PADDING)
break;
grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell);
log_debug("%s: padding erased (after) at %u", __func__, xx);
}
if (xx != s->cx) {
nci = ctx->item;
nci->type = CLEAR;
nci->x = s->cx;
nci->bg = 8;
nci->used = xx - s->cx;
TAILQ_INSERT_AFTER(&cl->items, ci, nci, entry);
ctx->item = screen_write_get_citem();
}
}
@@ -1928,7 +1951,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
struct tty_ctx ttyctx;
u_int sx = screen_size_x(s), sy = screen_size_y(s);
u_int width = ud->width, xx, not_wrap;
int selected, skip = 1;
int selected, skip = 1, redraw = 0;
/* Ignore padding cells. */
if (gc->flags & GRID_FLAG_PADDING)
@@ -1970,8 +1993,10 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
if (gl->flags & GRID_LINE_EXTENDED) {
grid_view_get_cell(gd, s->cx, s->cy, &now_gc);
if (screen_write_overwrite(ctx, &now_gc, width))
if (screen_write_overwrite(ctx, &now_gc, width)) {
redraw = 1;
skip = 0;
}
}
/*
@@ -2048,6 +2073,7 @@ 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;
tty_write(tty_cmd_cell, &ttyctx);
}
}

6
tty.c
View File

@@ -2112,6 +2112,12 @@ 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) {
tty_draw_line(tty, s, 0, s->cy, screen_size_x(s),
ctx->xoff - ctx->wox, py, &ctx->defaults, ctx->palette);
return;
}
/* Handle partially obstructed wide characters. */
if (gcp->data.width > 1) {
tty_check_overlay_range(tty, px, py, gcp->data.width, &r);