mirror of
https://github.com/openbsd/src.git
synced 2026-06-18 07:13:36 +02:00
Rename the visible ranges functions since they really relate to windows
and put them nto a new file.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.114 2026/02/24 08:20:52 nicm Exp $
|
||||
# $OpenBSD: Makefile,v 1.115 2026/06/16 10:47:35 nicm Exp $
|
||||
|
||||
PROG= tmux
|
||||
SRCS= alerts.c \
|
||||
@@ -130,6 +130,7 @@ SRCS= alerts.c \
|
||||
window-clock.c \
|
||||
window-copy.c \
|
||||
window-customize.c \
|
||||
window-visible.c \
|
||||
window-tree.c \
|
||||
window.c \
|
||||
xmalloc.c
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-display-panes.c,v 1.52 2026/06/15 21:47:01 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-display-panes.c,v 1.53 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -65,8 +65,7 @@ cmd_display_panes_put(struct screen_redraw_ctx *ctx,
|
||||
struct visible_range *ri;
|
||||
u_int i, j;
|
||||
|
||||
r = screen_redraw_get_visible_ranges(wp, ctx->ox + cx, ctx->oy + cy,
|
||||
len, NULL);
|
||||
r = window_visible_ranges(wp, ctx->ox + cx, ctx->oy + cy, len, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
for (j = ri->px; j < ri->px + ri->nx; j++) {
|
||||
@@ -103,7 +102,7 @@ cmd_display_panes_draw_format(struct screen_redraw_ctx *ctx,
|
||||
screen_write_stop(&sctx);
|
||||
free(expanded);
|
||||
|
||||
r = screen_redraw_get_visible_ranges(wp, px, wp->yoff, sx, NULL);
|
||||
r = window_visible_ranges(wp, px, wp->yoff, sx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
tty_draw_line(tty, &screen, ri->px - px, 0, ri->nx,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: screen-redraw.c,v 1.141 2026/06/16 08:53:14 nicm Exp $ */
|
||||
/* $OpenBSD: screen-redraw.c,v 1.142 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -734,7 +734,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
|
||||
}
|
||||
|
||||
r = tty_check_overlay_range(tty, x, yoff, width);
|
||||
r = screen_redraw_get_visible_ranges(wp, x, yoff, width, r);
|
||||
r = window_visible_ranges(wp, x, yoff, width, r);
|
||||
if (ctx->statustop)
|
||||
yoff += ctx->statuslines;
|
||||
for (i = 0; i < r->used; i++) {
|
||||
@@ -1125,205 +1125,6 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
|
||||
tty_draw_line(tty, s, 0, i, UINT_MAX, 0, y + i, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a single character is within a visible range (not obscured by a
|
||||
* floating pane).
|
||||
*/
|
||||
int
|
||||
screen_redraw_is_visible(struct visible_ranges *r, u_int px)
|
||||
{
|
||||
u_int i;
|
||||
struct visible_range *ri;
|
||||
|
||||
if (r == NULL)
|
||||
return (1);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx != 0 && px >= ri->px && px < ri->px + ri->nx)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct ranges array for the line at starting at px,py of width cells of
|
||||
* base_wp that are unobsructed. All ranges are in window coordinates.
|
||||
*/
|
||||
struct visible_ranges *
|
||||
screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
|
||||
int py, u_int width, struct visible_ranges *r)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
struct window *w;
|
||||
struct visible_range *ri;
|
||||
static struct visible_ranges sr = { NULL, 0, 0 };
|
||||
int found_self, sb, sb_w, sb_pos, no_border;
|
||||
int lb, rb, tb, bb, sx, ex;
|
||||
u_int i, s;
|
||||
|
||||
if (py < 0 || width == 0)
|
||||
goto empty;
|
||||
if (px < 0) {
|
||||
if ((u_int)-px >= width)
|
||||
goto empty;
|
||||
width -= (u_int)-px;
|
||||
px = 0;
|
||||
}
|
||||
|
||||
if (base_wp == NULL) {
|
||||
if (r != NULL)
|
||||
return (r);
|
||||
if (sr.ranges == NULL)
|
||||
sr.ranges = xcalloc(1, sizeof *sr.ranges);
|
||||
sr.ranges[0].px = px;
|
||||
sr.ranges[0].nx = width;
|
||||
sr.size = 1;
|
||||
sr.used = 1;
|
||||
return (&sr);
|
||||
}
|
||||
|
||||
w = base_wp->window;
|
||||
if ((u_int)py >= w->sy)
|
||||
goto empty;
|
||||
if (px + width > w->sx)
|
||||
width = w->sx - px;
|
||||
|
||||
if (r == NULL) {
|
||||
/* Start with the entire width of the range. */
|
||||
server_client_ensure_ranges(&base_wp->r, 1);
|
||||
r = &base_wp->r;
|
||||
r->ranges[0].px = px;
|
||||
r->ranges[0].nx = width;
|
||||
r->used = 1;
|
||||
}
|
||||
|
||||
sb = options_get_number(w->options, "pane-scrollbars");
|
||||
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
|
||||
|
||||
found_self = 0;
|
||||
TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) {
|
||||
if (wp == base_wp) {
|
||||
found_self = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (window_pane_is_floating(wp) &&
|
||||
window_pane_get_pane_lines(wp) == PANE_LINES_NONE)
|
||||
no_border = 1;
|
||||
else
|
||||
no_border = 0;
|
||||
if (no_border) {
|
||||
tb = wp->yoff;
|
||||
bb = wp->yoff + (int)wp->sy - 1;
|
||||
} else {
|
||||
tb = wp->yoff > 0 ? wp->yoff - 1 : 0;
|
||||
bb = wp->yoff + (int)wp->sy;
|
||||
}
|
||||
if (!found_self ||
|
||||
!window_pane_is_visible(wp) ||
|
||||
py < tb ||
|
||||
py > bb)
|
||||
continue;
|
||||
if (!window_pane_is_floating(wp) && (py == tb || py == bb))
|
||||
continue;
|
||||
|
||||
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
||||
if (!window_pane_show_scrollbar(wp, sb))
|
||||
sb_w = sb_pos = 0;
|
||||
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (no_border) {
|
||||
lb = wp->xoff;
|
||||
rb = wp->xoff + (int)wp->sx - 1;
|
||||
} else if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||
if (wp->xoff > sb_w)
|
||||
lb = wp->xoff - 1 - sb_w;
|
||||
else
|
||||
lb = 0;
|
||||
} else { /* PANE_SCROLLBARS_RIGHT or none. */
|
||||
if (wp->xoff > 0)
|
||||
lb = wp->xoff - 1;
|
||||
else
|
||||
lb = 0;
|
||||
}
|
||||
if (!no_border) {
|
||||
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||
rb = wp->xoff + (int)wp->sx;
|
||||
else /* PANE_SCROLLBARS_RIGHT or none. */
|
||||
rb = wp->xoff + (int)wp->sx + sb_w;
|
||||
}
|
||||
if (lb < 0)
|
||||
lb = 0;
|
||||
if (rb < 0)
|
||||
continue;
|
||||
if (no_border && rb >= (int)w->sx)
|
||||
rb = w->sx - 1;
|
||||
else if (!no_border && rb > (int)w->sx)
|
||||
rb = w->sx - 1;
|
||||
|
||||
sx = ri->px;
|
||||
ex = sx + ri->nx - 1;
|
||||
if (lb > sx && lb <= ex && rb > ex) {
|
||||
/*
|
||||
* If the left edge of floating pane falls
|
||||
* inside this range and right edge covers up
|
||||
* to right of range, then shrink left edge of
|
||||
* range.
|
||||
*/
|
||||
ri->nx = lb - sx;
|
||||
} else if (rb >= sx && rb <= ex && lb <= sx) {
|
||||
/*
|
||||
* Else if the right edge of floating pane falls
|
||||
* inside of this range and left edge covers
|
||||
* the left of range, then move px forward to
|
||||
* right edge of pane.
|
||||
*/
|
||||
ri->nx = ex - rb;
|
||||
ri->px = rb + 1;
|
||||
} else if (lb > sx && rb <= ex) {
|
||||
/*
|
||||
* Else if pane fully inside range then split
|
||||
* into 2 ranges.
|
||||
*/
|
||||
server_client_ensure_ranges(r, r->used + 1);
|
||||
for (s = r->used; s > i; s--) {
|
||||
memcpy(&r->ranges[s], &r->ranges[s - 1],
|
||||
sizeof *r->ranges);
|
||||
}
|
||||
ri = &r->ranges[i];
|
||||
r->ranges[i + 1].px = rb + 1;
|
||||
r->ranges[i + 1].nx = ex - rb;
|
||||
/* ri->px was copied, unchanged. */
|
||||
ri->nx = lb - sx;
|
||||
r->used++;
|
||||
} else if (lb <= sx && rb > ex) {
|
||||
/*
|
||||
* If floating pane completely covers this range
|
||||
* then delete it (make it 0 length).
|
||||
*/
|
||||
ri->nx = 0;
|
||||
} else {
|
||||
/*
|
||||
* The range is already obscured, do
|
||||
* nothing.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return (r);
|
||||
|
||||
empty:
|
||||
if (r == NULL) {
|
||||
if (sr.ranges == NULL)
|
||||
sr.ranges = xcalloc(1, sizeof *sr.ranges);
|
||||
sr.size = 1;
|
||||
sr.used = 0;
|
||||
return (&sr);
|
||||
}
|
||||
r->used = 0;
|
||||
return (r);
|
||||
}
|
||||
|
||||
/* Draw one pane. */
|
||||
static void
|
||||
@@ -1418,7 +1219,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||
|
||||
/* Get visible ranges of line before we draw it. */
|
||||
r = tty_check_overlay_range(tty, wx, wy, width);
|
||||
r = screen_redraw_get_visible_ranges(wp, wx, wy, width, r);
|
||||
r = window_visible_ranges(wp, wx, wy, width, r);
|
||||
for (k = 0; k < r->used; k++) {
|
||||
ri = &r->ranges[k];
|
||||
if (ri->nx == 0)
|
||||
@@ -1588,7 +1389,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
||||
wy = sb_wy + j; /* window y coordinate */
|
||||
py = sb_tty_y + j; /* tty y coordinate */
|
||||
r = tty_check_overlay_range(tty, sb_x, wy, imax);
|
||||
r = screen_redraw_get_visible_ranges(wp, sb_x, wy, imax, r);
|
||||
r = window_visible_ranges(wp, sb_x, wy, imax, r);
|
||||
for (i = imin; i < imax; i++) {
|
||||
px = sb_x + ox + i; /* tty x coordinate */
|
||||
wx = sb_x + i; /* window x coordinate */
|
||||
@@ -1596,7 +1397,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
||||
px >= sx || px < 0 ||
|
||||
wy < yoff - 1 ||
|
||||
py >= sy || py < 0 ||
|
||||
!screen_redraw_is_visible(r, wx))
|
||||
!window_position_is_visible(r, wx))
|
||||
continue;
|
||||
tty_cursor(tty, px, py);
|
||||
if ((sb_pos == PANE_SCROLLBARS_LEFT &&
|
||||
|
||||
+14
-19
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: screen-write.c,v 1.270 2026/06/15 14:56:30 nicm Exp $ */
|
||||
/* $OpenBSD: screen-write.c,v 1.271 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -644,8 +644,8 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
||||
break;
|
||||
s->cx = cx;
|
||||
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
||||
r = screen_redraw_get_visible_ranges(wp, xoff + s->cx,
|
||||
s->cy + yoff, nx, NULL);
|
||||
r = window_visible_ranges(wp, xoff + s->cx, s->cy + yoff, nx,
|
||||
NULL);
|
||||
for (xx = px; xx < px + nx; xx++) {
|
||||
gl = grid_get_line(gd, yy);
|
||||
sgl = grid_get_line(s->grid, s->cy);
|
||||
@@ -657,7 +657,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
||||
break;
|
||||
grid_view_set_cell(s->grid, s->cx, s->cy, &gc);
|
||||
|
||||
if (!screen_redraw_is_visible(r, xoff + s->cx))
|
||||
if (!window_position_is_visible(r, xoff + s->cx))
|
||||
break;
|
||||
ttyctx.cell = &gc;
|
||||
ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC);
|
||||
@@ -1162,7 +1162,7 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
||||
if (s->mode & MODE_SYNC)
|
||||
return;
|
||||
|
||||
r = screen_redraw_get_visible_ranges(wp, xoff, yoff + yy, sx, NULL);
|
||||
r = window_visible_ranges(wp, xoff, yoff + yy, sx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -1774,8 +1774,8 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||
|
||||
/* First line (containing the cursor). */
|
||||
if (s->cx <= sx - 1) {
|
||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff + s->cx,
|
||||
yoff + s->cy, sx - s->cx, NULL);
|
||||
r = window_visible_ranges(ctx->wp, xoff + s->cx, yoff + s->cy,
|
||||
sx - s->cx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -1788,8 +1788,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||
/* Below cursor to bottom. */
|
||||
for (y = s->cy + 1; y < sy; y++) {
|
||||
screen_write_set_cursor(ctx, 0, y);
|
||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
||||
sx, NULL);
|
||||
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -1846,8 +1845,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||
/* Top to above the cursor. */
|
||||
for (y = 0; y < s->cy; y++) {
|
||||
screen_write_set_cursor(ctx, 0, y);
|
||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
||||
sx, NULL);
|
||||
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -1859,8 +1857,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||
|
||||
/* Last line (containing the cursor). */
|
||||
screen_write_set_cursor(ctx, 0, s->cy);
|
||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + ocy,
|
||||
s->cx + 1, NULL);
|
||||
r = window_visible_ranges(ctx->wp, xoff, yoff + ocy, s->cx + 1, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -1916,8 +1913,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||
/* Clear every line. */
|
||||
for (y = 0; y < sy; y++) {
|
||||
screen_write_set_cursor(ctx, 0, y);
|
||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
||||
sx, NULL);
|
||||
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx == 0)
|
||||
@@ -2138,7 +2134,7 @@ screen_write_collect_flush_line(struct screen_write_ctx *ctx, u_int y)
|
||||
if (y + yoff >= wsy)
|
||||
return (0);
|
||||
|
||||
r = screen_redraw_get_visible_ranges(wp, 0, y + yoff, wsx, NULL);
|
||||
r = window_visible_ranges(wp, 0, y + yoff, wsx, NULL);
|
||||
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||
log_debug("collect list: x=%u (last %u), y=%u, used=%u", ci->x,
|
||||
last, y, ci->used);
|
||||
@@ -2528,8 +2524,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
xoff = wp->xoff;
|
||||
yoff = wp->yoff;
|
||||
}
|
||||
r = screen_redraw_get_visible_ranges(wp, xoff + s->cx, s->cy + yoff,
|
||||
width, NULL);
|
||||
r = window_visible_ranges(wp, xoff + s->cx, s->cy + yoff, width, NULL);
|
||||
|
||||
/*
|
||||
* Move the cursor. If not wrapping, stick at the last character and
|
||||
@@ -2701,7 +2696,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
*/
|
||||
if (wp != NULL)
|
||||
yoff = wp->yoff;
|
||||
r = screen_redraw_get_visible_ranges(wp, cx - n, cy + yoff, n, NULL);
|
||||
r = window_visible_ranges(wp, cx - n, cy + yoff, n, NULL);
|
||||
for (i = 0, vis = 0; i < r->used; i++)
|
||||
vis += r->ranges[i].nx;
|
||||
if (vis < n) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: server-client.c,v 1.472 2026/06/16 08:57:07 nicm Exp $ */
|
||||
/* $OpenBSD: server-client.c,v 1.473 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1851,8 +1851,8 @@ server_client_reset_state(struct client *c)
|
||||
cx = wp->xoff + (int)s->cx - (int)ox;
|
||||
cy = wp->yoff + (int)s->cy - (int)oy;
|
||||
|
||||
r = screen_redraw_get_visible_ranges(wp, cx, cy, 1, NULL);
|
||||
if (!screen_redraw_is_visible(r, cx))
|
||||
r = window_visible_ranges(wp, cx, cy, 1, NULL);
|
||||
if (!window_position_is_visible(r, cx))
|
||||
cursor = 0;
|
||||
|
||||
if (status_at_line(c) == 0)
|
||||
|
||||
+6
-4
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1355 2026/06/15 21:47:01 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1356 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -3339,9 +3339,6 @@ 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 *, u_int);
|
||||
struct visible_ranges *screen_redraw_get_visible_ranges(struct window_pane *,
|
||||
int, int, u_int, struct visible_ranges *);
|
||||
|
||||
/* screen.c */
|
||||
void screen_init(struct screen *, u_int, u_int, u_int);
|
||||
@@ -3489,6 +3486,11 @@ struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
|
||||
u_int);
|
||||
int window_pane_is_floating(struct window_pane *);
|
||||
|
||||
/* window-visible.c */
|
||||
int window_position_is_visible(struct visible_ranges *, u_int);
|
||||
struct visible_ranges *window_visible_ranges(struct window_pane *, int, int,
|
||||
u_int, struct visible_ranges *);
|
||||
|
||||
/* layout.c */
|
||||
u_int layout_count_cells(struct layout_cell *);
|
||||
struct layout_cell *layout_create_cell(struct layout_cell *);
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/* $OpenBSD: window-visible.c,v 1.1 2026/06/16 10:47:35 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Check if a single character is within a visible range (not obscured by a
|
||||
* floating pane).
|
||||
*/
|
||||
int
|
||||
window_position_is_visible(struct visible_ranges *r, u_int px)
|
||||
{
|
||||
u_int i;
|
||||
struct visible_range *ri;
|
||||
|
||||
if (r == NULL)
|
||||
return (1);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (ri->nx != 0 && px >= ri->px && px < ri->px + ri->nx)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct ranges array for the line at starting at px,py of width cells of
|
||||
* base_wp that are unobsructed. All ranges are in window coordinates.
|
||||
*/
|
||||
struct visible_ranges *
|
||||
window_visible_ranges(struct window_pane *base_wp, int px, int py, u_int width,
|
||||
struct visible_ranges *r)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
struct window *w;
|
||||
struct visible_range *ri;
|
||||
static struct visible_ranges sr = { NULL, 0, 0 };
|
||||
int found_self, sb, sb_w, sb_pos;
|
||||
int lb, rb, tb, bb, sx, ex, no_border;
|
||||
u_int i, s;
|
||||
|
||||
if (py < 0 || width == 0)
|
||||
goto empty;
|
||||
if (px < 0) {
|
||||
if ((u_int)-px >= width)
|
||||
goto empty;
|
||||
width -= (u_int)-px;
|
||||
px = 0;
|
||||
}
|
||||
|
||||
if (base_wp == NULL) {
|
||||
if (r != NULL)
|
||||
return (r);
|
||||
if (sr.ranges == NULL)
|
||||
sr.ranges = xcalloc(1, sizeof *sr.ranges);
|
||||
sr.ranges[0].px = px;
|
||||
sr.ranges[0].nx = width;
|
||||
sr.size = 1;
|
||||
sr.used = 1;
|
||||
return (&sr);
|
||||
}
|
||||
|
||||
w = base_wp->window;
|
||||
if ((u_int)py >= w->sy)
|
||||
goto empty;
|
||||
if (px + width > w->sx)
|
||||
width = w->sx - px;
|
||||
|
||||
if (r == NULL) {
|
||||
/* Start with the entire width of the range. */
|
||||
server_client_ensure_ranges(&base_wp->r, 1);
|
||||
r = &base_wp->r;
|
||||
r->ranges[0].px = px;
|
||||
r->ranges[0].nx = width;
|
||||
r->used = 1;
|
||||
}
|
||||
|
||||
sb = options_get_number(w->options, "pane-scrollbars");
|
||||
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
|
||||
|
||||
found_self = 0;
|
||||
TAILQ_FOREACH_REVERSE(wp, &w->z_index, window_panes_zindex, zentry) {
|
||||
if (wp == base_wp) {
|
||||
found_self = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (window_pane_is_floating(wp) &&
|
||||
window_pane_get_pane_lines(wp) == PANE_LINES_NONE)
|
||||
no_border = 1;
|
||||
else
|
||||
no_border = 0;
|
||||
if (no_border) {
|
||||
tb = wp->yoff;
|
||||
bb = wp->yoff + (int)wp->sy - 1;
|
||||
} else {
|
||||
tb = wp->yoff > 0 ? wp->yoff - 1 : 0;
|
||||
bb = wp->yoff + (int)wp->sy;
|
||||
}
|
||||
if (!found_self ||
|
||||
!window_pane_is_visible(wp) ||
|
||||
py < tb ||
|
||||
py > bb)
|
||||
continue;
|
||||
if (!window_pane_is_floating(wp) && (py == tb || py == bb))
|
||||
continue;
|
||||
|
||||
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
||||
if (!window_pane_show_scrollbar(wp, sb))
|
||||
sb_w = sb_pos = 0;
|
||||
|
||||
for (i = 0; i < r->used; i++) {
|
||||
ri = &r->ranges[i];
|
||||
if (no_border) {
|
||||
lb = wp->xoff;
|
||||
rb = wp->xoff + (int)wp->sx - 1;
|
||||
} else if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||
if (wp->xoff > sb_w)
|
||||
lb = wp->xoff - 1 - sb_w;
|
||||
else
|
||||
lb = 0;
|
||||
} else { /* PANE_SCROLLBARS_RIGHT or none. */
|
||||
if (wp->xoff > 0)
|
||||
lb = wp->xoff - 1;
|
||||
else
|
||||
lb = 0;
|
||||
}
|
||||
if (!no_border) {
|
||||
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||
rb = wp->xoff + (int)wp->sx;
|
||||
else /* PANE_SCROLLBARS_RIGHT or none. */
|
||||
rb = wp->xoff + (int)wp->sx + sb_w;
|
||||
}
|
||||
if (lb < 0)
|
||||
lb = 0;
|
||||
if (rb < 0)
|
||||
continue;
|
||||
if (no_border && rb >= (int)w->sx)
|
||||
rb = w->sx - 1;
|
||||
else if (!no_border && rb > (int)w->sx)
|
||||
rb = w->sx - 1;
|
||||
|
||||
sx = ri->px;
|
||||
ex = sx + ri->nx - 1;
|
||||
if (lb > sx && lb <= ex && rb > ex) {
|
||||
/*
|
||||
* If the left edge of floating pane falls
|
||||
* inside this range and right edge covers up
|
||||
* to right of range, then shrink left edge of
|
||||
* range.
|
||||
*/
|
||||
ri->nx = lb - sx;
|
||||
} else if (rb >= sx && rb <= ex && lb <= sx) {
|
||||
/*
|
||||
* Else if the right edge of floating pane falls
|
||||
* inside of this range and left edge covers
|
||||
* the left of range, then move px forward to
|
||||
* right edge of pane.
|
||||
*/
|
||||
ri->nx = ex - rb;
|
||||
ri->px = rb + 1;
|
||||
} else if (lb > sx && rb <= ex) {
|
||||
/*
|
||||
* Else if pane fully inside range then split
|
||||
* into 2 ranges.
|
||||
*/
|
||||
server_client_ensure_ranges(r, r->used + 1);
|
||||
for (s = r->used; s > i; s--) {
|
||||
memcpy(&r->ranges[s], &r->ranges[s - 1],
|
||||
sizeof *r->ranges);
|
||||
}
|
||||
ri = &r->ranges[i];
|
||||
r->ranges[i + 1].px = rb + 1;
|
||||
r->ranges[i + 1].nx = ex - rb;
|
||||
/* ri->px was copied, unchanged. */
|
||||
ri->nx = lb - sx;
|
||||
r->used++;
|
||||
} else if (lb <= sx && rb > ex) {
|
||||
/*
|
||||
* If floating pane completely covers this range
|
||||
* then delete it (make it 0 length).
|
||||
*/
|
||||
ri->nx = 0;
|
||||
} else {
|
||||
/*
|
||||
* The range is already obscured, do
|
||||
* nothing.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return (r);
|
||||
|
||||
empty:
|
||||
if (r == NULL) {
|
||||
if (sr.ranges == NULL)
|
||||
sr.ranges = xcalloc(1, sizeof *sr.ranges);
|
||||
sr.size = 1;
|
||||
sr.used = 0;
|
||||
return (&sr);
|
||||
}
|
||||
r->used = 0;
|
||||
return (r);
|
||||
}
|
||||
Reference in New Issue
Block a user