mirror of
https://github.com/tmux/tmux.git
synced 2026-08-28 09:31:34 +00:00
screen-write, tty, popup, window: fix remaining untested damage gaps
Two more fixes based on Michael K. Darling's branch
(github.com/darlingm/tmux, pr5516-regression-fixes), taken as-is -
neither is caught by any test in regress/ yet, found by code review
rather than a failing test:
- screen_write_redraw_cb() (screen-write.c) reported damage for only a
single row, using ttyctx->ocy as if every fallback redraw were a
single-cell write. But it's also the callback for cases that can
legitimately span many rows - a large scroll-region fallback
(tty_redraw_region(), when tty_large_region() or the pane is
obscured), a full reset, and entering/leaving the alternate screen.
For those, only the top row of the affected area ever got marked as
damaged, leaving the rest stale until an unrelated redraw happened to
cover it. Changed the shared tty_ctx_redraw_cb typedef to carry
(py, ny) - the actual row range - and updated every call site to pass
the range it actually knows about, instead of hardcoding a single
row.
- window_pane_redraw_floating() (window.c) never refreshed the status
line after moving/resizing a floating pane, so a status format
depending on that pane's geometry (e.g. #{pane_width}) could go
stale until an unrelated status refresh happened. Added a
server_status_window(w) call.
Also confirmed the window_pane_scrollbar_intersects() parameter
naming cleanup (loop -> wp) discussed earlier was already done in an
earlier "Cleanup." commit - nothing left to do there.
All 9 tests in regress/ plus the two pre-existing floating-pane tests
plus a further 19-test sweep of redraw/tty/input/sync-adjacent
regress tests pass.
Co-Authored-By: Michael K. Darling <darlingm@gmail.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
3
popup.c
3
popup.c
@@ -135,7 +135,8 @@ popup_reapply_styles(struct popup_data *pd)
|
||||
}
|
||||
|
||||
static void
|
||||
popup_redraw_cb(const struct tty_ctx *ttyctx)
|
||||
popup_redraw_cb(const struct tty_ctx *ttyctx, __unused u_int py,
|
||||
__unused u_int ny)
|
||||
{
|
||||
struct popup_data *pd = ttyctx->arg;
|
||||
|
||||
|
||||
@@ -122,21 +122,18 @@ screen_write_set_cursor(struct screen_write_ctx *ctx, int cx, int cy)
|
||||
|
||||
/*
|
||||
* Called when a write could not be applied directly to the terminal and
|
||||
* needs a redraw instead. Report damage for just the row the write was
|
||||
* targeting rather than the whole pane - ttyctx->ocy is the cursor row
|
||||
* within the pane's own screen at the point the write was issued, and
|
||||
* wp->yoff is already adjusted past any top pane-border-status row, so
|
||||
* wp->yoff + ocy is the correct window-coordinate row.
|
||||
* needs a redraw instead. Report damage for the requested rows. wp->yoff is
|
||||
* already adjusted past any top pane-border-status row, so wp->yoff + py is
|
||||
* the correct window-coordinate row.
|
||||
*/
|
||||
static void
|
||||
screen_write_redraw_cb(const struct tty_ctx *ttyctx)
|
||||
screen_write_redraw_cb(const struct tty_ctx *ttyctx, u_int py, u_int ny)
|
||||
{
|
||||
struct window_pane *wp = ttyctx->arg;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
redraw_damage_window(wp->window, wp->xoff, wp->yoff + ttyctx->ocy,
|
||||
wp->sx, 1);
|
||||
redraw_damage_window(wp->window, wp->xoff, wp->yoff + py, wp->sx, ny);
|
||||
}
|
||||
|
||||
/* Update context for client. */
|
||||
@@ -2164,7 +2161,7 @@ screen_write_fullredraw(struct screen_write_ctx *ctx)
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
/* Trim collected items. */
|
||||
@@ -3184,7 +3181,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
/* Turn alternate screen off. */
|
||||
@@ -3209,5 +3206,5 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
2
tmux.h
2
tmux.h
@@ -1844,7 +1844,7 @@ struct tty {
|
||||
};
|
||||
|
||||
/* Terminal command context. */
|
||||
typedef void (*tty_ctx_redraw_cb)(const struct tty_ctx *);
|
||||
typedef void (*tty_ctx_redraw_cb)(const struct tty_ctx *, u_int, u_int);
|
||||
typedef int (*tty_ctx_set_client_cb)(struct tty_ctx *, struct client *);
|
||||
struct tty_ctx {
|
||||
struct screen *s;
|
||||
|
||||
6
tty.c
6
tty.c
@@ -1104,7 +1104,7 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
|
||||
*/
|
||||
if (tty_large_region(tty, ctx) || ctx->flags & TTY_CTX_PANE_OBSCURED) {
|
||||
log_debug("%s: %s large region redraw", __func__, c->name);
|
||||
ctx->redraw_cb(ctx);
|
||||
ctx->redraw_cb(ctx, ctx->orupper, ctx->orlower - ctx->orupper + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2016,7 +2016,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
|
||||
c->overlay_check != NULL) {
|
||||
ctx->redraw_cb(ctx);
|
||||
ctx->redraw_cb(ctx, 0, ctx->sy);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2098,7 +2098,7 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
|
||||
tty->cy == tty->rlower)
|
||||
tty_draw_pane(tty, ctx, ctx->ocy);
|
||||
else
|
||||
ctx->redraw_cb(ctx);
|
||||
ctx->redraw_cb(ctx, ctx->ocy, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user