Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'

* refs/remotes/tmux-openbsd/master:
  Store background colour in padding cells and correctly clear adjacent cells when tabs are overwritten, GitHu issue 5441 from Ayman Bagabas.
  Exit failure on socket failure, from Rayan Salhab.
  Pessimize compiler flags for screen-redraw.c to prevent tmux from dumping core upon startup on landisk.
This commit is contained in:
Nicholas Marriott
2026-08-03 17:27:11 +01:00
5 changed files with 82 additions and 56 deletions

View File

@@ -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
View File

@@ -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>
@@ -682,9 +682,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. */

View File

@@ -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>
@@ -2480,15 +2480,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;
@@ -2504,8 +2551,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);
}
@@ -2514,20 +2560,12 @@ 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;
}
}
@@ -2538,28 +2576,20 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
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. */
@@ -2687,7 +2717,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;
}
@@ -2899,7 +2929,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
@@ -2968,12 +2998,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;
}
@@ -2991,17 +3021,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;
}
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: server.c,v 1.214 2026/07/10 13:38:45 nicm Exp $ */
/* $OpenBSD: server.c,v 1.215 2026/08/03 10:07:57 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -240,6 +240,7 @@ server_start(struct tmuxproc *client, uint64_t flags, struct event_base *base,
if (cause != NULL) {
if (c != NULL) {
c->exit_message = cause;
c->retval = 1;
c->flags |= CLIENT_EXIT;
} else {
fprintf(stderr, "%s\n", cause);
@@ -398,6 +399,7 @@ server_accept(int fd, short events, __unused void *data)
c = server_client_create(newfd);
if (!server_acl_join(c)) {
c->exit_message = xstrdup("access not allowed");
c->retval = 1;
c->flags |= CLIENT_EXIT;
}
}

6
tmux.h
View File

@@ -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>
@@ -3493,7 +3493,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);
@@ -3538,7 +3538,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);