From 1cb5aded8bfd8f6f1002c012f2f7eb3336676d29 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 5 Apr 2026 15:43:17 +0000 Subject: [PATCH] When a cell is cleared after having been moved, we cannot reuse its extended data, because that may still be in use. Add a flag to grid_clear_cell to indicate this. Fixes irritating problems with ICH (CSI @) mostly visible in emacs. --- usr.bin/tmux/grid.c | 12 ++++++------ usr.bin/tmux/screen.c | 7 +++++-- usr.bin/tmux/tmux.h | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index 34d15d726a2..9281ae34d23 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.145 2026/03/23 09:05:59 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.146 2026/04/05 15:43:17 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -200,7 +200,7 @@ grid_adjust_lines(struct grid *gd, u_int lines) /* Copy default into a cell. */ static void -grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg) +grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg, int moved) { struct grid_line *gl = &gd->linedata[py]; struct grid_cell_entry *gce = &gl->celldata[px]; @@ -209,7 +209,7 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg) int had_extd = (gce->flags & GRID_FLAG_EXTENDED); memcpy(gce, &grid_cleared_entry, sizeof *gce); - if (had_extd && old_offset < gl->extdsize) { + if (!moved && had_extd && old_offset < gl->extdsize) { gce->flags |= GRID_FLAG_EXTENDED; gce->offset = old_offset; gee = grid_extended_cell(gl, gce, &grid_cleared_cell); @@ -515,7 +515,7 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg) (sx - gl->cellsize) * sizeof *gl->celldata); } for (xx = gl->cellsize; xx < sx; xx++) - grid_clear_cell(gd, xx, py, bg); + grid_clear_cell(gd, xx, py, bg, 0); gl->cellsize = sx; } @@ -683,7 +683,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) grid_expand_line(gd, yy, px + ox, 8); /* default bg first */ for (xx = px; xx < px + ox; xx++) - grid_clear_cell(gd, xx, yy, bg); + grid_clear_cell(gd, xx, yy, bg, 0); } } @@ -777,7 +777,7 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx, for (xx = px; xx < px + nx; xx++) { if (xx >= dx && xx < dx + nx) continue; - grid_clear_cell(gd, xx, py, bg); + grid_clear_cell(gd, xx, py, bg, 1); } } diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c index 278af3b51c9..d67cdc46072 100644 --- a/usr.bin/tmux/screen.c +++ b/usr.bin/tmux/screen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen.c,v 1.96 2026/04/03 09:18:24 nicm Exp $ */ +/* $OpenBSD: screen.c,v 1.97 2026/04/05 15:43:17 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -760,8 +760,9 @@ screen_mode_to_string(int mode) return (tmp); } +/* Convert screen to a string. */ const char * -screen_print(struct screen *s) +screen_print(struct screen *s, int line) { static char *buf; static size_t len = 16384; @@ -777,6 +778,8 @@ screen_print(struct screen *s) buf = xmalloc(len); for (y = 0; y < screen_hsize(s) + s->grid->sy; y++) { + if (line >= 0 && y != (u_int)line) + continue; n = snprintf(buf + last, len - last, "%.4d \"", y); if (n <= 0 || (u_int)n >= len - last) goto out; diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 5d1967221ee..787f01e0de5 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1304 2026/04/04 17:13:07 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1305 2026/04/05 15:43:17 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3296,7 +3296,7 @@ int screen_select_cell(struct screen *, struct grid_cell *, void screen_alternate_on(struct screen *, struct grid_cell *, int); void screen_alternate_off(struct screen *, struct grid_cell *, int); const char *screen_mode_to_string(int); -const char *screen_print(struct screen *); +const char *screen_print(struct screen *, int); /* window.c */ extern struct windows windows;