aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-07 15:52:00 +0200
committeruser <user@clank>2026-09-07 15:52:00 +0200
commite9147fba11b735259a90089dd7207853ff49a3ad (patch)
tree6dc86b56987c7bb2e2dba4a3151cf4576efab2b0 /include
parentscreen: commit a wide cell's tail to prev, or the diff leaves a hole (diff)
parentapp: cut the modals, toasts and splash out of the images under them (diff)
downloadslosh-e9147fba11b735259a90089dd7207853ff49a3ad.tar.gz
slosh-e9147fba11b735259a90089dd7207853ff49a3ad.tar.xz
slosh-e9147fba11b735259a90089dd7207853ff49a3ad.zip
Merge branch 'graphics-fixes' (PR #2 from iksteen): five fixes to the kitty passthrough, found through a mirror
One synchronized message per frame with cells and images together, a placement said once rather than every frame, z=0 stated so a mirror knows where the picture goes, a float cutting an image into pieces instead of erasing it, and overlays cut out of the images under them. Found running slosh inside shellglass, real on a terminal too.
Diffstat (limited to 'include')
-rw-r--r--include/app.h3
-rw-r--r--include/app_internal.h16
-rw-r--r--include/graphics.h26
3 files changed, 42 insertions, 3 deletions
diff --git a/include/app.h b/include/app.h
index 6cf6886..106d54a 100644
--- a/include/app.h
+++ b/include/app.h
@@ -29,6 +29,9 @@ const char *app_graphics_view(app_t *a, graphics_t *state, uint16_t x,
uint16_t y, uint16_t cols, uint16_t rows,
size_t *len);
void app_graphics_reset(app_t *a);
+/* One client's own graphics state, after its screen was cleared: the
+ * placements it was holding went with the clear and are owed again. */
+void app_graphics_view_repaint(graphics_t *state);
/* Did the last app_graphics() stream reach the client? Undelivered frames
* are regenerated: transmissions repeat and deletions stay owed. */
void app_graphics_commit(app_t *a, bool delivered);
diff --git a/include/app_internal.h b/include/app_internal.h
index 38a1a6d..af59b6f 100644
--- a/include/app_internal.h
+++ b/include/app_internal.h
@@ -10,6 +10,10 @@
#include "expr.h"
#include "shader.h"
+/* How many overlays one frame can have cut out of its images: the modal box
+ * (one at a time), three toasts, the splash, and room to spare. */
+#define APP_MAX_OVERLAYS 8
+
/* A chain attached to one pane, with the programs its expressions compiled to
* kept beside it. Together because they are one lifetime: freeing the chain
* without the programs leaks, and freeing the programs without the chain leaves
@@ -229,6 +233,16 @@ struct app {
} toasts[3];
size_t ntoasts;
+ /* Where this frame's overlays landed: a modal's box, a toast, the splash.
+ * The compositor needs no such list -- painted later is on top -- but an
+ * image is not painted, it is placed, and the client's terminal draws it
+ * over the cells whatever order they arrived in. So the graphics pass cuts
+ * the overlays out of a placement the way it cuts out a float, and this is
+ * how it learns where they were. Rebuilt every compose; a rect that is not
+ * re-registered is one that is no longer on screen. */
+ rect_t overlays[APP_MAX_OVERLAYS];
+ size_t noverlays;
+
/* What a selection put on the clipboard, kept for middle-click paste (the
* X11 primary-selection habit) and handed to the client as OSC 52. */
char *clipboard;
@@ -444,6 +458,8 @@ void rename_begin(app_t *a, uint32_t id);
void rename_tab_begin(app_t *a, uint32_t id);
void draw_splash(app_t *a, screen_t *s);
+/* Say that a rect was painted over the panes this frame; see `overlays`. */
+void app_overlay(app_t *a, rect_t r);
/* round two */
void drop_pane_on_strip(app_t *a);
diff --git a/include/graphics.h b/include/graphics.h
index 13cc5dc..cebb53c 100644
--- a/include/graphics.h
+++ b/include/graphics.h
@@ -26,10 +26,20 @@ typedef struct {
bool sent;
} gfx_image_t;
-/* One placement on screen this frame. */
+/* One placement on screen this frame -- or one visible piece of it, when
+ * something on top has cut it into more than one rectangle. */
typedef struct {
uint32_t out_id;
- uint32_t place_id;
+ uint32_t place_id; /* the id the program chose */
+ /* Which visible rectangle of that placement this is. A placement nothing
+ * covers has one piece; a float across the middle of an image leaves two,
+ * and a float in a corner leaves two or three -- each of them a placement
+ * of its own on the wire, which is the only shape the protocol has. */
+ uint16_t piece;
+ /* The placement id the client is told, ours to hand out: the pieces of one
+ * placement need an id each, and the program's own id is one number that
+ * cannot be several. */
+ uint32_t wire_id;
uint16_t col, row; /* screen cells */
uint16_t cols, rows;
/* Where the image starts *inside* its first cell, in pixels. This is what
@@ -41,6 +51,9 @@ typedef struct {
uint16_t scale_cols, scale_rows;
uint32_t sx, sy, sw, sh; /* source rectangle, in image pixels */
bool live;
+ /* The client is holding this placement, exactly as described above. A
+ * placement the terminal already has is not re-sent: see gfx_flush(). */
+ bool shown;
} gfx_place_t;
graphics_t *gfx_new(void);
@@ -60,6 +73,7 @@ typedef struct {
uint32_t src_id; /* the id the program chose */
uint64_t gen; /* image generation, so a changed image is re-sent */
uint32_t place_id;
+ uint16_t piece; /* which visible rectangle of it */
uint16_t col, row; /* screen cells */
uint16_t cols, rows; /* cells covered */
uint16_t scale_cols, scale_rows; /* cells to scale into, 0 for natural */
@@ -86,8 +100,14 @@ char *gfx_flush(graphics_t *g, size_t *out_len);
* commits counts as undelivered at the next gfx_begin(). */
void gfx_commit(graphics_t *g, bool delivered);
-/* Forget what the client has seen (it is a different client now). */
+/* Forget what the client has seen (it is a different client now, or its screen
+ * was cleared -- ESC[2J takes the images with it). Everything still on screen
+ * is transmitted and placed again on the next frame. */
void gfx_reset(graphics_t *g);
+/* The client's screen was cleared (a full repaint takes the images with it):
+ * every placement is owed again, while transmitted pixels and owed deletions
+ * stand. */
+void gfx_repaint(graphics_t *g);
/* Drop everything belonging to a pane that is gone. */
void gfx_forget_pane(graphics_t *g, uint32_t pane);