diff options
| author | user <user@clank> | 2026-09-07 15:52:00 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-07 15:52:00 +0200 |
| commit | e9147fba11b735259a90089dd7207853ff49a3ad (patch) | |
| tree | 6dc86b56987c7bb2e2dba4a3151cf4576efab2b0 /include | |
| parent | screen: commit a wide cell's tail to prev, or the diff leaves a hole (diff) | |
| parent | app: cut the modals, toasts and splash out of the images under them (diff) | |
| download | slosh-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.h | 3 | ||||
| -rw-r--r-- | include/app_internal.h | 16 | ||||
| -rw-r--r-- | include/graphics.h | 26 |
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); |
