From 3e6c6576ab14a9aff8c7765c7fa5e0b979d601e6 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 14 Oct 2026 12:48:50 +0000 Subject: [PATCH] Track window scrolling for damage. --- screen-redraw.c | 36 +++++++++++++++++++++++++++++++++++- tmux.h | 10 +++++++++- tty.c | 10 +++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index ad6f52d12..b3c2f6f77 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-redraw.c,v 1.165 2026/10/14 12:38:18 nicm Exp $ */ +/* $OpenBSD: screen-redraw.c,v 1.166 2026/10/14 12:48:50 nicm Exp $ */ /* * Copyright (c) 2026 Nicholas Marriott @@ -1111,6 +1111,7 @@ redraw_free_damage(struct window *w) free(rd); } w->damage_count = 0; + w->scroll_pending = 0; } /* Collapse all pending damage for a window into one rectangle. */ @@ -1209,6 +1210,39 @@ redraw_damage_window(struct window *w, u_int x, u_int y, u_int sx, u_int sy) redraw_apply_window_damage(w, x, y, sx, sy, 0); } +/* Record damage caused by terminal scrolling. */ +void +redraw_damage_scroll(struct window *w, u_int x, u_int y, u_int sx, u_int sy) +{ + if (!w->scroll_pending) { + w->scroll_generation++; + w->scroll_pending = 1; + } + redraw_apply_window_damage(w, x, y, sx, sy, REDRAW_DAMAGE_SCROLL); +} + +/* Remember whether this client used terminal scrolling for the damage. */ +void +redraw_scroll_result(struct tty *tty, const struct tty_ctx *ctx, int failed) +{ + struct window_pane *wp = ctx->arg; + struct window *w; + + if (wp == NULL) + return; + w = wp->window; + if (!w->scroll_pending) + return; + if (tty->scroll_window != w || + tty->scroll_generation != w->scroll_generation) { + tty->scroll_window = w; + tty->scroll_generation = w->scroll_generation; + tty->scroll_failed = 0; + } + if (failed) + tty->scroll_failed = 1; +} + /* Mark all cached redraw scenes as out of date. */ void redraw_invalidate_all_scenes(void) diff --git a/tmux.h b/tmux.h index 4ea5e7671..f0c6ca61b 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1462 2026/10/14 12:33:46 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1463 2026/10/14 12:48:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1464,6 +1464,8 @@ struct window { struct redraw_damages damage; u_int damage_count; + uint64_t scroll_generation; + int scroll_pending; struct menu_data *menu; u_int menu_last_px; @@ -1835,6 +1837,10 @@ struct tty { struct event key_timer; struct tty_key *key_tree; + + struct window *scroll_window; + uint64_t scroll_generation; + int scroll_failed; }; /* Terminal command context. */ @@ -3620,6 +3626,8 @@ 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); +void redraw_damage_scroll(struct window *, u_int, u_int, u_int, u_int); +void redraw_scroll_result(struct tty *, const struct tty_ctx *, int); void redraw_free_damage(struct window *); void redraw_client_damage(struct client *); int redraw_get_status_border_cell_type(struct redraw_span **, u_int); diff --git a/tty.c b/tty.c index 982e65669..feae568c4 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.488 2026/10/14 11:54:55 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.489 2026/10/14 12:48:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1669,10 +1669,12 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_RIN)) || ctx->sx == 1 || ctx->sy == 1) { + redraw_scroll_result(tty, ctx, 1); tty_redraw_region(tty, ctx); return; } + redraw_scroll_result(tty, ctx, 0); tty_default_attributes(tty, ctx->bg, &ctx->style_ctx); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); @@ -1697,10 +1699,12 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_CSR) || ctx->sx == 1 || ctx->sy == 1) { + redraw_scroll_result(tty, ctx, 1); tty_redraw_region(tty, ctx); return; } + redraw_scroll_result(tty, ctx, 0); tty_default_attributes(tty, ctx->bg, &ctx->style_ctx); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); @@ -1735,10 +1739,12 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_CSR) || ctx->sx == 1 || ctx->sy == 1) { + redraw_scroll_result(tty, ctx, 1); tty_redraw_region(tty, ctx); return; } + redraw_scroll_result(tty, ctx, 0); tty_default_attributes(tty, ctx->bg, &ctx->style_ctx); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); @@ -1773,10 +1779,12 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_RIN)) || ctx->sx == 1 || ctx->sy == 1) { + redraw_scroll_result(tty, ctx, 1); tty_redraw_region(tty, ctx); return; } + redraw_scroll_result(tty, ctx, 0); tty_default_attributes(tty, ctx->bg, &ctx->style_ctx); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);