Change the visible_ranges array to work more like the overlay_ranges array, except be able to grow.

This commit is contained in:
Michael Grant
2025-10-26 14:18:27 +00:00
parent cc83ca6628
commit 984fbacccf
3 changed files with 63 additions and 65 deletions

View File

@@ -545,7 +545,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
struct tty *tty = &c->tty; struct tty *tty = &c->tty;
struct window_pane *wp; struct window_pane *wp;
struct screen *s; struct screen *s;
struct visible_range *vr; struct visible_ranges *vr;
u_int i, x, width, xoff, yoff, size; u_int i, x, width, xoff, yoff, size;
log_debug("%s: %s @%u", __func__, c->name, w->id); log_debug("%s: %s @%u", __func__, c->name, w->id);
@@ -922,7 +922,7 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
* floating window pane). Returns a boolean. * floating window pane). Returns a boolean.
*/ */
int int
screen_redraw_is_visible(struct visible_range *vr, u_int px) screen_redraw_is_visible(struct visible_ranges *vr, u_int px)
{ {
u_int r; u_int r;
@@ -930,10 +930,10 @@ screen_redraw_is_visible(struct visible_range *vr, u_int px)
if (vr == NULL) if (vr == NULL)
return (1); return (1);
for (r=0; vr[r].nx != -1; r++) { for (r=0; r < vr->used; r++) {
if (vr[r].nx == 0) if (vr->nx[r] == 0)
continue; continue;
if ((px >= vr[r].px) && (px <= vr[r].px + vr[r].nx)) if ((px >= vr->px[r]) && (px <= vr->px[r] + vr->nx[r]))
return (1); return (1);
} }
return (0); return (0);
@@ -941,30 +941,30 @@ screen_redraw_is_visible(struct visible_range *vr, u_int px)
/* Construct ranges array for the line at starting at px,py of width /* Construct ranges array for the line at starting at px,py of width
cells of base_wp that are unobsructed. */ cells of base_wp that are unobsructed. */
struct visible_range * struct visible_ranges *
screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
u_int py, u_int width) { u_int py, u_int width) {
struct window_pane *wp; struct window_pane *wp;
struct window *w; struct window *w;
static struct visible_range *vr = NULL; static struct visible_ranges vr = {NULL, NULL, 0, 0};
static size_t size = 0, last;
int found_self, sb_w; int found_self, sb_w;
u_int r, s, lb, rb, tb, bb; u_int r, s, lb, rb, tb, bb;
int pane_scrollbars; int pane_scrollbars;
/* For efficiency ranges is static and space reused. */ /* For efficiency vr is static and space reused. */
if (vr == NULL) { if (vr.size == 0) {
vr = xcalloc(4, sizeof(struct visible_range *)); vr.px = xcalloc(1, sizeof(u_int));
size = 4; vr.nx = xcalloc(1, sizeof(u_int));
vr.size = 1;
} }
/* Start with the entire width of the range. */ /* Start with the entire width of the range. */
vr[0].px = px; vr.px[0] = px;
vr[0].nx = width; vr.nx[0] = width;
last = 1; vr.used = 1;
if (base_wp == NULL) if (base_wp == NULL)
return (vr); return (&vr);
w = base_wp->window; w = base_wp->window;
pane_scrollbars = options_get_number(w->options, "pane-scrollbars"); pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
@@ -987,62 +987,58 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
if (window_pane_show_scrollbar(wp, pane_scrollbars)) if (window_pane_show_scrollbar(wp, pane_scrollbars))
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad; sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
for (r=0; r<last; r++) { for (r=0; r < vr.used; r++) {
lb = wp->xoff - 1; lb = wp->xoff - 1;
rb = wp->xoff + wp->sx + sb_w + 1; rb = wp->xoff + wp->sx + sb_w + 1;
/* If the left edge of floating wp /* If the left edge of floating wp
falls inside this range and right falls inside this range and right
edge covers up to right of range, edge covers up to right of range,
then shrink left edge of range. */ then shrink left edge of range. */
if (lb > vr[r].px && if (lb > vr.px[r] &&
lb < vr[r].px + vr[r].nx && lb < vr.px[r] + vr.nx[r] &&
rb >= vr[r].px + vr[r].nx) { rb >= vr.px[r] + vr.nx[r]) {
vr[r].nx = lb; vr.nx[r] = lb;
} }
/* Else if the right edge of floating wp /* Else if the right edge of floating wp
falls inside of this range and left falls inside of this range and left
edge covers the left of range, edge covers the left of range,
then move px forward to right edge of wp. */ then move px forward to right edge of wp. */
else if (rb > vr[r].px && else if (rb > vr.px[r] &&
rb < vr[r].px + vr[r].nx && rb < vr.px[r] + vr.nx[r] &&
lb <= vr[r].px) { lb <= vr.px[r]) {
vr[r].nx = vr[r].nx - (rb - vr[r].px); vr.nx[r] = vr.nx[r] - (rb - vr.px[r]);
vr[r].px = vr[r].px + (rb - vr[r].px); vr.px[r] = vr.px[r] + (rb - vr.px[r]);
} }
/* Else if wp fully inside range /* Else if wp fully inside range
then split range into 2 ranges. */ then split range into 2 ranges. */
else if (lb > vr[r].px && else if (lb > vr.px[r] &&
rb < vr[r].px + vr[r].nx) { rb < vr.px[r] + vr.nx[r]) {
if (size == last) { if (vr.size == vr.used) {
vr = xreallocarray(vr, vr.size++;
size += 4, sizeof *vr); vr.px = xreallocarray(vr.px,
vr.size, sizeof (u_int));
vr.nx = xreallocarray(vr.nx,
vr.size, sizeof (u_int));
} }
for (s=last; s>r; s--) { for (s=vr.used; s>r; s--) {
vr[s].px = vr[s-1].px; vr.px[s] = vr.px[s-1];
vr[s].nx = vr[s-1].nx; vr.nx[s] = vr.nx[s-1];
} }
last++; vr.used++;
vr[r].nx = lb; vr.nx[r] = lb;
vr[r+1].px = rb; vr.px[r+1] = rb;
} }
/* If floating wp completely covers this range /* If floating wp completely covers this range
then delete it (make it 0 length). */ then delete it (make it 0 length). */
else if (lb <= vr[r].px && else if (lb <= vr.px[r] &&
rb >= vr[r].px+vr[r].nx) { rb >= vr.px[r] + vr.nx[r]) {
vr[r].nx = 0; vr.nx[r] = 0;
} }
/* Else the range is already obscured, do nothing. */ /* Else the range is already obscured, do nothing. */
} }
} }
/* Tie off array. */ return (&vr);
if (size == last) {
vr = xreallocarray(vr, size += 4, sizeof *vr);
}
vr[last].px = 0;
vr[last].nx = -1;
return (vr);
} }
@@ -1056,7 +1052,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
struct screen *s = wp->screen; struct screen *s = wp->screen;
struct colour_palette *palette = &wp->palette; struct colour_palette *palette = &wp->palette;
struct grid_cell defaults; struct grid_cell defaults;
struct visible_range *vr; struct visible_ranges *vr;
u_int i, j, top, x, y, width, r; u_int i, j, top, x, y, width, r;
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id); log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
@@ -1104,14 +1100,14 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
tty_default_colours(&defaults, wp); tty_default_colours(&defaults, wp);
for (r=0; vr[r].nx != -1; r++) { for (r=0; r < vr->used; r++) {
if (vr[r].nx == 0) if (vr->nx[r] == 0)
continue; continue;
/* i is px of cell, add px of region, sub the /* i is px of cell, add px of region, sub the
pane offset. If you don't sub offset, pane offset. If you don't sub offset,
contents of pane shifted. */ contents of pane shifted. */
tty_draw_line(tty, s, i+vr[r].px-wp->xoff, j, tty_draw_line(tty, s, i + vr->px[r] - wp->xoff, j,
vr[r].nx, vr[r].px, y, &defaults, palette, vr->nx[r], vr->px[r], y, &defaults, palette,
vr); vr);
} }
} }
@@ -1203,7 +1199,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
int px, py, ox = ctx->ox, oy = ctx->oy; int px, py, ox = ctx->ox, oy = ctx->oy;
int sx = ctx->sx, sy = ctx->sy, xoff = wp->xoff; int sx = ctx->sx, sy = ctx->sy, xoff = wp->xoff;
int yoff = wp->yoff; int yoff = wp->yoff;
struct visible_range *vr; struct visible_ranges *vr;
/* Set up style for slider. */ /* Set up style for slider. */
gc = sb_style->gc; gc = sb_style->gc;

