mirror of
https://github.com/tmux/tmux.git
synced 2026-09-05 21:20:45 +00:00
Avoid redrawing kitty images when terminal scrolling moves them.
This commit is contained in:
9
image.c
9
image.c
@@ -1291,8 +1291,15 @@ void
|
||||
image_redraw_scroll(struct screen_write_ctx *ctx, __unused u_int lines)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct window_pane *wp = ctx->wp;
|
||||
|
||||
image_redraw_area(ctx, 0, s->rupper, screen_size_x(s),
|
||||
if (wp == NULL)
|
||||
return;
|
||||
if (!image_grid_check_area(s->grid, 0, s->grid->hsize + s->rupper,
|
||||
screen_size_x(s), s->rlower - s->rupper + 1))
|
||||
return;
|
||||
redraw_damage_window_scroll(wp->window, wp->xoff,
|
||||
wp->yoff + s->rupper, screen_size_x(s),
|
||||
s->rlower - s->rupper + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,8 @@ struct redraw_damage {
|
||||
u_int y;
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
int flags;
|
||||
#define REDRAW_DAMAGE_SCROLL 0x1
|
||||
|
||||
TAILQ_ENTRY(redraw_damage) entry;
|
||||
};
|
||||
@@ -1104,6 +1106,9 @@ redraw_free_damage(struct window *w)
|
||||
free(rd);
|
||||
}
|
||||
w->damage_count = 0;
|
||||
#ifdef ENABLE_IMAGES
|
||||
w->image_scroll_pending = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Collapse all pending damage for a window into one rectangle - its union. */
|
||||
@@ -1130,6 +1135,7 @@ redraw_collapse_damage(struct window *w)
|
||||
x1 = rd->x + rd->sx;
|
||||
if (rd->y + rd->sy > y1)
|
||||
y1 = rd->y + rd->sy;
|
||||
first->flags &= rd->flags;
|
||||
if (rd != first) {
|
||||
TAILQ_REMOVE(&w->damage, rd, entry);
|
||||
free(rd);
|
||||
@@ -1151,8 +1157,9 @@ redraw_collapse_damage(struct window *w)
|
||||
*
|
||||
* This only records damage - nothing consumes it yet.
|
||||
*/
|
||||
void
|
||||
redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy)
|
||||
static void
|
||||
redraw_damage_window_flags(struct window *w, u_int x, u_int y, u_int sx,
|
||||
u_int sy, int flags)
|
||||
{
|
||||
struct redraw_damage *rd;
|
||||
u_int x0, y0, x1, y1, area, union_area;
|
||||
@@ -1186,6 +1193,7 @@ redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy)
|
||||
rd->y = y0;
|
||||
rd->sx = x1 - x0;
|
||||
rd->sy = y1 - y0;
|
||||
rd->flags &= flags;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1194,6 +1202,7 @@ redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy)
|
||||
rd->y = y;
|
||||
rd->sx = sx;
|
||||
rd->sy = sy;
|
||||
rd->flags = flags;
|
||||
TAILQ_INSERT_TAIL(&w->damage, rd, entry);
|
||||
w->damage_count++;
|
||||
|
||||
@@ -1201,6 +1210,46 @@ redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy)
|
||||
redraw_collapse_damage(w);
|
||||
}
|
||||
|
||||
void
|
||||
redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy)
|
||||
{
|
||||
redraw_damage_window_flags(w, x, y, sx, sy, 0);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
/* Record damage caused by an image moving with a terminal scroll. */
|
||||
void
|
||||
redraw_damage_window_scroll(struct window *w, u_int x, u_int y, u_int sx,
|
||||
u_int sy)
|
||||
{
|
||||
if (!w->image_scroll_pending) {
|
||||
w->image_scroll_epoch++;
|
||||
w->image_scroll_pending = 1;
|
||||
}
|
||||
redraw_damage_window_flags(w, x, y, sx, sy, REDRAW_DAMAGE_SCROLL);
|
||||
}
|
||||
|
||||
/* Remember whether this client used terminal scrolling for the damage. */
|
||||
void
|
||||
redraw_image_scroll_result(struct tty *tty, const struct tty_ctx *ctx,
|
||||
int failed)
|
||||
{
|
||||
struct window_pane *wp = ctx->arg;
|
||||
struct window *w;
|
||||
|
||||
if (wp == NULL || (w = wp->window) == NULL || !w->image_scroll_pending)
|
||||
return;
|
||||
if (tty->image_scroll_window != w ||
|
||||
tty->image_scroll_epoch != w->image_scroll_epoch) {
|
||||
tty->image_scroll_window = w;
|
||||
tty->image_scroll_epoch = w->image_scroll_epoch;
|
||||
tty->image_scroll_failed = 0;
|
||||
}
|
||||
if (failed)
|
||||
tty->image_scroll_failed = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Record damage for every pane border-status row in a window. */
|
||||
static void
|
||||
redraw_damage_window_pane_status(struct window *w)
|
||||
@@ -2227,7 +2276,7 @@ redraw_damage_draw_pane_prompt(struct redraw_draw_ctx *dctx,
|
||||
*/
|
||||
static void
|
||||
redraw_draw_damage_rect(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
||||
u_int sx, u_int sy)
|
||||
u_int sx, u_int sy, int skip_images)
|
||||
{
|
||||
struct redraw_scene *scene = dctx->scene;
|
||||
struct redraw_line *line;
|
||||
@@ -2246,6 +2295,8 @@ redraw_draw_damage_rect(struct redraw_draw_ctx *dctx, u_int x, u_int y,
|
||||
|
||||
for (enum redraw_image_phase phase = REDRAW_IMAGES_BEFORE;
|
||||
phase <= REDRAW_IMAGES_AFTER; phase++) {
|
||||
if (skip_images && phase != REDRAW_TEXT)
|
||||
continue;
|
||||
for (yy = y; yy < y + sy; yy++) {
|
||||
line = &scene->lines[yy];
|
||||
if (dctx->flags & REDRAW_STATUS_TOP)
|
||||
@@ -2321,6 +2372,7 @@ redraw_client_damage(struct client *c)
|
||||
struct redraw_draw_ctx dctx;
|
||||
struct redraw_damage *rd;
|
||||
u_int ox, oy, sx, sy, x0, y0, x1, y1;
|
||||
int skip_images;
|
||||
|
||||
if (TAILQ_EMPTY(&w->damage))
|
||||
return;
|
||||
@@ -2335,6 +2387,15 @@ redraw_client_damage(struct client *c)
|
||||
tty_update_mode(&c->tty, c->tty.mode & ~CURSOR_MODES, NULL);
|
||||
|
||||
TAILQ_FOREACH(rd, &w->damage, entry) {
|
||||
skip_images = 0;
|
||||
#ifdef ENABLE_IMAGES
|
||||
if ((rd->flags & REDRAW_DAMAGE_SCROLL) &&
|
||||
(image_backend_flags(&c->tty) & IMAGE_BACKEND_SCROLLS) &&
|
||||
c->tty.image_scroll_window == w &&
|
||||
c->tty.image_scroll_epoch == w->image_scroll_epoch &&
|
||||
!c->tty.image_scroll_failed)
|
||||
skip_images = 1;
|
||||
#endif
|
||||
x0 = (rd->x > ox) ? rd->x : ox;
|
||||
y0 = (rd->y > oy) ? rd->y : oy;
|
||||
x1 = (rd->x + rd->sx < ox + sx) ? rd->x + rd->sx : ox + sx;
|
||||
@@ -2344,6 +2405,6 @@ redraw_client_damage(struct client *c)
|
||||
log_debug("%s: %s composing damage %u,%u %ux%u", __func__,
|
||||
c->name, x0 - ox, y0 - oy, x1 - x0, y1 - y0);
|
||||
redraw_draw_damage_rect(&dctx, x0 - ox, y0 - oy, x1 - x0,
|
||||
y1 - y0);
|
||||
y1 - y0, skip_images);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1774,7 +1774,7 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
image_redraw_all(ctx);
|
||||
image_redraw_scroll(ctx, 1);
|
||||
#endif
|
||||
|
||||
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
|
||||
@@ -1904,7 +1904,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
||||
lines = s->rlower - s->rupper + 1;
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
image_redraw_all(ctx);
|
||||
image_redraw_scroll(ctx, lines);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < lines; i++)
|
||||
|
||||
12
tmux.h
12
tmux.h
@@ -1519,6 +1519,10 @@ struct window {
|
||||
|
||||
struct redraw_damages damage;
|
||||
u_int damage_count;
|
||||
#ifdef ENABLE_IMAGES
|
||||
uint64_t image_scroll_epoch;
|
||||
int image_scroll_pending;
|
||||
#endif
|
||||
|
||||
struct menu_data *menu;
|
||||
u_int menu_last_px;
|
||||
@@ -1897,6 +1901,9 @@ struct tty {
|
||||
#ifdef ENABLE_IMAGES
|
||||
const struct image_backend *image_backend;
|
||||
void *image_data;
|
||||
struct window *image_scroll_window;
|
||||
uint64_t image_scroll_epoch;
|
||||
int image_scroll_failed;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -3716,6 +3723,11 @@ int redraw_client_has_window(struct client *, struct window *);
|
||||
void redraw_invalidate_scene(struct window *);
|
||||
void redraw_invalidate_all_scenes(void);
|
||||
void redraw_damage_window(struct window *, u_int, u_int, u_int, u_int);
|
||||
#ifdef ENABLE_IMAGES
|
||||
void redraw_damage_window_scroll(struct window *, u_int, u_int, u_int,
|
||||
u_int);
|
||||
void redraw_image_scroll_result(struct tty *, const struct tty_ctx *, int);
|
||||
#endif
|
||||
void redraw_free_damage(struct window *);
|
||||
void redraw_client_damage(struct client *);
|
||||
int redraw_get_status_border_cell_type(struct redraw_span **, u_int);
|
||||
|
||||
21
tty.c
21
tty.c
@@ -1765,10 +1765,17 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
|
||||
ctx->sx == 1 ||
|
||||
ctx->sy == 1 ||
|
||||
c->overlay_check != NULL) {
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 1);
|
||||
#endif
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 0);
|
||||
#endif
|
||||
|
||||
tty_default_attributes(tty, ctx->bg, &ctx->style_ctx);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
@@ -1836,10 +1843,17 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
|
||||
ctx->sx == 1 ||
|
||||
ctx->sy == 1 ||
|
||||
c->overlay_check != NULL) {
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 1);
|
||||
#endif
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 0);
|
||||
#endif
|
||||
|
||||
tty_default_attributes(tty, ctx->bg, &ctx->style_ctx);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
@@ -1876,10 +1890,17 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
|
||||
ctx->sx == 1 ||
|
||||
ctx->sy == 1 ||
|
||||
c->overlay_check != NULL) {
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 1);
|
||||
#endif
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
redraw_image_scroll_result(tty, ctx, 0);
|
||||
#endif
|
||||
|
||||
tty_default_attributes(tty, ctx->bg, &ctx->style_ctx);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
|
||||
Reference in New Issue
Block a user