Fix floating pane redraw bugs. Allow floating panes to be partly out of the window. This required changing xoff and yoff from u_int to int and it required a fair bit of casting for example when xoff is added to sx or comparing px to xoff. It makes sense for px and sx to be u_int since they refers to things which should never be negative.

This commit is contained in:
Michael Grant
2025-11-01 21:47:54 +01:00
parent 34e858ea05
commit 6dd552d689
9 changed files with 119 additions and 87 deletions

View File

@@ -70,10 +70,10 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
char buf[16], lbuf[16], rbuf[16], *ptr; char buf[16], lbuf[16], rbuf[16], *ptr;
size_t len, llen, rlen; size_t len, llen, rlen;
if (wp->xoff + wp->sx <= ctx->ox || if (wp->xoff + (int)wp->sx <= ctx->ox ||
wp->xoff >= ctx->ox + ctx->sx || wp->xoff >= ctx->ox + (int)ctx->sx ||
wp->yoff + wp->sy <= ctx->oy || wp->yoff + (int)wp->sy <= ctx->oy ||
wp->yoff >= ctx->oy + ctx->sy) wp->yoff >= ctx->oy + (int)ctx->sy)
return; return;
if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) { if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) {

View File

@@ -161,7 +161,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
u_int y, ly, x, lx, new_sx, new_sy; u_int y, ly, x, lx, new_sx, new_sy, resizes = 0;
wl = cmd_mouse_window(m, NULL); wl = cmd_mouse_window(m, NULL);
if (wl == NULL) { if (wl == NULL) {
@@ -176,7 +176,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
else if (m->statusat > 0 && y >= (u_int)m->statusat) else if (m->statusat > 0 && y >= (u_int)m->statusat)
y = m->statusat - 1; y = m->statusat - 1;
ly = m->ly + m->oy; lx = m->lx + m->ox; ly = m->ly + m->oy; lx = m->lx + m->ox;
if (m->statusat == 0 && ly >= m->statuslines) if (m->statusat == 0 && ly >= (u_int)m->statuslines)
ly -= m->statuslines; ly -= m->statuslines;
else if (m->statusat > 0 && ly >= (u_int)m->statusat) else if (m->statusat > 0 && ly >= (u_int)m->statusat)
ly = m->statusat - 1; ly = m->statusat - 1;
@@ -185,8 +185,8 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u", log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u",
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
if (((m->lx == wp->xoff - 1) || (m->lx == wp->xoff)) && if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
(m->ly == wp->yoff - 1)) { ((int)ly == wp->yoff - 1)) {
/* Top left border */ /* Top left border */
new_sx = wp->sx + (lx - x); new_sx = wp->sx + (lx - x);
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
@@ -196,10 +196,10 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
new_sy = PANE_MINIMUM; new_sy = PANE_MINIMUM;
window_pane_move(wp, x + 1, y + 1); window_pane_move(wp, x + 1, y + 1);
window_pane_resize(wp, new_sx, new_sy); window_pane_resize(wp, new_sx, new_sy);
server_redraw_window(w); resizes++;
} else if (((m->lx == wp->xoff + wp->sx + 1) || } else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
(m->lx == wp->xoff + wp->sx)) && ((int)lx == wp->xoff + (int)wp->sx)) &&
(m->ly == wp->yoff - 1)) { ((int)ly == wp->yoff - 1)) {
/* Top right border */ /* Top right border */
new_sx = x - wp->xoff - 1; new_sx = x - wp->xoff - 1;
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
@@ -209,9 +209,9 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
new_sy = PANE_MINIMUM; new_sy = PANE_MINIMUM;
window_pane_move(wp, wp->xoff, y + 1); window_pane_move(wp, wp->xoff, y + 1);
window_pane_resize(wp, new_sx, new_sy); window_pane_resize(wp, new_sx, new_sy);
server_redraw_window(w); resizes++;
} else if (((m->lx == wp->xoff - 1) || (m->lx == wp->xoff)) && } else if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) &&
(m->ly == wp->yoff + wp->sy)) { ((int)ly == wp->yoff + (int)wp->sy)) {
/* Bottom left border */ /* Bottom left border */
new_sx = wp->sx + (lx - x); new_sx = wp->sx + (lx - x);
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
@@ -221,10 +221,10 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
return; return;
window_pane_move(wp, x + 1, wp->yoff); window_pane_move(wp, x + 1, wp->yoff);
window_pane_resize(wp, new_sx, new_sy); window_pane_resize(wp, new_sx, new_sy);
server_redraw_window(w); resizes++;
} else if (((m->lx == wp->xoff + wp->sx + 1) || } else if ((((int)lx == wp->xoff + (int)wp->sx + 1) ||
(m->lx == wp->xoff + wp->sx)) && ((int)lx == wp->xoff + (int)wp->sx)) &&
(m->ly == wp->yoff + wp->sy)) { ((int)ly == wp->yoff + (int)wp->sy)) {
/* Bottom right corner */ /* Bottom right corner */
new_sx = x - wp->xoff - 1; new_sx = x - wp->xoff - 1;
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
@@ -233,30 +233,30 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
if (new_sy < PANE_MINIMUM) if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM; new_sy = PANE_MINIMUM;
window_pane_resize(wp, new_sx, new_sy); window_pane_resize(wp, new_sx, new_sy);
server_redraw_window(w); resizes++;
} else if (m->lx == wp->xoff + wp->sx + 1) { } else if ((int)lx == wp->xoff + (int)wp->sx + 1) {
/* Right border */ /* Right border */
new_sx = x - wp->xoff - 1; new_sx = x - wp->xoff - 1;
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
return; return;
window_pane_resize(wp, new_sx, wp->sy); window_pane_resize(wp, new_sx, wp->sy);
server_redraw_window(w); resizes++;
} else if (m->lx == wp->xoff - 1) { } else if ((int)lx == wp->xoff - 1) {
/* Left border */ /* Left border */
new_sx = wp->sx + (lx - x); new_sx = wp->sx + (lx - x);
if (new_sx < PANE_MINIMUM) if (new_sx < PANE_MINIMUM)
return; return;
window_pane_move(wp, x + 1, wp->yoff); window_pane_move(wp, x + 1, wp->yoff);
window_pane_resize(wp, new_sx, wp->sy); window_pane_resize(wp, new_sx, wp->sy);
server_redraw_window(w); resizes++;
} else if (m->ly == wp->yoff + wp->sy) { } else if ((int)ly == wp->yoff + (int)wp->sy) {
/* Bottom border */ /* Bottom border */
new_sy = y - wp->yoff; new_sy = y - wp->yoff;
if (new_sy < PANE_MINIMUM) if (new_sy < PANE_MINIMUM)
return; return;
window_pane_resize(wp, wp->sx, new_sy); window_pane_resize(wp, wp->sx, new_sy);
server_redraw_window(w); resizes++;
} else if (m->ly == wp->yoff - 1) { } else if ((int)ly == wp->yoff - 1) {
/* Top border */ /* Top border */
window_pane_move(wp, wp->xoff + (x - lx), y + 1); window_pane_move(wp, wp->xoff + (x - lx), y + 1);
/* /*
@@ -266,11 +266,15 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
window_pane_move(wp, wp->xoff, y + 1); window_pane_move(wp, wp->xoff, y + 1);
window_pane_resize(wp, wp->sx, new_sy); window_pane_resize(wp, wp->sx, new_sy);
*/ */
server_redraw_window(w); resizes++;
} else { } else {
log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u <else>", log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u <else>",
__func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly);
} }
if (resizes != 0) {
server_redraw_window(w);
server_redraw_window_borders(w);
}
} }
static void static void

