mirror of
https://github.com/tmux/tmux.git
synced 2026-08-23 23:21:36 +00:00
Store background colour in padding cells and correctly clear adjacent
cells when tabs are overwritten, GitHu issue 5441 from Ayman Bagabas.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: grid-view.c,v 1.38 2026/01/22 08:55:01 nicm Exp $ */
|
||||
/* $OpenBSD: grid-view.c,v 1.39 2026/08/03 12:58:53 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -47,9 +47,9 @@ grid_view_set_cell(struct grid *gd, u_int px, u_int py,
|
||||
|
||||
/* Set padding. */
|
||||
void
|
||||
grid_view_set_padding(struct grid *gd, u_int px, u_int py)
|
||||
grid_view_set_padding(struct grid *gd, u_int px, u_int py, int bg)
|
||||
{
|
||||
grid_set_padding(gd, grid_view_x(gd, px), grid_view_y(gd, py));
|
||||
grid_set_padding(gd, grid_view_x(gd, px), grid_view_y(gd, py), bg);
|
||||
}
|
||||
|
||||
/* Set cells. */
|
||||
|
||||
10
grid.c
10
grid.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: grid.c,v 1.155 2026/07/29 17:42:56 nicm Exp $ */
|
||||
/* $OpenBSD: grid.c,v 1.156 2026/08/03 12:58:53 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -631,9 +631,13 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
|
||||
|
||||
/* Set padding at position. */
|
||||
void
|
||||
grid_set_padding(struct grid *gd, u_int px, u_int py)
|
||||
grid_set_padding(struct grid *gd, u_int px, u_int py, int bg)
|
||||
{
|
||||
grid_set_cell(gd, px, py, &grid_padding_cell);
|
||||
struct grid_cell gc;
|
||||
|
||||
memcpy(&gc, &grid_padding_cell, sizeof gc);
|
||||
gc.bg = bg;
|
||||
grid_set_cell(gd, px, py, &gc);
|
||||
}
|
||||
|
||||
/* Set cells at position. */
|
||||
|
||||
112
screen-write.c
112
screen-write.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: screen-write.c,v 1.285 2026/07/26 09:02:08 nicm Exp $ */
|
||||
/* $OpenBSD: screen-write.c,v 1.286 2026/08/03 12:58:53 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -2393,15 +2393,62 @@ screen_write_collect_insert_clear(struct screen_write_ctx *ctx, u_int px,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear a cell that is being broken up by a write over part of it, keeping the
|
||||
* background so the columns it covered do not lose their colour.
|
||||
*/
|
||||
static void
|
||||
screen_write_clear_cell(struct grid *gd, u_int px, u_int py)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
int bg;
|
||||
|
||||
grid_view_get_cell(gd, px, py, &gc);
|
||||
bg = gc.bg;
|
||||
|
||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||
gc.bg = bg;
|
||||
grid_view_set_cell(gd, px, py, &gc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert clears for a range of cells already cleared in the grid. Adjacent
|
||||
* cells may have come from different characters and so have different
|
||||
* backgrounds, so this is done in runs of the same colour.
|
||||
*/
|
||||
static void
|
||||
screen_write_insert_clears(struct screen_write_ctx *ctx, u_int px, u_int nx)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct grid_cell gc;
|
||||
u_int xx, start = px, n;
|
||||
int bg = 8;
|
||||
|
||||
for (xx = px; xx < px + nx; xx++) {
|
||||
grid_view_get_cell(s->grid, xx, s->cy, &gc);
|
||||
if (xx == start)
|
||||
bg = gc.bg;
|
||||
else if (gc.bg != bg) {
|
||||
n = xx - start;
|
||||
log_debug("%s: from %u, size %u", __func__, start, n);
|
||||
screen_write_collect_insert_clear(ctx, start, n, bg);
|
||||
start = xx;
|
||||
bg = gc.bg;
|
||||
}
|
||||
}
|
||||
log_debug("%s: from %u, size %u", __func__, start, xx - start);
|
||||
screen_write_collect_insert_clear(ctx, start, xx - start, bg);
|
||||
}
|
||||
|
||||
/* Finish and store collected cells. */
|
||||
void
|
||||
screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct screen_write_citem *ci = ctx->item, *bci = NULL, *aci;
|
||||
struct screen_write_citem *ci = ctx->item;
|
||||
struct screen_write_cline *cl = &s->write_list[s->cy];
|
||||
struct grid_cell gc;
|
||||
u_int xx;
|
||||
u_int xx, bx = 0, bnx = 0;
|
||||
|
||||
if (ci->used == 0)
|
||||
return;
|
||||
@@ -2417,8 +2464,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
grid_view_get_cell(s->grid, xx, s->cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
grid_view_set_cell(s->grid, xx, s->cy,
|
||||
&grid_default_cell);
|
||||
screen_write_clear_cell(s->grid, xx, s->cy);
|
||||
log_debug("%s: padding erased (before) at %u (cx %u)",
|
||||
__func__, xx, s->cx);
|
||||
}
|
||||
@@ -2427,47 +2473,31 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
grid_view_get_cell(s->grid, 0, s->cy, &gc);
|
||||
if (gc.data.width > 1 ||
|
||||
(gc.flags & GRID_FLAG_PADDING)) {
|
||||
grid_view_set_cell(s->grid, xx, s->cy,
|
||||
&grid_default_cell);
|
||||
screen_write_clear_cell(s->grid, xx, s->cy);
|
||||
log_debug("%s: padding erased (before) at %u "
|
||||
"(cx %u)", __func__, xx, s->cx);
|
||||
}
|
||||
}
|
||||
if (xx != s->cx) {
|
||||
bci = ctx->item;
|
||||
bci->type = CLEAR;
|
||||
bci->x = xx;
|
||||
bci->bg = 8;
|
||||
bci->used = s->cx - xx;
|
||||
log_debug("%s: padding erased (before): from %u, "
|
||||
"size %u", __func__, bci->x, bci->used);
|
||||
bx = xx;
|
||||
bnx = s->cx - xx;
|
||||
}
|
||||
}
|
||||
|
||||
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, cl->data + ci->x,
|
||||
ci->used);
|
||||
if (bci != NULL)
|
||||
screen_write_collect_insert(ctx, bci);
|
||||
if (bnx != 0)
|
||||
screen_write_insert_clears(ctx, bx, bnx);
|
||||
screen_write_set_cursor(ctx, s->cx + ci->used, -1);
|
||||
|
||||
for (xx = s->cx; xx < screen_size_x(s); xx++) {
|
||||
grid_view_get_cell(s->grid, xx, s->cy, &gc);
|
||||
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 (cx %u)",
|
||||
__func__, xx, s->cx);
|
||||
}
|
||||
if (xx != s->cx) {
|
||||
aci = ctx->item;
|
||||
aci->type = CLEAR;
|
||||
aci->x = s->cx;
|
||||
aci->bg = 8;
|
||||
aci->used = xx - s->cx;
|
||||
log_debug("%s: padding erased (after): from %u, size %u",
|
||||
__func__, aci->x, aci->used);
|
||||
screen_write_collect_insert(ctx, aci);
|
||||
screen_write_clear_cell(s->grid, xx, s->cy);
|
||||
log_debug("%s: padding erased (after) at %u (cx %u)", __func__,
|
||||
xx, s->cx);
|
||||
}
|
||||
if (xx != s->cx)
|
||||
screen_write_insert_clears(ctx, s->cx, xx - s->cx);
|
||||
}
|
||||
|
||||
/* Write cell data, collecting if necessary. */
|
||||
@@ -2595,7 +2625,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
*/
|
||||
for (xx = s->cx + 1; xx < s->cx + width; xx++) {
|
||||
log_debug("%s: new padding at %u,%u", __func__, xx, s->cy);
|
||||
grid_view_set_padding(gd, xx, s->cy);
|
||||
grid_view_set_padding(gd, xx, s->cy, gc->bg);
|
||||
skip = 0;
|
||||
}
|
||||
|
||||
@@ -2807,7 +2837,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
/* Set the new cell. */
|
||||
grid_view_set_cell(gd, cx - n, cy, &last);
|
||||
if (force_wide)
|
||||
grid_view_set_padding(gd, cx - 1, cy);
|
||||
grid_view_set_padding(gd, cx - 1, cy, last.bg);
|
||||
|
||||
/*
|
||||
* Check if all of this character is visible. No character will be
|
||||
@@ -2876,12 +2906,12 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
if (~tmp_gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
log_debug("%s: padding at %u,%u", __func__, xx, s->cy);
|
||||
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
||||
screen_write_clear_cell(gd, xx, s->cy);
|
||||
}
|
||||
|
||||
/* Overwrite the character at the start of this padding. */
|
||||
log_debug("%s: character at %u,%u", __func__, xx, s->cy);
|
||||
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
||||
screen_write_clear_cell(gd, xx, s->cy);
|
||||
done = 1;
|
||||
}
|
||||
|
||||
@@ -2899,17 +2929,7 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
break;
|
||||
log_debug("%s: overwrite at %u,%u", __func__, xx,
|
||||
s->cy);
|
||||
if (gc->flags & GRID_FLAG_TAB) {
|
||||
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
||||
memset(tmp_gc.data.data, 0,
|
||||
sizeof tmp_gc.data.data);
|
||||
*tmp_gc.data.data = ' ';
|
||||
tmp_gc.data.width = tmp_gc.data.size =
|
||||
tmp_gc.data.have = 1;
|
||||
grid_view_set_cell(gd, xx, s->cy, &tmp_gc);
|
||||
} else
|
||||
grid_view_set_cell(gd, xx, s->cy,
|
||||
&grid_default_cell);
|
||||
screen_write_clear_cell(gd, xx, s->cy);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
6
tmux.h
6
tmux.h
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1418 2026/07/29 17:42:56 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1419 2026/08/03 12:58:53 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -3447,7 +3447,7 @@ void grid_clear_history(struct grid *);
|
||||
const struct grid_line *grid_peek_line(struct grid *, u_int);
|
||||
void grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
||||
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
|
||||
void grid_set_padding(struct grid *, u_int, u_int);
|
||||
void grid_set_padding(struct grid *, u_int, u_int, int);
|
||||
void grid_set_cells(struct grid *, u_int, u_int, const struct grid_cell *,
|
||||
const char *, size_t);
|
||||
struct grid_line *grid_get_line(struct grid *, u_int);
|
||||
@@ -3492,7 +3492,7 @@ void grid_reader_cursor_back_to_indentation(struct grid_reader *);
|
||||
void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
||||
void grid_view_set_cell(struct grid *, u_int, u_int,
|
||||
const struct grid_cell *);
|
||||
void grid_view_set_padding(struct grid *, u_int, u_int);
|
||||
void grid_view_set_padding(struct grid *, u_int, u_int, int);
|
||||
void grid_view_set_cells(struct grid *, u_int, u_int,
|
||||
const struct grid_cell *, const char *, size_t);
|
||||
void grid_view_clear_history(struct grid *, u_int);
|
||||
|
||||
Reference in New Issue
Block a user