From d1719785606d6a8b977af37eca9e358ef8fc839d Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <hpj@hpjansson.org>
Date: Mon, 10 Feb 2025 13:21:02 +0100
Subject: [PATCH] Fix a case of failure to overwrite sixel image cells

When the cell to be overwritten contained part of an image, no update
would be issued if the backing cell character appeared unchanged.

We address this by issuing cell updates when the cell intersects with
an image, allowing images to e.g. be reliably erased with spaces.
---
 image.c        | 15 +++++++++++++++
 screen-write.c |  4 ++++
 tmux.h         |  1 +
 3 files changed, 20 insertions(+)

diff --git a/image.c b/image.c
index 43808785..71cbaeed 100644
--- a/image.c
+++ b/image.c
@@ -149,6 +149,21 @@ image_check_area(struct screen *s, u_int px, u_int py, u_int nx, u_int ny)
 	return (redraw);
 }
 
+int
+image_intersect_area(struct screen *s, u_int px, u_int py, u_int nx, u_int ny)
+{
+	struct image	*im;
+
+	TAILQ_FOREACH(im, &s->images, entry) {
+		if (py + ny <= im->py || py >= im->py + im->sy)
+			continue;
+		if (px + nx <= im->px || px >= im->px + im->sx)
+			continue;
+		return (1);
+	}
+	return (0);
+}
+
 int
 image_scroll_up(struct screen *s, u_int lines)
 {
diff --git a/screen-write.c b/screen-write.c
index bce56b8e..d28c3530 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -2022,6 +2022,10 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
 	if (skip) {
 		if (s->cx >= gl->cellsize)
 			skip = grid_cells_equal(gc, &grid_default_cell);
+#ifdef ENABLE_SIXEL
+		else if (image_intersect_area(s, s->cx, s->cy, width, 1))
+			skip = 0;
+#endif
 		else {
 			gce = &gl->celldata[s->cx];
 			if (gce->flags & GRID_FLAG_EXTENDED)
diff --git a/tmux.h b/tmux.h
index 84028cb0..7adea4de 100644
--- a/tmux.h
+++ b/tmux.h
@@ -3561,6 +3561,7 @@ int		 image_free_all(struct screen *);
 struct image	*image_store(struct screen *, struct sixel_image *);
 int		 image_check_line(struct screen *, u_int, u_int);
 int		 image_check_area(struct screen *, u_int, u_int, u_int, u_int);
+int		 image_intersect_area(struct screen *, u_int, u_int, u_int, u_int);
 int		 image_scroll_up(struct screen *, u_int);
 
 /* image-sixel.c */