View File

@@ -1783,7 +1783,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
u_int r_start, r_end, ci_start, ci_end; 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, sx, xoff, yoff;
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
struct visible_range *vr; struct visible_ranges *vr;
struct window_pane *wp = ctx->wp; struct window_pane *wp = ctx->wp;
if (ctx->scrolled != 0) { if (ctx->scrolled != 0) {
@@ -1833,10 +1833,10 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
ci->x, last); ci->x, last);
} }
wr_length = 0; wr_length = 0;
for (r = 0; vr[r].nx != -1; r++) { for (r = 0; r < vr->used; r++) {
if (vr[r].nx == 0) continue; if (vr->nx[r] == 0) continue;
r_start = vr[r].px; r_start = vr->px[r];
r_end = vr[r].px + vr[r].nx; r_end = vr->px[r] + vr->nx[r];
ci_start = ci->x; ci_start = ci->x;
ci_end = ci->x + ci->used; ci_end = ci->x + ci->used;

14
tmux.h
View File

@@ -2235,9 +2235,11 @@ struct mode_tree_sort_criteria {
}; };
/* Visible range array element. nx==-1 is end of array mark. */ /* Visible range array element. nx==-1 is end of array mark. */
struct visible_range { struct visible_ranges {
u_int px; /* Start */ u_int *px; /* Start */
int nx; /* Length */ u_int *nx; /* Length */
size_t used;
size_t size;
}; };
/* tmux.c */ /* tmux.c */
@@ -2528,7 +2530,7 @@ void tty_set_path(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *); void tty_update_mode(struct tty *, int, struct screen *);
void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int, void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
u_int, u_int, const struct grid_cell *, struct colour_palette *, u_int, u_int, const struct grid_cell *, struct colour_palette *,
struct visible_range *); struct visible_ranges *);
#ifdef ENABLE_SIXEL #ifdef ENABLE_SIXEL
void tty_draw_images(struct client *, struct window_pane *, struct screen *); void tty_draw_images(struct client *, struct window_pane *, struct screen *);
@@ -3171,8 +3173,8 @@ void screen_write_alternateoff(struct screen_write_ctx *,
/* screen-redraw.c */ /* screen-redraw.c */
void screen_redraw_screen(struct client *); void screen_redraw_screen(struct client *);
void screen_redraw_pane(struct client *, struct window_pane *, int); void screen_redraw_pane(struct client *, struct window_pane *, int);
int screen_redraw_is_visible(struct visible_range *, u_int px); int screen_redraw_is_visible(struct visible_ranges *, u_int px);
struct visible_range *screen_redraw_get_visible_ranges(struct window_pane *, struct visible_ranges *screen_redraw_get_visible_ranges(struct window_pane *,
u_int, u_int, u_int); u_int, u_int, u_int);