mirror of
https://github.com/tmux/tmux.git
synced 2026-06-21 17:55:21 +00:00
Merge branch 'master' into floating_panes
This commit is contained in:
@@ -217,6 +217,7 @@ dist_tmux_SOURCES = \
|
|||||||
window-copy.c \
|
window-copy.c \
|
||||||
window-customize.c \
|
window-customize.c \
|
||||||
window-tree.c \
|
window-tree.c \
|
||||||
|
window-visible.c \
|
||||||
window.c \
|
window.c \
|
||||||
xmalloc.c \
|
xmalloc.c \
|
||||||
xmalloc.h
|
xmalloc.h
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
w->active = wp;
|
w->active = wp;
|
||||||
w->latest = tc;
|
w->latest = tc;
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name == NULL) {
|
||||||
newname = default_window_name(w);
|
newname = default_window_name(w);
|
||||||
window_set_name(w, newname, WINDOW_NAME_FORBID);
|
window_set_name(w, newname, WINDOW_NAME_FORBID);
|
||||||
free(newname);
|
free(newname);
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ cmd_display_panes_put(struct screen_redraw_ctx *ctx,
|
|||||||
struct visible_range *ri;
|
struct visible_range *ri;
|
||||||
u_int i, j;
|
u_int i, j;
|
||||||
|
|
||||||
r = screen_redraw_get_visible_ranges(wp, ctx->ox + cx, ctx->oy + cy,
|
r = window_visible_ranges(wp, ctx->ox + cx, ctx->oy + cy, len, NULL);
|
||||||
len, NULL);
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
for (j = ri->px; j < ri->px + ri->nx; j++) {
|
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);
|
screen_write_stop(&sctx);
|
||||||
free(expanded);
|
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++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
tty_draw_line(tty, &screen, ri->px - px, 0, ri->nx,
|
tty_draw_line(tty, &screen, ri->px - px, 0, ri->nx,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
struct winlink *wl = target->wl, *new_wl = NULL;
|
struct winlink *wl = target->wl, *new_wl = NULL;
|
||||||
int idx = target->idx, before;
|
int idx = target->idx, before;
|
||||||
char *cause = NULL, *cp, *expanded, *wname;
|
char *cause = NULL, *cp, *expanded, *wname = NULL;
|
||||||
const char *template, *name;
|
const char *template, *name;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
struct args_value *av;
|
struct args_value *av;
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct layout_cell *lc;
|
struct layout_cell *lc;
|
||||||
int y, ly, x, lx, sx, sy, new_sx, new_sy;
|
int y, ly, x, lx, sx, sy, new_sx, new_sy;
|
||||||
|
int scrollbars, sb_pos, left, right;
|
||||||
int new_xoff, new_yoff, resizes = 0;
|
int new_xoff, new_yoff, resizes = 0;
|
||||||
|
|
||||||
wp = cmd_mouse_pane(m, NULL, &wl);
|
wp = cmd_mouse_pane(m, NULL, &wl);
|
||||||
@@ -237,6 +238,17 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
lc = wp->layout_cell;
|
lc = wp->layout_cell;
|
||||||
sx = wp->sx;
|
sx = wp->sx;
|
||||||
sy = wp->sy;
|
sy = wp->sy;
|
||||||
|
scrollbars = options_get_number(w->options, "pane-scrollbars");
|
||||||
|
sb_pos = options_get_number(w->options, "pane-scrollbars-position");
|
||||||
|
left = wp->xoff - 1;
|
||||||
|
right = wp->xoff + sx;
|
||||||
|
if (window_pane_show_scrollbar(wp, scrollbars) &&
|
||||||
|
sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||||
|
left -= wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
||||||
|
} else if (window_pane_show_scrollbar(wp, scrollbars) &&
|
||||||
|
sb_pos == PANE_SCROLLBARS_RIGHT) {
|
||||||
|
right += wp->scrollbar_style.width + wp->scrollbar_style.pad;
|
||||||
|
}
|
||||||
|
|
||||||
y = m->y + m->oy; x = m->x + m->ox;
|
y = m->y + m->oy; x = m->x + m->ox;
|
||||||
if (m->statusat == 0 && y >= (int)m->statuslines)
|
if (m->statusat == 0 && y >= (int)m->statuslines)
|
||||||
@@ -249,7 +261,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
else if (m->statusat > 0 && ly >= m->statusat)
|
else if (m->statusat > 0 && ly >= m->statusat)
|
||||||
ly = m->statusat - 1;
|
ly = m->statusat - 1;
|
||||||
|
|
||||||
if ((lx == wp->xoff - 1 || lx == wp->xoff) && ly == wp->yoff - 1) {
|
if ((lx == left || lx == left + 1) && ly == wp->yoff - 1) {
|
||||||
/* Top left corner. */
|
/* Top left corner. */
|
||||||
new_sx = lc->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
@@ -261,7 +273,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
new_yoff = y + 1;
|
new_yoff = y + 1;
|
||||||
layout_set_size(lc, new_sx, new_sy, new_xoff, new_yoff);
|
layout_set_size(lc, new_sx, new_sy, new_xoff, new_yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((lx == wp->xoff + sx + 1 || lx == wp->xoff + sx) &&
|
} else if ((lx == right + 1 || lx == right) &&
|
||||||
ly == wp->yoff - 1) {
|
ly == wp->yoff - 1) {
|
||||||
/* Top right corner. */
|
/* Top right corner. */
|
||||||
new_sx = x - lc->xoff;
|
new_sx = x - lc->xoff;
|
||||||
@@ -273,7 +285,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
new_yoff = y + 1;
|
new_yoff = y + 1;
|
||||||
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
|
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((lx == wp->xoff - 1 || lx == wp->xoff) &&
|
} else if ((lx == left || lx == left + 1) &&
|
||||||
ly == wp->yoff + sy) {
|
ly == wp->yoff + sy) {
|
||||||
/* Bottom left corner. */
|
/* Bottom left corner. */
|
||||||
new_sx = lc->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
@@ -285,7 +297,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
new_xoff = x + 1;
|
new_xoff = x + 1;
|
||||||
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
|
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if ((lx == wp->xoff + sx + 1 || lx == wp->xoff + sx) &&
|
} else if ((lx == right + 1 || lx == right) &&
|
||||||
ly == wp->yoff + sy) {
|
ly == wp->yoff + sy) {
|
||||||
/* Bottom right corner. */
|
/* Bottom right corner. */
|
||||||
new_sx = x - lc->xoff;
|
new_sx = x - lc->xoff;
|
||||||
@@ -296,14 +308,14 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
|
|||||||
new_sy = PANE_MINIMUM;
|
new_sy = PANE_MINIMUM;
|
||||||
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
|
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if (lx == wp->xoff + sx + 1) {
|
} else if (lx == right) {
|
||||||
/* Right border. */
|
/* Right border. */
|
||||||
new_sx = x - lc->xoff;
|
new_sx = x - lc->xoff;
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
return;
|
return;
|
||||||
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
|
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
|
||||||
resizes++;
|
resizes++;
|
||||||
} else if (lx == wp->xoff - 1) {
|
} else if (lx == left) {
|
||||||
/* Left border. */
|
/* Left border. */
|
||||||
new_sx = lc->sx + (lx - x);
|
new_sx = lc->sx + (lx - x);
|
||||||
if (new_sx < PANE_MINIMUM)
|
if (new_sx < PANE_MINIMUM)
|
||||||
|
|||||||
35
configure.ac
35
configure.ac
@@ -297,24 +297,24 @@ fi
|
|||||||
# Look for ncurses or curses. Try pkg-config first then directly for the
|
# Look for ncurses or curses. Try pkg-config first then directly for the
|
||||||
# library.
|
# library.
|
||||||
PKG_CHECK_MODULES(
|
PKG_CHECK_MODULES(
|
||||||
LIBTINFO,
|
LIBTINFOW,
|
||||||
tinfo,
|
tinfow,
|
||||||
[
|
[
|
||||||
AM_CPPFLAGS="$LIBTINFO_CFLAGS $AM_CPPFLAGS"
|
AM_CPPFLAGS="$LIBTINFOW_CFLAGS $AM_CPPFLAGS"
|
||||||
CPPFLAGS="$LIBTINFO_CFLAGS $SAVED_CPPFLAGS"
|
CPPFLAGS="$LIBTINFOW_CFLAGS $SAVED_CPPFLAGS"
|
||||||
LIBS="$LIBTINFO_LIBS $LIBS"
|
LIBS="$LIBTINFOW_LIBS $LIBS"
|
||||||
found_ncurses=yes
|
found_ncurses=yes
|
||||||
],
|
],
|
||||||
found_ncurses=no
|
found_ncurses=no
|
||||||
)
|
)
|
||||||
if test "x$found_ncurses" = xno; then
|
if test "x$found_ncurses" = xno; then
|
||||||
PKG_CHECK_MODULES(
|
PKG_CHECK_MODULES(
|
||||||
LIBNCURSES,
|
LIBTINFO,
|
||||||
ncurses,
|
tinfo,
|
||||||
[
|
[
|
||||||
AM_CPPFLAGS="$LIBNCURSES_CFLAGS $AM_CPPFLAGS"
|
AM_CPPFLAGS="$LIBTINFO_CFLAGS $AM_CPPFLAGS"
|
||||||
CPPFLAGS="$LIBNCURSES_CFLAGS $SAVED_CPPFLAGS"
|
CPPFLAGS="$LIBTINFO_CFLAGS $SAVED_CPPFLAGS"
|
||||||
LIBS="$LIBNCURSES_LIBS $LIBS"
|
LIBS="$LIBTINFO_LIBS $LIBS"
|
||||||
found_ncurses=yes
|
found_ncurses=yes
|
||||||
],
|
],
|
||||||
found_ncurses=no
|
found_ncurses=no
|
||||||
@@ -333,10 +333,23 @@ if test "x$found_ncurses" = xno; then
|
|||||||
found_ncurses=no
|
found_ncurses=no
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
if test "x$found_ncurses" = xno; then
|
||||||
|
PKG_CHECK_MODULES(
|
||||||
|
LIBNCURSES,
|
||||||
|
ncurses,
|
||||||
|
[
|
||||||
|
AM_CPPFLAGS="$LIBNCURSES_CFLAGS $AM_CPPFLAGS"
|
||||||
|
CPPFLAGS="$LIBNCURSES_CFLAGS $SAVED_CPPFLAGS"
|
||||||
|
LIBS="$LIBNCURSES_LIBS $LIBS"
|
||||||
|
found_ncurses=yes
|
||||||
|
],
|
||||||
|
found_ncurses=no
|
||||||
|
)
|
||||||
|
fi
|
||||||
if test "x$found_ncurses" = xno; then
|
if test "x$found_ncurses" = xno; then
|
||||||
AC_SEARCH_LIBS(
|
AC_SEARCH_LIBS(
|
||||||
setupterm,
|
setupterm,
|
||||||
[tinfo terminfo ncurses ncursesw],
|
[tinfow tinfo terminfo ncursesw ncurses],
|
||||||
found_ncurses=yes,
|
found_ncurses=yes,
|
||||||
found_ncurses=no
|
found_ncurses=no
|
||||||
)
|
)
|
||||||
|
|||||||
57
layout.c
57
layout.c
@@ -28,10 +28,10 @@
|
|||||||
* left-right container for a list of cells, a top-bottom container for a list
|
* left-right container for a list of cells, a top-bottom container for a list
|
||||||
* of cells, or a container for a window pane. 'Node' will be used to refer to
|
* of cells, or a container for a window pane. 'Node' will be used to refer to
|
||||||
* a cell which contains a list of cells, and 'leaf' to refer to a cell that
|
* a cell which contains a list of cells, and 'leaf' to refer to a cell that
|
||||||
* contains a window pane. A leaf is considered to be tiled if it is to be drawn
|
* contains a window pane. A leaf is considered to be 'tiled' if it is to be
|
||||||
* as a part of the tiled layout. A 'neighbour' is a sibling that is also tiled.
|
* drawn as a part of the tiled layout. A 'neighbour' is a sibling that is also
|
||||||
* A cell's 'split' size refers to the side that is shortened when splitting it,
|
* tiled. A cell's 'split' size refers to the side that is shortened when
|
||||||
* determined by the parent's type.
|
* splitting it, determined by the parent's type.
|
||||||
*
|
*
|
||||||
* Each window has a pointer to the root of its layout tree (containing its
|
* Each window has a pointer to the root of its layout tree (containing its
|
||||||
* panes), every pane has a pointer back to the cell containing it, and each
|
* panes), every pane has a pointer back to the cell containing it, and each
|
||||||
@@ -264,6 +264,49 @@ layout_fix_zindexes(struct window *w, struct layout_cell *lc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_is_tiled(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
int is_leaf = lc->type == LAYOUT_WINDOWPANE;
|
||||||
|
int is_floating = lc->flags & LAYOUT_CELL_FLOATING;
|
||||||
|
|
||||||
|
return is_leaf && !is_floating;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_has_tiled_child(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild;
|
||||||
|
|
||||||
|
if (lc->type == LAYOUT_WINDOWPANE)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
|
if (layout_cell_is_tiled(lcchild) ||
|
||||||
|
layout_cell_has_tiled_child(lcchild))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_is_first_tiled(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild, *lcparent = lc->parent;
|
||||||
|
|
||||||
|
if (lcparent == NULL)
|
||||||
|
return (layout_cell_is_tiled(lc));
|
||||||
|
|
||||||
|
TAILQ_FOREACH(lcchild, &lcparent->cells, entry) {
|
||||||
|
if (layout_cell_is_tiled(lcchild) ||
|
||||||
|
layout_cell_has_tiled_child(lcchild))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lcchild == lc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fix cell offsets for a child cell. */
|
/* Fix cell offsets for a child cell. */
|
||||||
static void
|
static void
|
||||||
layout_fix_offsets1(struct layout_cell *lc)
|
layout_fix_offsets1(struct layout_cell *lc)
|
||||||
@@ -725,8 +768,10 @@ out:
|
|||||||
lc->parent = lcparent->parent;
|
lc->parent = lcparent->parent;
|
||||||
|
|
||||||
if (lc->parent == NULL) {
|
if (lc->parent == NULL) {
|
||||||
if (layout_cell_is_tiled(lc))
|
if (layout_cell_is_tiled(lc)) {
|
||||||
layout_set_size(lc, w->sx, w->sy, 0, 0);
|
lc->xoff = 0;
|
||||||
|
lc->yoff = 0;
|
||||||
|
}
|
||||||
*lcroot = lc;
|
*lcroot = lc;
|
||||||
} else
|
} else
|
||||||
TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
|
TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
|
||||||
|
|||||||
232
screen-redraw.c
232
screen-redraw.c
@@ -129,7 +129,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
int hsplit = 0, vsplit = 0;
|
int hsplit = 0, vsplit = 0;
|
||||||
int pane_status = window_pane_get_pane_status(wp);
|
int pane_status = window_pane_get_pane_status(wp);
|
||||||
int pane_scrollbars = ctx->pane_scrollbars, sb_w = 0;
|
int pane_scrollbars = ctx->pane_scrollbars, sb_w = 0;
|
||||||
int sb_pos, sx = wp->sx, sy = wp->sy;
|
int sb_pos, sx = wp->sx, sy = wp->sy, left, right;
|
||||||
enum layout_type split_type;
|
enum layout_type split_type;
|
||||||
|
|
||||||
if (pane_scrollbars != 0)
|
if (pane_scrollbars != 0)
|
||||||
@@ -151,20 +151,19 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
|||||||
|
|
||||||
/* Floating pane borders. */
|
/* Floating pane borders. */
|
||||||
if (window_pane_is_floating(wp)) {
|
if (window_pane_is_floating(wp)) {
|
||||||
|
left = wp->xoff - 1;
|
||||||
|
right = wp->xoff + sx;
|
||||||
|
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||||
|
left -= sb_w;
|
||||||
|
else
|
||||||
|
right += sb_w;
|
||||||
if (py >= wp->yoff - 1 && py <= wp->yoff + sy) {
|
if (py >= wp->yoff - 1 && py <= wp->yoff + sy) {
|
||||||
if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
if (px == left)
|
||||||
if (px == wp->xoff - 1 - sb_w)
|
return (SCREEN_REDRAW_BORDER_LEFT);
|
||||||
return (SCREEN_REDRAW_BORDER_LEFT);
|
if (px == right)
|
||||||
if (px == wp->xoff + sx)
|
return (SCREEN_REDRAW_BORDER_RIGHT);
|
||||||
return (SCREEN_REDRAW_BORDER_RIGHT);
|
|
||||||
} else { /* PANE_SCROLLBARS_RIGHT or none. */
|
|
||||||
if (px == wp->xoff - 1)
|
|
||||||
return (SCREEN_REDRAW_BORDER_LEFT);
|
|
||||||
if (px == wp->xoff + sx + sb_w)
|
|
||||||
return (SCREEN_REDRAW_BORDER_RIGHT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (px >= wp->xoff && px <= wp->xoff + sx) {
|
if (px > left && px <= right) {
|
||||||
if (py == wp->yoff - 1)
|
if (py == wp->yoff - 1)
|
||||||
return (SCREEN_REDRAW_BORDER_TOP);
|
return (SCREEN_REDRAW_BORDER_TOP);
|
||||||
if (py == wp->yoff + sy)
|
if (py == wp->yoff + sy)
|
||||||
@@ -737,7 +736,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = tty_check_overlay_range(tty, x, yoff, width);
|
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)
|
if (ctx->statustop)
|
||||||
yoff += ctx->statuslines;
|
yoff += ctx->statuslines;
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
@@ -1128,205 +1127,6 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
|
|||||||
tty_draw_line(tty, s, 0, i, UINT_MAX, 0, y + i, NULL);
|
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. */
|
/* Draw one pane. */
|
||||||
static void
|
static void
|
||||||
@@ -1421,7 +1221,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
|
|
||||||
/* Get visible ranges of line before we draw it. */
|
/* Get visible ranges of line before we draw it. */
|
||||||
r = tty_check_overlay_range(tty, wx, wy, width);
|
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++) {
|
for (k = 0; k < r->used; k++) {
|
||||||
ri = &r->ranges[k];
|
ri = &r->ranges[k];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -1595,7 +1395,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
wy = sb_wy + j; /* window y coordinate */
|
wy = sb_wy + j; /* window y coordinate */
|
||||||
py = sb_tty_y + j; /* tty y coordinate */
|
py = sb_tty_y + j; /* tty y coordinate */
|
||||||
r = tty_check_overlay_range(tty, sb_x, wy, imax);
|
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++) {
|
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 */
|
||||||
@@ -1603,7 +1403,7 @@ screen_redraw_draw_scrollbar(struct screen_redraw_ctx *ctx,
|
|||||||
px >= sx || px < 0 ||
|
px >= sx || px < 0 ||
|
||||||
wy < yoff - 1 ||
|
wy < yoff - 1 ||
|
||||||
py >= sy || py < 0 ||
|
py >= sy || py < 0 ||
|
||||||
!screen_redraw_is_visible(r, wx))
|
!window_position_is_visible(r, wx))
|
||||||
continue;
|
continue;
|
||||||
tty_cursor(tty, px, py);
|
tty_cursor(tty, px, py);
|
||||||
if ((sb_pos == PANE_SCROLLBARS_LEFT &&
|
if ((sb_pos == PANE_SCROLLBARS_LEFT &&
|
||||||
|
|||||||
@@ -647,8 +647,8 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
|||||||
break;
|
break;
|
||||||
s->cx = cx;
|
s->cx = cx;
|
||||||
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
||||||
r = screen_redraw_get_visible_ranges(wp, xoff + s->cx,
|
r = window_visible_ranges(wp, xoff + s->cx, s->cy + yoff, nx,
|
||||||
s->cy + yoff, nx, NULL);
|
NULL);
|
||||||
for (xx = px; xx < px + nx; xx++) {
|
for (xx = px; xx < px + nx; xx++) {
|
||||||
gl = grid_get_line(gd, yy);
|
gl = grid_get_line(gd, yy);
|
||||||
sgl = grid_get_line(s->grid, s->cy);
|
sgl = grid_get_line(s->grid, s->cy);
|
||||||
@@ -660,7 +660,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
|||||||
break;
|
break;
|
||||||
grid_view_set_cell(s->grid, s->cx, s->cy, &gc);
|
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;
|
break;
|
||||||
ttyctx.cell = &gc;
|
ttyctx.cell = &gc;
|
||||||
ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC);
|
ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC);
|
||||||
@@ -1165,7 +1165,7 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
|||||||
if (s->mode & MODE_SYNC)
|
if (s->mode & MODE_SYNC)
|
||||||
return;
|
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++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -1853,8 +1853,8 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
|
|
||||||
/* First line (containing the cursor). */
|
/* First line (containing the cursor). */
|
||||||
if (s->cx <= sx - 1) {
|
if (s->cx <= sx - 1) {
|
||||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff + s->cx,
|
r = window_visible_ranges(ctx->wp, xoff + s->cx, yoff + s->cy,
|
||||||
yoff + s->cy, sx - s->cx, NULL);
|
sx - s->cx, NULL);
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -1867,8 +1867,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
/* Below cursor to bottom. */
|
/* Below cursor to bottom. */
|
||||||
for (y = s->cy + 1; y < sy; y++) {
|
for (y = s->cy + 1; y < sy; y++) {
|
||||||
screen_write_set_cursor(ctx, 0, y);
|
screen_write_set_cursor(ctx, 0, y);
|
||||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||||
sx, NULL);
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -1930,8 +1929,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
/* Top to above the cursor. */
|
/* Top to above the cursor. */
|
||||||
for (y = 0; y < s->cy; y++) {
|
for (y = 0; y < s->cy; y++) {
|
||||||
screen_write_set_cursor(ctx, 0, y);
|
screen_write_set_cursor(ctx, 0, y);
|
||||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||||
sx, NULL);
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -1943,8 +1941,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
|
|
||||||
/* Last line (containing the cursor). */
|
/* Last line (containing the cursor). */
|
||||||
screen_write_set_cursor(ctx, 0, s->cy);
|
screen_write_set_cursor(ctx, 0, s->cy);
|
||||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + ocy,
|
r = window_visible_ranges(ctx->wp, xoff, yoff + ocy, s->cx + 1, NULL);
|
||||||
s->cx + 1, NULL);
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -2005,8 +2002,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
/* Clear every line. */
|
/* Clear every line. */
|
||||||
for (y = 0; y < sy; y++) {
|
for (y = 0; y < sy; y++) {
|
||||||
screen_write_set_cursor(ctx, 0, y);
|
screen_write_set_cursor(ctx, 0, y);
|
||||||
r = screen_redraw_get_visible_ranges(ctx->wp, xoff, yoff + y,
|
r = window_visible_ranges(ctx->wp, xoff, yoff + y, sx, NULL);
|
||||||
sx, NULL);
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
@@ -2230,7 +2226,7 @@ screen_write_collect_flush_line(struct screen_write_ctx *ctx, u_int y)
|
|||||||
if (y + yoff >= wsy)
|
if (y + yoff >= wsy)
|
||||||
return (0);
|
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) {
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||||
log_debug("collect list: x=%u (last %u), y=%u, used=%u", ci->x,
|
log_debug("collect list: x=%u (last %u), y=%u, used=%u", ci->x,
|
||||||
last, y, ci->used);
|
last, y, ci->used);
|
||||||
@@ -2625,8 +2621,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
xoff = wp->xoff;
|
xoff = wp->xoff;
|
||||||
yoff = wp->yoff;
|
yoff = wp->yoff;
|
||||||
}
|
}
|
||||||
r = screen_redraw_get_visible_ranges(wp, xoff + s->cx, s->cy + yoff,
|
r = window_visible_ranges(wp, xoff + s->cx, s->cy + yoff, width, NULL);
|
||||||
width, NULL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move the cursor. If not wrapping, stick at the last character and
|
* Move the cursor. If not wrapping, stick at the last character and
|
||||||
@@ -2798,7 +2793,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
*/
|
*/
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
yoff = wp->yoff;
|
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++)
|
for (i = 0, vis = 0; i < r->used; i++)
|
||||||
vis += r->ranges[i].nx;
|
vis += r->ranges[i].nx;
|
||||||
if (vis < n) {
|
if (vis < n) {
|
||||||
|
|||||||
@@ -627,6 +627,9 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
|||||||
pane_status_line = wp->yoff + wp->sy;
|
pane_status_line = wp->yoff + wp->sy;
|
||||||
else
|
else
|
||||||
pane_status_line = -1; /* not used */
|
pane_status_line = -1; /* not used */
|
||||||
|
bdr_left = wp->xoff - 1;
|
||||||
|
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||||
|
bdr_left -= sb_pad + sb_w;
|
||||||
|
|
||||||
/* Check if point is within the pane or scrollbar. */
|
/* Check if point is within the pane or scrollbar. */
|
||||||
if (((pane_status != PANE_STATUS_OFF &&
|
if (((pane_status != PANE_STATUS_OFF &&
|
||||||
@@ -657,7 +660,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
|||||||
return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN);
|
return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN);
|
||||||
} else if (window_pane_is_floating(wp) &&
|
} else if (window_pane_is_floating(wp) &&
|
||||||
window_pane_get_pane_lines(wp) != PANE_LINES_NONE &&
|
window_pane_get_pane_lines(wp) != PANE_LINES_NONE &&
|
||||||
(px == wp->xoff - 1 ||
|
(px == bdr_left ||
|
||||||
py == wp->yoff - 1 ||
|
py == wp->yoff - 1 ||
|
||||||
py == wp->yoff + (int)wp->sy)) {
|
py == wp->yoff + (int)wp->sy)) {
|
||||||
/* Floating pane left, bottom or top border. */
|
/* Floating pane left, bottom or top border. */
|
||||||
@@ -675,11 +678,20 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
|||||||
if (window_pane_is_floating(fwp) &&
|
if (window_pane_is_floating(fwp) &&
|
||||||
window_pane_get_pane_lines(fwp) == PANE_LINES_NONE)
|
window_pane_get_pane_lines(fwp) == PANE_LINES_NONE)
|
||||||
continue;
|
continue;
|
||||||
|
if (window_pane_show_scrollbar(fwp, sb)) {
|
||||||
|
sb_w = fwp->scrollbar_style.width;
|
||||||
|
sb_pad = fwp->scrollbar_style.pad;
|
||||||
|
} else {
|
||||||
|
sb_w = 0;
|
||||||
|
sb_pad = 0;
|
||||||
|
}
|
||||||
bdr_top = fwp->yoff - 1;
|
bdr_top = fwp->yoff - 1;
|
||||||
bdr_bottom = fwp->yoff + fwp->sy;
|
bdr_bottom = fwp->yoff + fwp->sy;
|
||||||
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
bdr_left = fwp->xoff - 1;
|
||||||
|
if (sb_pos == PANE_SCROLLBARS_LEFT) {
|
||||||
|
bdr_left -= sb_pad + sb_w;
|
||||||
bdr_right = fwp->xoff + fwp->sx;
|
bdr_right = fwp->xoff + fwp->sx;
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -689,13 +701,11 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
|||||||
break;
|
break;
|
||||||
if (window_pane_is_floating(wp)) {
|
if (window_pane_is_floating(wp)) {
|
||||||
/* Floating pane, check left border. */
|
/* Floating pane, check left border. */
|
||||||
bdr_left = fwp->xoff - 1;
|
|
||||||
if (px == bdr_left)
|
if (px == bdr_left)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (px >= fwp->xoff - 1 &&
|
if (px >= bdr_left && px <= fwp->xoff + (int)fwp->sx) {
|
||||||
px <= fwp->xoff + (int)fwp->sx) {
|
|
||||||
bdr_bottom = fwp->yoff + fwp->sy;
|
bdr_bottom = fwp->yoff + fwp->sy;
|
||||||
if (py == bdr_bottom)
|
if (py == bdr_bottom)
|
||||||
break;
|
break;
|
||||||
@@ -1837,8 +1847,8 @@ server_client_reset_state(struct client *c)
|
|||||||
cx = wp->xoff + (int)s->cx - (int)ox;
|
cx = wp->xoff + (int)s->cx - (int)ox;
|
||||||
cy = wp->yoff + (int)s->cy - (int)oy;
|
cy = wp->yoff + (int)s->cy - (int)oy;
|
||||||
|
|
||||||
r = screen_redraw_get_visible_ranges(wp, cx, cy, 1, NULL);
|
r = window_visible_ranges(wp, cx, cy, 1, NULL);
|
||||||
if (!screen_redraw_is_visible(r, cx))
|
if (!window_position_is_visible(r, cx))
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
|
|
||||||
if (status_at_line(c) == 0)
|
if (status_at_line(c) == 0)
|
||||||
|
|||||||
2
tmux.1
2
tmux.1
@@ -3430,7 +3430,7 @@ which may be one of:
|
|||||||
.It Li "top-left-centre" Ta "Centre of top-left quadrant"
|
.It Li "top-left-centre" Ta "Centre of top-left quadrant"
|
||||||
.It Li "top-right-centre" Ta "Centre of top-right quadrant"
|
.It Li "top-right-centre" Ta "Centre of top-right quadrant"
|
||||||
.It Li "bottom-left-centre" Ta "Centre of bottom-left quadrant"
|
.It Li "bottom-left-centre" Ta "Centre of bottom-left quadrant"
|
||||||
.It Li "bottom-right-centre" Ta "Centre of botton-right quadrant"
|
.It Li "bottom-right-centre" Ta "Centre of bottom-right quadrant"
|
||||||
.It Li "front" Ta "Front of floating panes"
|
.It Li "front" Ta "Front of floating panes"
|
||||||
.It Li "back" Ta "Back of floating panes"
|
.It Li "back" Ta "Back of floating panes"
|
||||||
.It Li "forward" Ta "Forward one floating pane"
|
.It Li "forward" Ta "Forward one floating pane"
|
||||||
|
|||||||
8
tmux.h
8
tmux.h
@@ -3396,9 +3396,6 @@ void screen_write_alternateoff(struct screen_write_ctx *,
|
|||||||
/* screen-redraw.c */
|
/* screen-redraw.c */
|
||||||
void screen_redraw_screen(struct client *);
|
void screen_redraw_screen(struct client *);
|
||||||
void screen_redraw_pane(struct client *, struct window_pane *, int);
|
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 */
|
/* screen.c */
|
||||||
void screen_init(struct screen *, u_int, u_int, u_int);
|
void screen_init(struct screen *, u_int, u_int, u_int);
|
||||||
@@ -3547,6 +3544,11 @@ struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
|
|||||||
int window_pane_is_floating(struct window_pane *);
|
int window_pane_is_floating(struct window_pane *);
|
||||||
int window_pane_is_hidden(struct window_pane *);
|
int window_pane_is_hidden(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 */
|
/* layout.c */
|
||||||
u_int layout_count_cells(struct layout_cell *);
|
u_int layout_count_cells(struct layout_cell *);
|
||||||
struct layout_cell *layout_create_cell(struct layout_cell *);
|
struct layout_cell *layout_create_cell(struct layout_cell *);
|
||||||
|
|||||||
@@ -5403,8 +5403,12 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
|
|||||||
u_int maxx;
|
u_int maxx;
|
||||||
int allow_onemore;
|
int allow_onemore;
|
||||||
|
|
||||||
allow_onemore = (data->screen.sel != NULL && data->rectflag);
|
/*
|
||||||
if (cy < screen_size_y(s)) {
|
* Allow rectangle selection to extend past end of current line to
|
||||||
|
* behave the same as vi with virtualedit=block set.
|
||||||
|
*/
|
||||||
|
if (!data->rectflag && cy < screen_size_y(s)) {
|
||||||
|
allow_onemore = (data->screen.sel != NULL && data->rectflag);
|
||||||
py = screen_hsize(data->backing) + cy - data->oy;
|
py = screen_hsize(data->backing) + cy - data->oy;
|
||||||
maxx = window_copy_cursor_limit(wme, py, allow_onemore);
|
maxx = window_copy_cursor_limit(wme, py, allow_onemore);
|
||||||
if (cx > maxx)
|
if (cx > maxx)
|
||||||
|
|||||||
224
window-visible.c
Normal file
224
window-visible.c
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/* $OpenBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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