From 6c5cc400394005459ee61b32a49bbbeb4baef432 Mon Sep 17 00:00:00 2001 From: Michael Grant Date: Mon, 3 Nov 2025 21:56:15 +0100 Subject: [PATCH] Bugfix, more changes to allow xoff and yoff to be int. --- screen-redraw.c | 17 +++++++++-------- screen-write.c | 40 +++++++++++++--------------------------- server-client.c | 1 + tmux.h | 8 ++++---- tty.c | 30 +++++++++++++++++++++--------- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index 7cc4f955..c467b951 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -126,7 +126,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, u_int px, u_int py) { struct options *oo = wp->window->options; - u_int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy; + int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy; int hsplit = 0, vsplit = 0, pane_status = ctx->pane_status; int pane_scrollbars = ctx->pane_scrollbars, sb_w = 0; int sb_pos; @@ -137,7 +137,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, sb_pos = 0; /* Inside pane. */ - if ((int)px >= wp->xoff && px < ex && (int)py >= wp->yoff && py < ey) + if ((int)px >= wp->xoff && (int)px < ex && (int)py >= wp->yoff && (int)py < ey) return (SCREEN_REDRAW_INSIDE); /* Get pane indicator. */ @@ -157,7 +157,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, * Left/right borders. The wp->sy / 2 test is to colour only half the * active window's border when there are two panes. */ - if ((wp->yoff == 0 || (int)py >= wp->yoff - 1) && py <= ey) { + if ((wp->yoff == 0 || (int)py >= wp->yoff - 1) && (int)py <= ey) { if (sb_pos == PANE_SCROLLBARS_LEFT) { if (wp->xoff - sb_w == 0 && px == wp->sx + sb_w) if (!hsplit || (hsplit && py <= wp->sy / 2)) @@ -192,18 +192,18 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, } else { if (sb_pos == PANE_SCROLLBARS_LEFT) { if ((wp->xoff - sb_w == 0 || (int)px >= wp->xoff - sb_w) && - (px <= ex || (sb_w != 0 && px < ex + sb_w))) { + ((int)px <= ex || (sb_w != 0 && (int)px < ex + sb_w))) { if (wp->yoff != 0 && (int)py == wp->yoff - 1) return (SCREEN_REDRAW_BORDER_TOP); - if (py == ey) + if ((int)py == ey) return (SCREEN_REDRAW_BORDER_BOTTOM); } } else { /* sb_pos == PANE_SCROLLBARS_RIGHT */ if ((wp->xoff == 0 || (int)px >= wp->xoff) && - (px <= ex || (sb_w != 0 && px < ex + sb_w))) { + ((int)px <= ex || (sb_w != 0 && (int)px < ex + sb_w))) { if (wp->yoff != 0 && (int)py == wp->yoff - 1) return (SCREEN_REDRAW_BORDER_TOP); - if (py == ey) + if ((int)py == ey) return (SCREEN_REDRAW_BORDER_BOTTOM); } } @@ -950,7 +950,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, struct window *w; static struct visible_ranges vr = {NULL, NULL, 0, 0}; int found_self, sb_w; - u_int r, s, lb, rb, tb, bb; + u_int lb, rb, tb, bb; + u_int r, s; int pane_scrollbars; /* For efficiency vr is static and space reused. */ diff --git a/screen-write.c b/screen-write.c index 083290b3..c9ff2178 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1780,8 +1780,9 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, struct screen_write_citem *ci, *tmp; struct screen_write_cline *cl; u_int y, cx, cy, last, items = 0, r; - u_int r_start, r_end, ci_start, ci_end; - u_int wr_start, wr_end, wr_length, sx, xoff, yoff; + u_int wr_start, wr_end, wr_length, wsx, wsy; + int r_start, r_end, ci_start, ci_end; + int xoff, yoff; struct tty_ctx ttyctx; struct visible_ranges *vr; struct window_pane *wp = ctx->wp; @@ -1793,6 +1794,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ctx->scrolled = s->rlower - s->rupper + 1; screen_write_initctx(ctx, &ttyctx, 1); + if (wp->yoff + wp->sy > wp->window->sy) + ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); ttyctx.num = ctx->scrolled; ttyctx.bg = ctx->bg; tty_write(tty_cmd_scrollup, &ttyctx); @@ -1811,20 +1814,24 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, /* The xoff and width of window pane relative to the window we * are writing to relative to the visible_ranges array. */ if (wp != NULL) { - sx = wp->window->sx; + wsx = wp->window->sx; + wsy = wp->window->sy; xoff = wp->xoff; yoff = wp->yoff; } else { - sx = screen_size_x(s); + wsx = screen_size_x(s); + wsy = screen_size_y(s); xoff = 0; yoff = 0; } for (y = 0; y < screen_size_y(s); y++) { + if (y + yoff >= wsy) + continue; cl = &ctx->s->write_list[y]; vr = screen_redraw_get_visible_ranges(wp, 0, y + yoff, - sx); + wsx); last = UINT_MAX; TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { @@ -1855,7 +1862,6 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, if (wr_length <= 0) continue; - screen_write_set_cursor(ctx, wr_start, y); if (ci->type == CLEAR) { screen_write_initctx(ctx, &ttyctx, 1); @@ -1879,6 +1885,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, } } } + s->cx = cx; s->cy = cy; log_debug("%s: flushed %u items (%s)", __func__, items, from); @@ -2014,28 +2021,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) u_int sx = screen_size_x(s), sy = screen_size_y(s); u_int width = ud->width, xx, not_wrap; int selected, skip = 1; - struct window_pane *base_wp = ctx->wp, *wp; - struct window *w; - u_int found_self, px, py; - /* early attempt. - if (base_wp != NULL) { - w = base_wp->window; - px = ctx->s->cx; - py = ctx->s->cy; - TAILQ_FOREACH(wp, &w->panes, zentry) { - if (wp == base_wp) { - found_self = 1; - continue; - } - if (found_self && wp->layout_cell == NULL && - !(wp->flags & PANE_MINIMISED) && - ((int)py >= wp->yoff && (int)py <= wp->yoff + (int)wp->sy) && - ((int)px >= wp->xoff && (int)px <= wp->xoff + (int)wp->sx)) - return; - } - } - */ /* Ignore padding cells. */ if (gc->flags & GRID_FLAG_PADDING) return; diff --git a/server-client.c b/server-client.c index 87f8196f..60a6ddb3 100644 --- a/server-client.c +++ b/server-client.c @@ -605,6 +605,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, sb_w = 0; sb_pad = 0; } + /* xxxx isn't this only for tiled panes at the top or bottom of the window? */ if (pane_status == PANE_STATUS_TOP) line = wp->yoff - 1; else if (pane_status == PANE_STATUS_BOTTOM) diff --git a/tmux.h b/tmux.h index 974ce600..ad071260 100644 --- a/tmux.h +++ b/tmux.h @@ -1642,10 +1642,10 @@ struct tty_ctx { u_int orlower; /* Target region (usually pane) offset and size. */ - u_int xoff; - u_int yoff; - u_int rxoff; - u_int ryoff; + int xoff; + int yoff; + int rxoff; + int ryoff; u_int sx; u_int sy; diff --git a/tty.c b/tty.c index d31246ce..064bb4b7 100644 --- a/tty.c +++ b/tty.c @@ -1121,23 +1121,23 @@ static int tty_clamp_line(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, u_int nx, u_int *i, u_int *x, u_int *rx, u_int *ry) { - u_int xoff = ctx->rxoff + px; + int xoff = ctx->rxoff + px; if (!tty_is_visible(tty, ctx, px, py, nx, 1)) return (0); *ry = ctx->yoff + py - ctx->woy; - if (xoff >= ctx->wox && xoff + nx <= ctx->wox + ctx->wsx) { + if (xoff >= (int)ctx->wox && xoff + nx <= ctx->wox + ctx->wsx) { /* All visible. */ *i = 0; *x = ctx->xoff + px - ctx->wox; *rx = nx; - } else if (xoff < ctx->wox && xoff + nx > ctx->wox + ctx->wsx) { + } else if (xoff < (int)ctx->wox && xoff + nx > ctx->wox + ctx->wsx) { /* Both left and right not visible. */ *i = ctx->wox; *x = 0; *rx = ctx->wsx; - } else if (xoff < ctx->wox) { + } else if (xoff < (int)ctx->wox) { /* Left not visible. */ *i = ctx->wox - (ctx->xoff + px); *x = 0; @@ -2065,7 +2065,7 @@ void tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - u_int i; + u_int i, rlower; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || @@ -2085,11 +2085,16 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); + if (tty->rlower < ctx->wsy) + rlower = tty->rlower; + else + rlower = ctx->wsy - 1; + if (ctx->num == 1 || !tty_term_has(tty->term, TTYC_INDN)) { if (!tty_use_margin(tty)) - tty_cursor(tty, 0, tty->rlower); + tty_cursor(tty, 0, rlower); else - tty_cursor(tty, tty->rright, tty->rlower); + tty_cursor(tty, tty->rright, rlower); for (i = 0; i < ctx->num; i++) tty_putc(tty, '\n'); } else { @@ -2558,8 +2563,15 @@ tty_margin_off(struct tty *tty) static void tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) { - tty_margin(tty, ctx->xoff - ctx->wox, - ctx->xoff + ctx->sx - 1 - ctx->wox); + int l, r; + + l = ctx->xoff - ctx->wox; + r = ctx->xoff + ctx->sx - 1 - ctx->wox; + + if (l < 0) l = 0; + if (r < 0) r = 0; + + tty_margin(tty, l, r); } /* Set margin at absolute position. */