diff --git a/screen-redraw.c b/screen-redraw.c index 18b78ef5..8088aabd 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -545,7 +545,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx) struct tty *tty = &c->tty; struct window_pane *wp; struct screen *s; - struct visible_ranges *visible_ranges; + struct visible_range *vr; u_int i, x, width, xoff, yoff, size; log_debug("%s: %s @%u", __func__, c->name, w->id); @@ -592,11 +592,10 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx) if (ctx->statustop) yoff += ctx->statuslines; - visible_ranges = screen_redraw_get_visible_ranges(wp, i, 0, - width); + vr = screen_redraw_get_visible_ranges(wp, i, 0, width); tty_draw_line(tty, s, i, 0, width, x, yoff - ctx->oy, - &grid_default_cell, NULL, visible_ranges); + &grid_default_cell, NULL, vr); } tty_cursor(tty, 0, 0); } @@ -923,17 +922,15 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx) * floating window pane). Returns a boolean. */ int -screen_redraw_is_visible(struct visible_ranges *ranges, u_int px) +screen_redraw_is_visible(struct visible_range *vr, u_int px) { - struct visible_range *vr; u_int r; /* No visible_ranges if called from a popup or menu. Always visible. */ - if (ranges == NULL) + if (vr == NULL) return (1); - vr = ranges->array; - for (r=0; rn; r++) { + for (r=0; vr[r].nx != -1; r++) { if (vr[r].nx == 0) continue; if ((px >= vr[r].px) && (px <= vr[r].px + vr[r].nx)) @@ -942,33 +939,32 @@ screen_redraw_is_visible(struct visible_ranges *ranges, u_int px) return (0); } -/* Construct ranges of line at px,py of width cells of base_wp that are - unobsructed. */ -struct visible_ranges * +/* Construct ranges array for the line at starting at px,py of width + cells of base_wp that are unobsructed. */ +struct visible_range * screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, u_int py, u_int width) { struct window_pane *wp; struct window *w; - static struct visible_ranges ranges = { NULL, 0, 0 }; - static struct visible_range *vr; - int found_self, sb_w; - u_int r, s, lb, rb, tb, bb; - int pane_scrollbars; + static struct visible_range *vr = NULL; + static size_t size = 0, last; + int found_self, sb_w; + u_int r, s, lb, rb, tb, bb; + int pane_scrollbars; /* For efficiency ranges is static and space reused. */ - if (ranges.array == NULL) { - ranges.array = xcalloc(4, sizeof(struct visible_range *)); - ranges.size = 4; + if (vr == NULL) { + vr = xcalloc(4, sizeof(struct visible_range *)); + size = 4; } /* Start with the entire width of the range. */ - vr = ranges.array; vr[0].px = px; vr[0].nx = width; - ranges.n = 1; + last = 1; if (base_wp == NULL) - return (&ranges); + return (vr); w = base_wp->window; pane_scrollbars = options_get_number(w->options, "pane-scrollbars"); @@ -991,7 +987,7 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, if (window_pane_show_scrollbar(wp, pane_scrollbars)) sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad; - for (r=0; rxoff - 1; rb = wp->xoff + wp->sx + sb_w + 1; /* If the left edge of floating wp @@ -1017,18 +1013,17 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, then split range into 2 ranges. */ else if (lb > vr[r].px && rb < vr[r].px + vr[r].nx) { - if (ranges.size == ranges.n) { - ranges.array = xreallocarray(vr, - ranges.size += 4, sizeof *vr); - ranges.array = vr; + if (size == last) { + vr = xreallocarray(vr, + size += 4, sizeof *vr); } - for (s=ranges.n; s>r; s--) { + for (s=last; s>r; s--) { vr[s].px = vr[s-1].px; vr[s].nx = vr[s-1].nx; } + last++; vr[r].nx = lb; vr[r+1].px = rb; - ranges.n++; } /* If floating wp completely covers this range then delete it (make it 0 length). */ @@ -1039,7 +1034,15 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, /* Else the range is already obscured, do nothing. */ } } - return (&ranges); + + /* Tie off array. */ + if (size == last) { + vr = xreallocarray(vr, size += 4, sizeof *vr); + } + vr[last].px = 0; + vr[last].nx = -1; + + return (vr); } @@ -1053,7 +1056,6 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) struct screen *s = wp->screen; struct colour_palette *palette = &wp->palette; struct grid_cell defaults; - struct visible_ranges *visible_ranges; struct visible_range *vr; u_int i, j, top, x, y, width, r; @@ -1098,15 +1100,11 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) __func__, c->name, wp->id, i, j, x, y, width); /* Get visible ranges of line before we draw it. */ - visible_ranges = screen_redraw_get_visible_ranges(wp, x, y, - width); - vr = visible_ranges->array; + vr = screen_redraw_get_visible_ranges(wp, x, y, width); tty_default_colours(&defaults, wp); - /* xxxx tty_draw_line should drawn only visible ranges. see xxxx commment in tty_draw_line. */ - /*tty_draw_line(tty, s, i, j, width, x, y, &defaults, palette, visible_ranges); */ - for (r=0; rn; r++) { + for (r=0; vr[r].nx != -1; r++) { if (vr[r].nx == 0) continue; /* i is px of cell, add px of region, sub the @@ -1114,7 +1112,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) contents of pane shifted. */ tty_draw_line(tty, s, i+vr[r].px-wp->xoff, j, vr[r].nx, vr[r].px, y, &defaults, palette, - visible_ranges); + vr); } } @@ -1205,7 +1203,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx, int px, py, ox = ctx->ox, oy = ctx->oy; int sx = ctx->sx, sy = ctx->sy, xoff = wp->xoff; int yoff = wp->yoff; - struct visible_ranges *visible_ranges; + struct visible_range *vr; /* Set up style for slider. */ gc = sb_style->gc; @@ -1222,15 +1220,14 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx, for (j = 0; j < jmax; j++) { py = sb_y + j; - visible_ranges = screen_redraw_get_visible_ranges(wp, sb_x, py, - imax); + vr = screen_redraw_get_visible_ranges(wp, sb_x, py, imax); for (i = 0; i < imax; i++) { px = sb_x + i; if (px < xoff - ox - (int)sb_w - (int)sb_pad || px >= sx || px < 0 || py < yoff - oy - 1 || py >= sy || py < 0 || - ! screen_redraw_is_visible(visible_ranges, px)) + ! screen_redraw_is_visible(vr, px)) continue; tty_cursor(tty, px, py); if ((sb_pos == PANE_SCROLLBARS_LEFT && diff --git a/screen-write.c b/screen-write.c index 00575942..bccbdede 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1783,7 +1783,6 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, u_int r_start, r_end, ci_start, ci_end; u_int wr_start, wr_end, wr_length, sx, xoff, yoff; struct tty_ctx ttyctx; - struct visible_ranges *visible_ranges; struct visible_range *vr; struct window_pane *wp = ctx->wp; @@ -1824,9 +1823,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, for (y = 0; y < screen_size_y(s); y++) { cl = &ctx->s->write_list[y]; - visible_ranges = screen_redraw_get_visible_ranges(wp, 0, y + yoff, + vr = screen_redraw_get_visible_ranges(wp, 0, y + yoff, sx); - vr = visible_ranges->array; last = UINT_MAX; TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { @@ -1835,7 +1833,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ci->x, last); } wr_length = 0; - for (r = 0; r < visible_ranges->n; r++) { + for (r = 0; vr[r].nx != -1; r++) { if (vr[r].nx == 0) continue; r_start = vr[r].px; r_end = vr[r].px + vr[r].nx; diff --git a/server-client.c b/server-client.c index 27c555de..d8d516b5 100644 --- a/server-client.c +++ b/server-client.c @@ -670,14 +670,6 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, break; } } - /* - if ((((sb_pos == PANE_SCROLLBARS_RIGHT && fwp->xoff + fwp->sx + sb_pad + sb_w == px) || - (sb_pos == PANE_SCROLLBARS_LEFT && fwp->xoff + fwp->sx == px)) && - fwp->yoff <= 1 + py && fwp->yoff + fwp->sy >= py) || - (fwp->yoff + fwp->sy == py && - fwp->xoff <= 1 + px && fwp->xoff + fwp->sx >= px)) - break; - */ } if (fwp != NULL) return (BORDER); diff --git a/tmux.h b/tmux.h index 23e7036a..4bb92a65 100644 --- a/tmux.h +++ b/tmux.h @@ -2234,14 +2234,10 @@ struct mode_tree_sort_criteria { int reversed; }; +/* Visible range array element. nx==-1 is end of array mark. */ struct visible_range { - u_int px; /* Start */ - u_int nx; /* Length */ -}; -struct visible_ranges { - struct visible_range *array; - size_t n; /* Elements used */ - size_t size; /* Array size */ + u_int px; /* Start */ + int nx; /* Length */ }; /* tmux.c */ @@ -2532,7 +2528,7 @@ void tty_set_path(struct tty *, const char *); void tty_update_mode(struct tty *, int, struct screen *); 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 *, - struct visible_ranges *); + struct visible_range *); #ifdef ENABLE_SIXEL void tty_draw_images(struct client *, struct window_pane *, struct screen *); @@ -3175,8 +3171,8 @@ void screen_write_alternateoff(struct screen_write_ctx *, /* screen-redraw.c */ void screen_redraw_screen(struct client *); void screen_redraw_pane(struct client *, struct window_pane *, int); -int screen_redraw_is_visible(struct visible_ranges *ranges, u_int px); -struct visible_ranges *screen_redraw_get_visible_ranges(struct window_pane *, +int screen_redraw_is_visible(struct visible_range *, u_int px); +struct visible_range *screen_redraw_get_visible_ranges(struct window_pane *, u_int, u_int, u_int); diff --git a/tty.c b/tty.c index da8eafa3..07b89334 100644 --- a/tty.c +++ b/tty.c @@ -1373,22 +1373,22 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) { struct screen *s = ctx->s; struct window_pane *wp = ctx->arg; - struct visible_ranges *visible_ranges = NULL; + struct visible_range *vr = NULL; u_int nx = ctx->sx, i, x, rx, ry; log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger); if (wp) - visible_ranges = screen_redraw_get_visible_ranges(wp, 0, py, nx); + vr = screen_redraw_get_visible_ranges(wp, 0, py, nx); if (!ctx->bigger) { tty_draw_line(tty, s, 0, py, nx, ctx->xoff, ctx->yoff + py, - &ctx->defaults, ctx->palette, visible_ranges); + &ctx->defaults, ctx->palette, vr); return; } if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) { tty_draw_line(tty, s, i, py, rx, x, ry, &ctx->defaults, - ctx->palette, visible_ranges); + ctx->palette, vr); } } @@ -1468,7 +1468,7 @@ tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx, void tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, u_int atx, u_int aty, const struct grid_cell *defaults, - struct colour_palette *palette, struct visible_ranges *visible_ranges) + struct colour_palette *palette, struct visible_range *vr) { struct grid *gd = s->grid; struct grid_cell gc, last; @@ -1555,8 +1555,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, gcp = tty_check_codeset(tty, &gc); if (len != 0 && (!tty_check_overlay(tty, atx + ux + width, aty) || - screen_redraw_is_visible(visible_ranges, - atx + ux + width) || + screen_redraw_is_visible(vr, atx + ux + width) || (gcp->attr & GRID_ATTR_CHARSET) || gcp->flags != last.flags || gcp->attr != last.attr || @@ -2217,7 +2216,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = ctx->s; struct overlay_ranges r; struct window_pane *wp = ctx->arg; - struct visible_ranges *visible_ranges; + struct visible_range *vr; u_int px, py, i, vis = 0; px = ctx->xoff + ctx->ocx - ctx->wox; @@ -2227,7 +2226,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) return; if (wp) - visible_ranges = screen_redraw_get_visible_ranges(wp, px, py, 1); + vr = screen_redraw_get_visible_ranges(wp, px, py, 1); /* Handle partially obstructed wide characters. */ if (gcp->data.width > 1) { @@ -2236,8 +2235,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) vis += r.nx[i]; if (vis < gcp->data.width) { tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width, - px, py, &ctx->defaults, ctx->palette, - visible_ranges); + px, py, &ctx->defaults, ctx->palette, vr); return; } }