diff --git a/screen-redraw.c b/screen-redraw.c index 48b0c511..c0c34bc4 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -917,12 +917,19 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx) } } -static int +/* Check if a single character is within a visible range (not obscured by a + * floating window pane). Returns a boolean. + */ +int screen_redraw_is_visible(struct visible_ranges *ranges, 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) + return (1); + vr = ranges->array; for (r=0; rn; r++) { if (vr[r].nx == 0) @@ -1000,8 +1007,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px, else if (rb > vr[r].px && rb < vr[r].px + vr[r].nx && lb <= vr[r].px) { - vr[r].px = vr[r].px + rb; - vr[r].nx = vr[r].nx - rb; + vr[r].px = vr[r].px + (rb - vr[r].px); + vr[r].nx = vr[r].nx - (rb - vr[r].px); } /* Else if wp fully inside range then split range into 2 ranges. */ diff --git a/screen-write.c b/screen-write.c index 099a9754..9ab54a14 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1781,7 +1781,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, 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; + u_int wr_start, wr_end, wr_length, sx, xoff; struct tty_ctx ttyctx; struct visible_ranges *visible_ranges; struct visible_range *vr; @@ -1809,11 +1809,21 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, cx = s->cx; cy = s->cy; + /* 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; + xoff = wp->xoff; + } else { + sx = screen_size_x(s); + xoff = 0; + } + 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, - screen_size_x(s)); + sx); vr = visible_ranges->array; last = UINT_MAX; @@ -1830,16 +1840,20 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ci_start = ci->x; ci_end = ci->x + ci->used; - if (ci_end <= r_start || ci_start >= r_end) + if (ci_start + xoff > r_end || ci_end + xoff < r_start) continue; - wr_start = (ci_start < r_start) ? - r_start : ci_start; - wr_end = (ci_end > r_end) ? - r_end : ci_end; + if (r_start > ci_start + xoff) + wr_start = ci_start + (r_start - (ci_start + xoff)); + else + wr_start = ci_start; + if (ci_end + xoff > r_end) + wr_end = ci_end - ((ci_end + xoff) - r_end); + else + wr_end = ci_end; wr_length = wr_end - wr_start; - if (wr_length == 0) + if (wr_length <= 0) continue; screen_write_set_cursor(ctx, wr_start, y); diff --git a/tmux.h b/tmux.h index cb9fee24..23e7036a 100644 --- a/tmux.h +++ b/tmux.h @@ -3175,6 +3175,7 @@ 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 *, u_int, u_int, u_int); diff --git a/tty.c b/tty.c index 40b019f9..da8eafa3 100644 --- a/tty.c +++ b/tty.c @@ -1465,34 +1465,6 @@ tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx, c->overlay_check(c, c->overlay_data, px, py, nx, r); } -/* Check if a single character is within a visible range (not obscured by a - * floating window pane). Returns a boolean. - */ -static int -tty_check_in_visible_range(struct visible_ranges *visible_ranges, u_int px) -{ - struct visible_range *vr; - u_int r; - - /* No visible_ranges if called from a popup or menu. Always on top. */ - if (visible_ranges == NULL) - return (0); - - vr = visible_ranges->array; - - /* Verify if px is in a visible range. */ - for (r=0; rn; r++) { - if (vr[r].nx == 0) - continue; - if (px >= vr[r].px && - px <= (vr[r].px + vr[r].nx)) - return (0); - } - - /* px not found in any visible range, it is obscured by a pane. */ - return (1); -} - 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, @@ -1583,7 +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) || - !tty_check_in_visible_range(visible_ranges, + screen_redraw_is_visible(visible_ranges, atx + ux + width) || (gcp->attr & GRID_ATTR_CHARSET) || gcp->flags != last.flags || @@ -2059,10 +2031,14 @@ tty_is_obscured(const struct tty_ctx *ctx) } if (found_self && wp->layout_cell == NULL && ! (wp->flags & PANE_MINIMISED) && - (wp->yoff > base_wp->yoff && - wp->yoff + wp->sy < base_wp->yoff + base_wp->sy) && - (wp->xoff > base_wp->xoff && - wp->xoff + wp->sx < base_wp->xoff + base_wp->sx)) + ((wp->yoff >= base_wp->yoff && + wp->yoff <= base_wp->yoff + base_wp->sy) || + (wp->yoff + wp->sy >= base_wp->yoff && + wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) && + ((wp->xoff >= base_wp->xoff && + wp->xoff <= base_wp->xoff + base_wp->sx) || + (wp->xoff + wp->sx >= base_wp->xoff && + wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx))) return (1); } return (0);