4
cmd.c
View File

@@ -766,9 +766,9 @@ cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp,
if (m->statusat == 0 && y >= m->statuslines) if (m->statusat == 0 && y >= m->statuslines)
y -= m->statuslines; y -= m->statuslines;
if (x < wp->xoff || x >= wp->xoff + wp->sx) if ((int)x < wp->xoff || (int)x >= wp->xoff + (int)wp->sx)
return (-1); return (-1);
if (y < wp->yoff || y >= wp->yoff + wp->sy) if ((int)y < wp->yoff || (int)y >= wp->yoff + (int)wp->sy)
return (-1); return (-1);
if (xp != NULL) if (xp != NULL)

View File

@@ -137,7 +137,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
sb_pos = 0; sb_pos = 0;
/* Inside pane. */ /* Inside pane. */
if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey) if ((int)px >= wp->xoff && px < ex && (int)py >= wp->yoff && py < ey)
return (SCREEN_REDRAW_INSIDE); return (SCREEN_REDRAW_INSIDE);
/* Get pane indicator. */ /* Get pane indicator. */
@@ -157,16 +157,16 @@ 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 * Left/right borders. The wp->sy / 2 test is to colour only half the
* active window's border when there are two panes. * active window's border when there are two panes.
*/ */
if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) { if ((wp->yoff == 0 || (int)py >= wp->yoff - 1) && py <= ey) {
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
if (wp->xoff - sb_w == 0 && px == wp->sx + sb_w) if (wp->xoff - sb_w == 0 && px == wp->sx + sb_w)
if (!hsplit || (hsplit && py <= wp->sy / 2)) if (!hsplit || (hsplit && py <= wp->sy / 2))
return (SCREEN_REDRAW_BORDER_RIGHT); return (SCREEN_REDRAW_BORDER_RIGHT);
if (wp->xoff - sb_w != 0) { if (wp->xoff - sb_w != 0) {
if (px == wp->xoff - sb_w - 1 && if ((int)px == wp->xoff - sb_w - 1 &&
(!hsplit || (hsplit && py > wp->sy / 2))) (!hsplit || (hsplit && py > wp->sy / 2)))
return (SCREEN_REDRAW_BORDER_LEFT); return (SCREEN_REDRAW_BORDER_LEFT);
if (px == wp->xoff + wp->sx + sb_w - 1) if ((int)px == wp->xoff + (int)wp->sx + sb_w - 1)
return (SCREEN_REDRAW_BORDER_RIGHT); return (SCREEN_REDRAW_BORDER_RIGHT);
} }
} else { /* sb_pos == PANE_SCROLLBARS_RIGHT or disabled*/ } else { /* sb_pos == PANE_SCROLLBARS_RIGHT or disabled*/
@@ -174,7 +174,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
if (!hsplit || (hsplit && py <= wp->sy / 2)) if (!hsplit || (hsplit && py <= wp->sy / 2))
return (SCREEN_REDRAW_BORDER_RIGHT); return (SCREEN_REDRAW_BORDER_RIGHT);
if (wp->xoff != 0) { if (wp->xoff != 0) {
if (px == wp->xoff - 1 && if ((int)px == wp->xoff - 1 &&
(!hsplit || (hsplit && py > wp->sy / 2))) (!hsplit || (hsplit && py > wp->sy / 2)))
return (SCREEN_REDRAW_BORDER_LEFT); return (SCREEN_REDRAW_BORDER_LEFT);
if (px == wp->xoff + wp->sx + sb_w) if (px == wp->xoff + wp->sx + sb_w)
@@ -187,21 +187,21 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
if (vsplit && pane_status == PANE_STATUS_OFF && sb_w == 0) { if (vsplit && pane_status == PANE_STATUS_OFF && sb_w == 0) {
if (wp->yoff == 0 && py == wp->sy && px <= wp->sx / 2) if (wp->yoff == 0 && py == wp->sy && px <= wp->sx / 2)
return (SCREEN_REDRAW_BORDER_BOTTOM); return (SCREEN_REDRAW_BORDER_BOTTOM);
if (wp->yoff != 0 && py == wp->yoff - 1 && px > wp->sx / 2) if (wp->yoff != 0 && (int)py == wp->yoff - 1 && px > wp->sx / 2)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
} else { } else {
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) && if ((wp->xoff - sb_w == 0 || (int)px >= wp->xoff - sb_w) &&
(px <= ex || (sb_w != 0 && px < ex + sb_w))) { (px <= ex || (sb_w != 0 && px < ex + sb_w))) {
if (wp->yoff != 0 && py == wp->yoff - 1) if (wp->yoff != 0 && (int)py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey) if (py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM); return (SCREEN_REDRAW_BORDER_BOTTOM);
} }
} else { /* sb_pos == PANE_SCROLLBARS_RIGHT */ } else { /* sb_pos == PANE_SCROLLBARS_RIGHT */
if ((wp->xoff == 0 || px >= wp->xoff) && if ((wp->xoff == 0 || (int)px >= wp->xoff) &&
(px <= ex || (sb_w != 0 && px < ex + sb_w))) { (px <= ex || (sb_w != 0 && px < ex + sb_w))) {
if (wp->yoff != 0 && py == wp->yoff - 1) if (wp->yoff != 0 && (int)py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey) if (py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM); return (SCREEN_REDRAW_BORDER_BOTTOM);
@@ -358,8 +358,8 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
/* Look for higest z-index window at px,py. xxxx scrollbars? */ /* Look for higest z-index window at px,py. xxxx scrollbars? */
TAILQ_FOREACH(wp, &w->z_index, zentry) { TAILQ_FOREACH(wp, &w->z_index, zentry) {
if (! (wp->flags & PANE_MINIMISED) && if (! (wp->flags & PANE_MINIMISED) &&
(px >= wp->xoff - 1 && px<= wp->xoff + wp->sx + 1) && ((int)px >= wp->xoff - 1 && (int)px <= wp->xoff + (int)wp->sx + 1) &&
(py >= wp->yoff - 1 && py<= wp->yoff + wp->sy + 1)) ((int)py >= wp->yoff - 1 && (int)py <= wp->yoff + (int)wp->sy + 1))
break; break;
} }
if (wp != NULL) if (wp != NULL)
@@ -378,7 +378,7 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
line = wp->yoff + sy; line = wp->yoff + sy;
right = wp->xoff + 2 + wp->status_size - 1; right = wp->xoff + 2 + wp->status_size - 1;
if (py == line && px >= wp->xoff + 2 && px <= right) if (py == line && (int)px >= wp->xoff + 2 && px <= right)
return (CELL_INSIDE); return (CELL_INSIDE);
next1: next1:
@@ -394,8 +394,8 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
sb_w = wp->scrollbar_style.width + sb_w = wp->scrollbar_style.width +
wp->scrollbar_style.pad; wp->scrollbar_style.pad;
if (! (wp->flags & PANE_MINIMISED) && if (! (wp->flags & PANE_MINIMISED) &&
(px >= wp->xoff - 1 && px <= wp->xoff + wp->sx + sb_w) && ((int)px >= wp->xoff - 1 && (int)px <= wp->xoff + (int)wp->sx + sb_w) &&
(py >= wp->yoff - 1 && py <= wp->yoff + wp->sy)) ((int)py >= wp->yoff - 1 && (int)py <= wp->yoff + (int)wp->sy))
break; break;
} }
if (wp == NULL) if (wp == NULL)
@@ -421,14 +421,14 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
sb_w = wp->scrollbar_style.width + sb_w = wp->scrollbar_style.width +
wp->scrollbar_style.pad; wp->scrollbar_style.pad;
if ((wp->yoff == 0 && py < wp->sy) || if ((wp->yoff == 0 && py < wp->sy) ||
(py >= wp->yoff && py < wp->yoff + wp->sy)) { ((int)py >= wp->yoff && (int)py < wp->yoff + (int)wp->sy)) {
/* Check if px lies within a scrollbar. */ /* Check if px lies within a scrollbar. */
if ((sb_pos == PANE_SCROLLBARS_RIGHT && if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
(px >= wp->xoff + wp->sx && ((int)px >= wp->xoff + (int)wp->sx &&
px < wp->xoff + wp->sx + sb_w)) || (int)px < wp->xoff + (int)wp->sx + sb_w)) ||
(sb_pos == PANE_SCROLLBARS_LEFT && (sb_pos == PANE_SCROLLBARS_LEFT &&
(px >= wp->xoff - sb_w && ((int)px >= wp->xoff - sb_w &&
px < wp->xoff))) (int)px < wp->xoff)))
return (CELL_SCROLLBAR); return (CELL_SCROLLBAR);
} }
} }
@@ -543,7 +543,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
struct window_pane *wp; struct window_pane *wp;
struct screen *s; struct screen *s;
struct visible_ranges *vr; struct visible_ranges *vr;
u_int i, x, width, xoff, yoff, size, r; u_int i, x, width, size, r;
int xoff, yoff;
log_debug("%s: %s @%u", __func__, c->name, w->id); log_debug("%s: %s @%u", __func__, c->name, w->id);
@@ -559,10 +560,10 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
yoff = wp->yoff + wp->sy; yoff = wp->yoff + wp->sy;
xoff = wp->xoff + 2; xoff = wp->xoff + 2;
if (xoff + size <= ctx->ox || if (xoff + (int)size <= ctx->ox ||
xoff >= ctx->ox + ctx->sx || xoff >= ctx->ox + (int)ctx->sx ||
yoff < ctx->oy || yoff < ctx->oy ||
yoff >= ctx->oy + ctx->sy) yoff >= ctx->oy + (int)ctx->sy)
continue; continue;
if (xoff >= ctx->ox && xoff + size <= ctx->ox + ctx->sx) { if (xoff >= ctx->ox && xoff + size <= ctx->ox + ctx->sx) {
@@ -837,13 +838,13 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
if (wp != NULL && arrows) { if (wp != NULL && arrows) {
border = screen_redraw_pane_border(ctx, active, x, y); border = screen_redraw_pane_border(ctx, active, x, y);
if (((i == wp->xoff + 1 && if ((((int)i == wp->xoff + 1 &&
(cell_type == CELL_LEFTRIGHT || (cell_type == CELL_LEFTRIGHT ||
(cell_type == CELL_TOPJOIN && (cell_type == CELL_TOPJOIN &&
border == SCREEN_REDRAW_BORDER_BOTTOM) || border == SCREEN_REDRAW_BORDER_BOTTOM) ||
(cell_type == CELL_BOTTOMJOIN && (cell_type == CELL_BOTTOMJOIN &&
border == SCREEN_REDRAW_BORDER_TOP))) || border == SCREEN_REDRAW_BORDER_TOP))) ||
(j == wp->yoff + 1 && ((int)j == wp->yoff + 1 &&
(cell_type == CELL_TOPBOTTOM || (cell_type == CELL_TOPBOTTOM ||
(cell_type == CELL_LEFTJOIN && (cell_type == CELL_LEFTJOIN &&
border == SCREEN_REDRAW_BORDER_RIGHT) || border == SCREEN_REDRAW_BORDER_RIGHT) ||
@@ -989,8 +990,13 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad; sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
for (r=0; r < vr.used; r++) { for (r=0; r < vr.used; r++) {
lb = wp->xoff - 1; if (wp->xoff > 0)
lb = wp->xoff - 1;
else
lb = 0;
rb = wp->xoff + wp->sx + sb_w; rb = wp->xoff + wp->sx + sb_w;
if (rb > w->sx)
rb = w->sx - 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,
@@ -998,7 +1004,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
if (lb > vr.px[r] && if (lb > vr.px[r] &&
lb < vr.px[r] + vr.nx[r] && lb < vr.px[r] + vr.nx[r] &&
rb >= vr.px[r] + vr.nx[r]) { rb >= vr.px[r] + vr.nx[r]) {
vr.nx[r] = lb; /* vr.nx[r] = vr.nx[r] - ((vr.px[r] + vr.nx[r]) - lb); */
vr.nx[r] = lb - vr.px[r];
} }
/* 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
@@ -1007,8 +1014,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
else if (rb > vr.px[r] && else if (rb > vr.px[r] &&
rb < vr.px[r] + vr.nx[r] && rb < vr.px[r] + vr.nx[r] &&
lb <= vr.px[r]) { lb <= vr.px[r]) {
vr.nx[r] = vr.nx[r] - (rb - vr.px[r]); vr.nx[r] = vr.nx[r] - (rb + 1 - vr.px[r]);
vr.px[r] = vr.px[r] + (rb - vr.px[r]); vr.px[r] = vr.px[r] + (rb + 1 - 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. */
@@ -1025,10 +1032,11 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
vr.px[s] = vr.px[s-1]; vr.px[s] = vr.px[s-1];
vr.nx[s] = vr.nx[s-1]; vr.nx[s] = vr.nx[s-1];
} }
vr.px[r+1] = rb + 1;
vr.nx[r+1] = (vr.px[r] + vr.nx[r]) - (rb + 1);
/* vr.px[r] was copied, unchanged. */
vr.nx[r] = lb - vr.px[r];
vr.used++; vr.used++;
vr.nx[r] = lb;
vr.px[r+1] = rb;
vr.nx[r+1] = vr.nx[r+1] - rb - 1;
} }
/* 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). */
@@ -1039,6 +1047,11 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
/* Else the range is already obscured, do nothing. */ /* Else the range is already obscured, do nothing. */
} }
} }
for (r=0; r<vr.used; r++) {
log_debug("%s: %%%u visible_range py=%u %u: [px=%u nx=%u]",
__func__, base_wp->id, py, r, vr.px[r], vr.nx[r]);
}
return (&vr); return (&vr);
} }
@@ -1059,7 +1072,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
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);
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) if (wp->xoff + (int)wp->sx <= ctx->ox || wp->xoff >= ctx->ox + (int)ctx->sx)
return; return;
if (ctx->statustop) if (ctx->statustop)
top = ctx->statuslines; top = ctx->statuslines;
@@ -1067,7 +1080,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
top = 0; top = 0;
for (j = 0; j < wp->sy; j++) { for (j = 0; j < wp->sy; j++) {
if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy) if (wp->yoff + (int)j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy)
continue; continue;
y = top + wp->yoff + j - ctx->oy; y = top + wp->yoff + j - ctx->oy;
@@ -1195,7 +1208,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
struct tty *tty = &c->tty; struct tty *tty = &c->tty;
struct grid_cell gc, slgc, *gcp; struct grid_cell gc, slgc, *gcp;
struct style *sb_style = &wp->scrollbar_style; struct style *sb_style = &wp->scrollbar_style;
u_int i, j, imax, jmax; u_int i, j, imin = 0, jmin = 0, imax, jmax;
u_int sb_w = sb_style->width, sb_pad = sb_style->pad; u_int sb_w = sb_style->width, sb_pad = sb_style->pad;
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;
@@ -1208,17 +1221,32 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
slgc.fg = gc.bg; slgc.fg = gc.bg;
slgc.bg = gc.fg; slgc.bg = gc.fg;
if (sb_x + (int)sb_w < 0)
/* Whole sb off screen. */
return;
if (sb_x < 0)
imin = - sb_x;
imax = sb_w + sb_pad; imax = sb_w + sb_pad;
if ((int)imax + sb_x > sx) if ((int)imax + sb_x > sx) {
if (sb_x > sx)
/* Whole sb off screen. */
return;
imax = sx - sb_x; imax = sx - sb_x;
}
if (sb_y > oy + sy)
return;
if (sb_y < 0)
jmin = -sb_y;
if ((int)sb_h < oy)
return;
jmax = sb_h; jmax = sb_h;
if ((int)jmax + sb_y > sy) if ((int)jmax + sb_y > sy)
jmax = sy - sb_y; jmax = sy - sb_y;
for (j = 0; j < jmax; j++) { for (j = jmin; j < jmax; j++) {
py = sb_y + j; py = sb_y + j;
vr = 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++) { for (i = imin; i < imax; i++) {
px = sb_x + i; px = sb_x + i;
if (px < xoff - ox - (int)sb_w - (int)sb_pad || if (px < xoff - ox - (int)sb_w - (int)sb_pad ||
px >= sx || px < 0 || px >= sx || px < 0 ||

View File

@@ -2030,8 +2030,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
} }
if (found_self && wp->layout_cell == NULL && if (found_self && wp->layout_cell == NULL &&
!(wp->flags & PANE_MINIMISED) && !(wp->flags & PANE_MINIMISED) &&
(py >= wp->yoff && py <= wp->yoff + wp->sy) && ((int)py >= wp->yoff && (int)py <= wp->yoff + (int)wp->sy) &&
(px >= wp->xoff && px <= wp->xoff + wp->sx)) ((int)px >= wp->xoff && (int)px <= wp->xoff + (int)wp->sx))
return; return;
} }
} }

View File

@@ -613,7 +613,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
/* Check if point is within the pane or scrollbar. */ /* Check if point is within the pane or scrollbar. */
if (((pane_status != PANE_STATUS_OFF && py != line) || if (((pane_status != PANE_STATUS_OFF && py != line) ||
(wp->yoff == 0 && py < wp->sy) || (wp->yoff == 0 && py < wp->sy) ||
(py >= wp->yoff && py < wp->yoff + wp->sy)) && ((int)py >= wp->yoff && py < wp->yoff + wp->sy)) &&
((sb_pos == PANE_SCROLLBARS_RIGHT && ((sb_pos == PANE_SCROLLBARS_RIGHT &&
px < wp->xoff + wp->sx + sb_pad + sb_w) || px < wp->xoff + wp->sx + sb_pad + sb_w) ||
(sb_pos == PANE_SCROLLBARS_LEFT && (sb_pos == PANE_SCROLLBARS_LEFT &&
@@ -623,8 +623,8 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
(px >= wp->xoff + wp->sx + sb_pad && (px >= wp->xoff + wp->sx + sb_pad &&
px < wp->xoff + wp->sx + sb_pad + sb_w)) || px < wp->xoff + wp->sx + sb_pad + sb_w)) ||
(sb_pos == PANE_SCROLLBARS_LEFT && (sb_pos == PANE_SCROLLBARS_LEFT &&
(px >= wp->xoff - sb_pad - sb_w && ((int)px >= wp->xoff - sb_pad - sb_w &&
px < wp->xoff - sb_pad))) { (int)px < wp->xoff - sb_pad))) {
/* Check where inside the scrollbar. */ /* Check where inside the scrollbar. */
sl_top = wp->yoff + wp->sb_slider_y; sl_top = wp->yoff + wp->sb_slider_y;
sl_bottom = (wp->yoff + wp->sb_slider_y + sl_bottom = (wp->yoff + wp->sb_slider_y +
@@ -638,7 +638,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
} else /* py > sl_bottom */ } else /* py > sl_bottom */
return (SCROLLBAR_DOWN); return (SCROLLBAR_DOWN);
} else if (wp->layout_cell == NULL && } else if (wp->layout_cell == NULL &&
(px == wp->xoff - 1 || py == wp->yoff -1)) { ((int)px == wp->xoff - 1 || (int)py == wp->yoff -1)) {
/* Floating pane left or top border. */ /* Floating pane left or top border. */
return (BORDER); return (BORDER);
} else { } else {
@@ -653,7 +653,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
else else
/* PANE_SCROLLBARS_RIGHT or none. */ /* PANE_SCROLLBARS_RIGHT or none. */
bdr_right = fwp->xoff + fwp->sx + sb_pad + sb_w; bdr_right = fwp->xoff + fwp->sx + sb_pad + sb_w;
if (py >= fwp->yoff - 1 && py <= fwp->yoff + fwp->sy) { if ((int)py >= fwp->yoff - 1 && py <= fwp->yoff + fwp->sy) {
if (px == bdr_right) if (px == bdr_right)
break; break;
if (wp->layout_cell == NULL) { if (wp->layout_cell == NULL) {
@@ -663,7 +663,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
break; break;
} }
} }
if (px >= fwp->xoff - 1 && px <= fwp->xoff + fwp->sx) { if ((int)px >= fwp->xoff - 1 && px <= fwp->xoff + fwp->sx) {
bdr_bottom = fwp->yoff + fwp->sy; bdr_bottom = fwp->yoff + fwp->sy;
if (py == bdr_bottom) if (py == bdr_bottom)
break; break;

10
tmux.h
View File

@@ -1058,8 +1058,8 @@ struct screen_redraw_ctx {
u_int sx; u_int sx;
u_int sy; u_int sy;
u_int ox; int ox;
u_int oy; int oy;
}; };
/* Screen size. */ /* Screen size. */
@@ -1154,8 +1154,8 @@ struct window_pane {
u_int sx; u_int sx;
u_int sy; u_int sy;
u_int xoff; int xoff;
u_int yoff; int yoff;
int flags; int flags;
#define PANE_REDRAW 0x1 #define PANE_REDRAW 0x1
@@ -3266,7 +3266,7 @@ struct window_pane *window_pane_find_by_id_str(const char *);
struct window_pane *window_pane_find_by_id(u_int); struct window_pane *window_pane_find_by_id(u_int);
int window_pane_destroy_ready(struct window_pane *); int window_pane_destroy_ready(struct window_pane *);
void window_pane_resize(struct window_pane *, u_int, u_int); void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_move(struct window_pane *, u_int, u_int); void window_pane_move(struct window_pane *, int, int);
int window_pane_set_mode(struct window_pane *, int window_pane_set_mode(struct window_pane *,
struct window_pane *, const struct window_mode *, struct window_pane *, const struct window_mode *,
struct cmd_find_state *, struct args *); struct cmd_find_state *, struct args *);

8
tty.c
View File

@@ -2049,12 +2049,12 @@ tty_is_obscured(const struct tty_ctx *ctx)
if (found_self && wp->layout_cell == NULL && if (found_self && wp->layout_cell == NULL &&
! (wp->flags & PANE_MINIMISED) && ! (wp->flags & PANE_MINIMISED) &&
((wp->yoff >= base_wp->yoff && ((wp->yoff >= base_wp->yoff &&
wp->yoff <= base_wp->yoff + base_wp->sy) || wp->yoff <= base_wp->yoff + (int)base_wp->sy) ||
(wp->yoff + wp->sy >= base_wp->yoff && (wp->yoff + (int)wp->sy >= base_wp->yoff &&
wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) && wp->yoff + wp->sy <= base_wp->yoff + base_wp->sy)) &&
((wp->xoff >= base_wp->xoff && ((wp->xoff >= base_wp->xoff &&
wp->xoff <= base_wp->xoff + base_wp->sx) || wp->xoff <= base_wp->xoff + (int)base_wp->sx) ||
(wp->xoff + wp->sx >= base_wp->xoff && (wp->xoff + (int)wp->sx >= base_wp->xoff &&
wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx))) wp->xoff + wp->sx <= base_wp->xoff + base_wp->sx)))
return (1); return (1);
} }

View File

@@ -1118,7 +1118,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
} }
void void
window_pane_move(struct window_pane *wp, u_int xoff, u_int yoff) window_pane_move(struct window_pane *wp, int xoff, int yoff)
{ {
if (xoff == wp->xoff && yoff == wp->yoff) if (xoff == wp->xoff && yoff == wp->yoff)
return; return;