aboutsummaryrefslogtreecommitdiffstats
path: root/src/graphics.c
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-07 15:54:34 +0200
committeruser <user@clank>2026-09-07 15:54:34 +0200
commit2a440fbc01c4e4afd58e15ace5eddd4a171d15ef (patch)
tree06cef911eca321ea6b00ed8aabc91b5242077e10 /src/graphics.c
parentMerge branch 'graphics-fixes' (PR #2 from iksteen): five fixes to the kitty p... (diff)
downloadslosh-2a440fbc01c4e4afd58e15ace5eddd4a171d15ef.tar.gz
slosh-2a440fbc01c4e4afd58e15ace5eddd4a171d15ef.tar.xz
slosh-2a440fbc01c4e4afd58e15ace5eddd4a171d15ef.zip
graphics: a retransmit invalidates every placement of the image
Replacing an image's pixels deletes all of its placements on the client -- kitty drops them when the data is replaced, which is the very fact the place-once logic leans on. But the invalidation rode a local in one gfx_place() call, so only the placement said in the same breath as the transmit was owed again. The image's other placements -- a second one elsewhere, the other pieces of one a float has cut -- were judged unchanged against a client that no longer holds them, and stayed unsaid: a picture the client deleted and we believe it still has, gone until something moves it. Masked before place-once by the every-frame re-emission, so this is the regression that fix bought. The transmit now un-marks every placement of its image, and each is said again as its gfx_place() comes around. The live check drives one image placed twice, then replaces its pixels and places both again: both must reach the client after the second transmit, where the old code re-sent one.
Diffstat (limited to 'src/graphics.c')
-rw-r--r--src/graphics.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/graphics.c b/src/graphics.c
index 77b3b7f..86a5b56 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -220,6 +220,14 @@ void gfx_place(graphics_t *g, const gfx_req_t *req) {
transmit(g, img, req->px_w, req->px_h, req->format, req->compression,
req->data, req->data_len);
transmitted = img->sent;
+ /* Replacing an image's data deletes every placement of it on the client,
+ * not just the one this call is about to make: kitty drops them all. The
+ * other placements of this image -- the other pieces of a cut one, a
+ * second placement in another spot -- are invalidated here, or a `same`
+ * verdict below leaves them un-said while the client no longer has them. */
+ if (transmitted)
+ for (size_t i = 0; i < g->nplaces; i++)
+ if (g->places[i].out_id == img->out_id) g->places[i].shown = false;
}
uint32_t pid = req->place_id ? req->place_id : 1;
@@ -253,7 +261,8 @@ void gfx_place(graphics_t *g, const gfx_req_t *req) {
bool same = slot->shown && !transmitted && slot->col == req->col &&
slot->row == req->row && slot->cols == req->cols &&
slot->rows == req->rows && slot->x_off == req->x_off &&
- slot->y_off == req->y_off && slot->scale_cols == req->scale_cols &&
+ slot->y_off == req->y_off &&
+ slot->scale_cols == req->scale_cols &&
slot->scale_rows == req->scale_rows && slot->sx == req->sx &&
slot->sy == req->sy && slot->sw == req->sw && slot->sh == req->sh;
slot->col = req->col;