mirror of
https://github.com/tmux/tmux.git
synced 2026-01-11 16:30:22 +00:00
Fix some of the offset issues when windows size is greater than tty size.
This commit is contained in:
112
screen-redraw.c
112
screen-redraw.c
@@ -232,15 +232,13 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
if ((wp->xoff == 0 || (int)px >= wp->xoff) &&
|
if ((wp->xoff == 0 || (int)px >= wp->xoff) &&
|
||||||
((int)px <= ex ||
|
((int)px <= ex ||
|
||||||
(sb_w != 0 && (int)px < ex + sb_w))) {
|
(sb_w != 0 && (int)px < ex + sb_w))) {
|
||||||
if (pane_status == PANE_STATUS_TOP) {
|
if (pane_status != PANE_STATUS_BOTTOM &&
|
||||||
if ((int)py == wp->yoff - 1)
|
wp->yoff != 0 &&
|
||||||
return (SCREEN_REDRAW_BORDER_TOP);
|
(int)py == wp->yoff - 1)
|
||||||
} else { /* PANE_STATUS_BOTTOM or OFF. */
|
return (SCREEN_REDRAW_BORDER_TOP);
|
||||||
if (wp->yoff != 0 && (int)py == wp->yoff - 1)
|
if (pane_status != PANE_STATUS_TOP &&
|
||||||
return (SCREEN_REDRAW_BORDER_TOP);
|
(int)py == ey)
|
||||||
if ((int)py == ey)
|
|
||||||
return (SCREEN_REDRAW_BORDER_BOTTOM);
|
return (SCREEN_REDRAW_BORDER_BOTTOM);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,6 +454,9 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
|||||||
|
|
||||||
/* Find pane higest in z-index at this point. */
|
/* Find pane higest in z-index at this point. */
|
||||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||||
|
if (wp->flags & PANE_FLOATING && (px >= sx || py >= sy))
|
||||||
|
/* Clip floating panes to window. */
|
||||||
|
continue;
|
||||||
sb_w = wp->scrollbar_style.width +
|
sb_w = wp->scrollbar_style.width +
|
||||||
wp->scrollbar_style.pad;
|
wp->scrollbar_style.pad;
|
||||||
if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||||
@@ -525,11 +526,11 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
|||||||
if (pane_status == PANE_STATUS_TOP)
|
if (pane_status == PANE_STATUS_TOP)
|
||||||
pane_status_line = wp->yoff - 1;
|
pane_status_line = wp->yoff - 1;
|
||||||
else
|
else
|
||||||
pane_status_line = wp->yoff + sy;
|
pane_status_line = wp->yoff + wp->sy;
|
||||||
left = wp->xoff + 2;
|
left = wp->xoff + 2;
|
||||||
right = wp->xoff + 2 + wp->status_size - 1;
|
right = wp->xoff + 2 + wp->status_size - 1;
|
||||||
|
|
||||||
if (py == pane_status_line &&
|
if (py == pane_status_line + ctx->oy && /* XXX unsure about adding oy here, needs more testing. */
|
||||||
(int)px >= left && (int)px <= right)
|
(int)px >= left && (int)px <= right)
|
||||||
return (CELL_INSIDE);
|
return (CELL_INSIDE);
|
||||||
}
|
}
|
||||||
@@ -719,8 +720,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
|
|||||||
width = size - x;
|
width = size - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
vr = screen_redraw_get_visible_ranges(wp, x, yoff - ctx->oy,
|
vr = screen_redraw_get_visible_ranges(wp, x, yoff, width);
|
||||||
width);
|
|
||||||
|
|
||||||
if (ctx->statustop)
|
if (ctx->statustop)
|
||||||
yoff += ctx->statuslines;
|
yoff += ctx->statuslines;
|
||||||
@@ -1083,10 +1083,9 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
static struct visible_ranges vr = {NULL, NULL, 0, 0};
|
static struct visible_ranges vr = {NULL, NULL, 0, 0};
|
||||||
int found_self, sb_w;
|
int found_self, sb_w, sb_pos;
|
||||||
u_int lb, rb, tb, bb;
|
u_int lb, rb, tb, bb;
|
||||||
u_int r, s;
|
u_int r, s;
|
||||||
int pane_scrollbars, pane_scrollbars_pos;
|
|
||||||
|
|
||||||
/* For efficiency vr is static and space reused. */
|
/* For efficiency vr is static and space reused. */
|
||||||
if (vr.size == 0) {
|
if (vr.size == 0) {
|
||||||
@@ -1095,6 +1094,11 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
vr.size = 1;
|
vr.size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* debugging:
|
||||||
|
* display *vr.px@vr.used
|
||||||
|
* display *vr.nx@vr.used
|
||||||
|
*/
|
||||||
|
|
||||||
/* Start with the entire width of the range. */
|
/* Start with the entire width of the range. */
|
||||||
vr.px[0] = px;
|
vr.px[0] = px;
|
||||||
vr.nx[0] = width;
|
vr.nx[0] = width;
|
||||||
@@ -1104,8 +1108,7 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
return (&vr);
|
return (&vr);
|
||||||
|
|
||||||
w = base_wp->window;
|
w = base_wp->window;
|
||||||
pane_scrollbars = options_get_number(w->options, "pane-scrollbars");
|
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
|
||||||
pane_scrollbars_pos = options_get_number(w->options, "pane-scrollbars-position");
|
|
||||||
|
|
||||||
found_self = 0;
|
found_self = 0;
|
||||||
TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) {
|
TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) {
|
||||||
@@ -1118,18 +1121,23 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
bb = wp->yoff + wp->sy;
|
bb = wp->yoff + wp->sy;
|
||||||
if (!found_self ||
|
if (!found_self ||
|
||||||
!window_pane_visible(wp) ||
|
!window_pane_visible(wp) ||
|
||||||
py < tb ||
|
py < tb || py > bb)
|
||||||
((wp->flags & PANE_FLOATING) && py > bb) ||
|
continue;
|
||||||
(~(wp->flags & PANE_FLOATING) && py > bb))
|
if (~wp->flags & PANE_FLOATING && py == bb)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Are scrollbars enabled? */
|
/* Are scrollbars enabled? */
|
||||||
if (window_pane_show_scrollbar(wp, pane_scrollbars))
|
if (window_pane_show_scrollbar(wp,
|
||||||
|
options_get_number(w->options, "pane-scrollbars")))
|
||||||
sb_w = wp->scrollbar_style.width +
|
sb_w = wp->scrollbar_style.width +
|
||||||
wp->scrollbar_style.pad;
|
wp->scrollbar_style.pad;
|
||||||
|
else {
|
||||||
|
sb_w = 0;
|
||||||
|
sb_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (r=0; r < vr.used; r++) {
|
for (r=0; r < vr.used; r++) {
|
||||||
if (pane_scrollbars_pos == PANE_SCROLLBARS_LEFT) {
|
if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||||
if (wp->xoff > sb_w)
|
if (wp->xoff > sb_w)
|
||||||
lb = wp->xoff - 1 - sb_w;
|
lb = wp->xoff - 1 - sb_w;
|
||||||
else
|
else
|
||||||
@@ -1140,7 +1148,7 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, u_int px,
|
|||||||
else
|
else
|
||||||
lb = 0;
|
lb = 0;
|
||||||
}
|
}
|
||||||
if (pane_scrollbars_pos == PANE_SCROLLBARS_LEFT)
|
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||||
rb = wp->xoff + wp->sx;
|
rb = wp->xoff + wp->sx;
|
||||||
else /* PANE_SCROLLBARS_RIGHT or none. */
|
else /* PANE_SCROLLBARS_RIGHT or none. */
|
||||||
rb = wp->xoff + wp->sx + sb_w;
|
rb = wp->xoff + wp->sx + sb_w;
|
||||||
@@ -1216,7 +1224,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
struct colour_palette *palette = &wp->palette;
|
struct colour_palette *palette = &wp->palette;
|
||||||
struct grid_cell defaults;
|
struct grid_cell defaults;
|
||||||
struct visible_ranges *vr;
|
struct visible_ranges *vr;
|
||||||
u_int i, j, top, x, y, width, r;
|
u_int i, j, woy, wx, wy, px, py, width, r;
|
||||||
|
|
||||||
if (wp->base.mode & MODE_SYNC)
|
if (wp->base.mode & MODE_SYNC)
|
||||||
screen_write_stop_sync(wp);
|
screen_write_stop_sync(wp);
|
||||||
@@ -1226,16 +1234,22 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
if (wp->xoff + (int)wp->sx <= ctx->ox ||
|
if (wp->xoff + (int)wp->sx <= ctx->ox ||
|
||||||
wp->xoff >= ctx->ox + (int)ctx->sx)
|
wp->xoff >= ctx->ox + (int)ctx->sx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* woy is window y offset in tty. */
|
||||||
if (ctx->statustop)
|
if (ctx->statustop)
|
||||||
top = ctx->statuslines;
|
woy = ctx->statuslines;
|
||||||
else
|
else
|
||||||
top = 0;
|
woy = 0;
|
||||||
|
|
||||||
for (j = 0; j < wp->sy; j++) {
|
for (j = 0; j < wp->sy; j++) {
|
||||||
if (wp->yoff + (int)j < ctx->oy ||
|
if (wp->yoff + (int)j < ctx->oy ||
|
||||||
wp->yoff + j >= ctx->oy + ctx->sy)
|
wp->yoff + j >= ctx->oy + ctx->sy)
|
||||||
continue;
|
continue;
|
||||||
y = wp->yoff + j - ctx->oy;
|
wy = wp->yoff + j; /* y line within window w. */
|
||||||
|
py = woy + wy - ctx->oy; /* y line within tty. */
|
||||||
|
if (py > tty->sy)
|
||||||
|
/* Continue if this line is off of tty. */
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Note: i is apparenty not used now that the vr array
|
/* Note: i is apparenty not used now that the vr array
|
||||||
* returns where in s to read from.
|
* returns where in s to read from.
|
||||||
@@ -1244,42 +1258,44 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
|
wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
|
||||||
/* All visible. */
|
/* All visible. */
|
||||||
i = 0;
|
i = 0;
|
||||||
x = wp->xoff - ctx->ox;
|
wx = wp->xoff - ctx->ox;
|
||||||
width = wp->sx;
|
width = wp->sx;
|
||||||
} else if (wp->xoff < ctx->ox &&
|
} else if (wp->xoff < ctx->ox &&
|
||||||
wp->xoff + wp->sx > ctx->ox + ctx->sx) {
|
wp->xoff + wp->sx > ctx->ox + ctx->sx) {
|
||||||
/* Both left and right not visible. */
|
/* Both left and right not visible. */
|
||||||
i = ctx->ox;
|
i = ctx->ox;
|
||||||
x = 0;
|
wx = 0;
|
||||||
width = ctx->sx;
|
width = ctx->sx;
|
||||||
} else if (wp->xoff < ctx->ox) {
|
} else if (wp->xoff < ctx->ox) {
|
||||||
/* Left not visible. */
|
/* Left not visible. */
|
||||||
i = ctx->ox - wp->xoff;
|
i = ctx->ox - wp->xoff;
|
||||||
x = 0;
|
wx = 0;
|
||||||
width = wp->sx - i;
|
width = wp->sx - i;
|
||||||
} else {
|
} else {
|
||||||
/* Right not visible. */
|
/* Right not visible. */
|
||||||
i = 0;
|
i = 0;
|
||||||
x = wp->xoff - ctx->ox;
|
wx = wp->xoff - ctx->ox;
|
||||||
width = ctx->sx - x;
|
width = ctx->sx - wx;
|
||||||
}
|
}
|
||||||
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
||||||
__func__, c->name, wp->id, i, j, x, y, width);
|
__func__, c->name, wp->id, i, j, wx, wy, width);
|
||||||
|
|
||||||
/* Get visible ranges of line before we draw it. */
|
/* Get visible ranges of line before we draw it. */
|
||||||
vr = screen_redraw_get_visible_ranges(wp, x, y, width);
|
vr = screen_redraw_get_visible_ranges(wp, wx, wy, width);
|
||||||
|
|
||||||
tty_default_colours(&defaults, wp);
|
tty_default_colours(&defaults, wp);
|
||||||
|
|
||||||
for (r=0; r < vr->used; r++) {
|
for (r=0; r < vr->used; r++) {
|
||||||
if (vr->nx[r] == 0)
|
if (vr->nx[r] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
/* Convert window coordinates to tty coordinates. */
|
||||||
|
px = vr->px[r];
|
||||||
/* 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. note: i apparently unnec.
|
* contents of pane shifted. note: i apparently unnec.
|
||||||
*/
|
*/
|
||||||
tty_draw_line(tty, s, /* i + */ vr->px[r] - wp->xoff, j,
|
tty_draw_line(tty, s, /* i + */ vr->px[r] - wp->xoff, j,
|
||||||
vr->nx[r], vr->px[r], top + y, &defaults, palette);
|
vr->nx[r], px, py, &defaults, palette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1305,7 +1321,7 @@ screen_redraw_draw_pane_scrollbars(struct screen_redraw_ctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw pane scrollbar. */
|
/* Calculate position and size of pane scrollbar. */
|
||||||
void
|
void
|
||||||
screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
||||||
struct window_pane *wp)
|
struct window_pane *wp)
|
||||||
@@ -1316,8 +1332,8 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
u_int sb_pos = ctx->pane_scrollbars_pos, slider_h, slider_y;
|
u_int sb_pos = ctx->pane_scrollbars_pos, slider_h, slider_y;
|
||||||
int sb_w = wp->scrollbar_style.width;
|
int sb_w = wp->scrollbar_style.width;
|
||||||
int sb_pad = wp->scrollbar_style.pad;
|
int sb_pad = wp->scrollbar_style.pad;
|
||||||
int cm_y, cm_size, xoff = wp->xoff, ox = ctx->ox;
|
int cm_y, cm_size, xoff = wp->xoff;
|
||||||
int sb_x, sb_y = (int)(wp->yoff - ctx->oy); /* sb top */
|
int sb_x, sb_y = (int)(wp->yoff); /* sb top */
|
||||||
|
|
||||||
if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) {
|
if (window_pane_mode(wp) == WINDOW_PANE_NO_MODE) {
|
||||||
if (sb == PANE_SCROLLBARS_MODAL)
|
if (sb == PANE_SCROLLBARS_MODAL)
|
||||||
@@ -1335,13 +1351,13 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
total_height = cm_size + sb_h;
|
total_height = cm_size + sb_h;
|
||||||
percent_view = (double)sb_h / (cm_size + sb_h);
|
percent_view = (double)sb_h / (cm_size + sb_h);
|
||||||
slider_h = (double)sb_h * percent_view;
|
slider_h = (double)sb_h * percent_view;
|
||||||
slider_y = (sb_h + 1) * ((double)cm_y / total_height);
|
slider_y = (sb_h + 1) * ((double)cm_y / (total_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||||
sb_x = xoff - sb_w - sb_pad - ox;
|
sb_x = xoff - sb_w - sb_pad;
|
||||||
else
|
else
|
||||||
sb_x = xoff + wp->sx - ox;
|
sb_x = xoff + wp->sx;
|
||||||
|
|
||||||
if (slider_h < 1)
|
if (slider_h < 1)
|
||||||
slider_h = 1;
|
slider_h = 1;
|
||||||
@@ -1356,6 +1372,7 @@ screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
wp->sb_slider_h = slider_h; /* height of slider */
|
wp->sb_slider_h = slider_h; /* height of slider */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Draw pane scrollbar. */
|
||||||
static void
|
static void
|
||||||
screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
||||||
struct window_pane *wp, int sb_pos, int sb_x, int sb_y, u_int sb_h,
|
struct window_pane *wp, int sb_pos, int sb_x, int sb_y, u_int sb_h,
|
||||||
@@ -1377,12 +1394,13 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
* Status at top offsets window downward.
|
* Status at top offsets window downward.
|
||||||
*/
|
*/
|
||||||
sx = ctx->sx;
|
sx = ctx->sx;
|
||||||
sy = ctx->sy;
|
sy = tty->sy - ctx->statuslines;
|
||||||
ox = ctx->ox;
|
ox = ctx->ox;
|
||||||
oy = ctx->oy;
|
oy = ctx->oy;
|
||||||
if (ctx->statustop) {
|
if (ctx->statustop) {
|
||||||
sy += ctx->statuslines; /* Height of tty. */
|
sb_y += ctx->statuslines;
|
||||||
oy += ctx->statuslines; /* Top of w in tty. */
|
sy += ctx->statuslines; /* Height of window in tty. */
|
||||||
|
oy += ctx->statuslines; /* Top of window in tty. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1419,16 +1437,16 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
jmax = sy - sb_y;
|
jmax = sy - sb_y;
|
||||||
|
|
||||||
for (j = jmin; j < jmax; j++) {
|
for (j = jmin; j < jmax; j++) {
|
||||||
py = sb_y + oy + j; /* tty y coordinate. */
|
py = sb_y + j; /* tty y coordinate. */
|
||||||
wy = sb_y + j; /* window y coordinate. */
|
wy = sb_y + j + oy; /* window y coordinate. */
|
||||||
vr = screen_redraw_get_visible_ranges(wp, sb_x, wy, imax);
|
vr = screen_redraw_get_visible_ranges(wp, sb_x, wy, imax);
|
||||||
for (i = imin; i < imax; i++) {
|
for (i = imin; i < imax; i++) {
|
||||||
px = sb_x + ox + i; /* tty x coordinate. */
|
px = sb_x + ox + i; /* tty x coordinate. */
|
||||||
wx = sb_x + i; /* window x coordinate. */
|
wx = sb_x + i; /* window x coordinate. */
|
||||||
if (wx < xoff - (int)sb_w - (int)sb_pad ||
|
if (wx < xoff - (int)sb_w - (int)sb_pad ||
|
||||||
wx >= sx || wx < 0 ||
|
px >= sx || px < 0 ||
|
||||||
wy < yoff - 1 ||
|
wy < yoff - 1 ||
|
||||||
wy >= sy || wy < 0 ||
|
py >= sy || py < 0 ||
|
||||||
! screen_redraw_is_visible(vr, wx))
|
! screen_redraw_is_visible(vr, wx))
|
||||||
continue;
|
continue;
|
||||||
tty_cursor(tty, px, py);
|
tty_cursor(tty, px, py);
|
||||||
|
|||||||
7
tty.c
7
tty.c
@@ -1007,7 +1007,10 @@ tty_window_offset1(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy)
|
|||||||
else if (cy > w->sy - *sy)
|
else if (cy > w->sy - *sy)
|
||||||
*oy = w->sy - *sy;
|
*oy = w->sy - *sy;
|
||||||
else
|
else
|
||||||
*oy = cy - *sy / 2;
|
/* cy-sy/2 was causing panned panes to scroll
|
||||||
|
* when the cursor was half way down the pane.
|
||||||
|
*/
|
||||||
|
*oy = cy - *sy + 1; /* cy - *sy / 2; */
|
||||||
}
|
}
|
||||||
|
|
||||||
c->pan_window = NULL;
|
c->pan_window = NULL;
|
||||||
@@ -1220,7 +1223,7 @@ tty_clear_pane_line(struct tty *tty, const struct tty_ctx *ctx, u_int py,
|
|||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
struct window_pane *wp = ctx->arg;
|
struct window_pane *wp = ctx->arg;
|
||||||
struct visible_ranges *vr = NULL;
|
struct visible_ranges *vr = NULL;
|
||||||
u_int r, i, x, rx, ry, oy = 0;
|
u_int r, i, x, rx, ry;
|
||||||
|
|
||||||
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py);
|
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user