mirror of
https://github.com/tmux/tmux.git
synced 2026-06-22 06:46:57 +00:00
Clip floating panes at window edge.
This commit is contained in:
110
screen-redraw.c
110
screen-redraw.c
@@ -337,13 +337,32 @@ redraw_window_to_scene(struct redraw_build_ctx *bctx, int wx, int wy,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert pane position to scene position. Return 0 if outside the scene. */
|
/*
|
||||||
|
* Convert pane position to scene position. Return 0 if outside the scene. A
|
||||||
|
* floating pane is clipped to the window edge.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
redraw_pane_to_scene(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
redraw_pane_to_scene(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
||||||
int px, int py, u_int *x, u_int *y)
|
int px, int py, u_int *x, u_int *y)
|
||||||
{
|
{
|
||||||
int wx = wp->xoff + px, wy = wp->yoff + py;
|
int wx = wp->xoff + px, wy = wp->yoff + py;
|
||||||
|
int left, right, top, bottom;
|
||||||
|
|
||||||
|
if (window_pane_is_floating(wp)) {
|
||||||
|
left = wp->xoff - 1;
|
||||||
|
right = wp->xoff + wp->sx;
|
||||||
|
top = wp->yoff - 1;
|
||||||
|
bottom = wp->yoff + wp->sy;
|
||||||
|
|
||||||
|
if (left < 0 && wx <= 0)
|
||||||
|
return (0);
|
||||||
|
if (right > (int)bctx->w->sx && wx >= (int)bctx->w->sx)
|
||||||
|
return (0);
|
||||||
|
if (top < 0 && wy <= 0)
|
||||||
|
return (0);
|
||||||
|
if (bottom > (int)bctx->w->sy && wy >= (int)bctx->w->sy)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
return (redraw_window_to_scene(bctx, wx, wy, x, y));
|
return (redraw_window_to_scene(bctx, wx, wy, x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,9 +481,28 @@ redraw_mark_pane_scrollbar(struct redraw_build_ctx *bctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return if span data belongs to pane, that is: is the cell adjacent to this
|
||||||
|
* pane?
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
redraw_data_has_pane(struct redraw_span_data *data, struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (data->b.top_wp == wp)
|
||||||
|
return (1);
|
||||||
|
if (data->b.bottom_wp == wp)
|
||||||
|
return (1);
|
||||||
|
if (data->b.left_wp == wp)
|
||||||
|
return (1);
|
||||||
|
if (data->b.right_wp == wp)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark one border cell. If a non-border cell is marked as a border, replace
|
* Mark one border cell. If a non-border cell is marked as a border, replace
|
||||||
* it. If it is already a border, merge the border mask and pane ownership.
|
* it. If it is already a border and this is not a floating pane, merge the
|
||||||
|
* border mask and pane ownership.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
redraw_mark_border_cell(struct redraw_build_ctx *bctx, int wx, int wy,
|
redraw_mark_border_cell(struct redraw_build_ctx *bctx, int wx, int wy,
|
||||||
@@ -474,17 +512,25 @@ redraw_mark_border_cell(struct redraw_build_ctx *bctx, int wx, int wy,
|
|||||||
struct redraw_build_cell *bc;
|
struct redraw_build_cell *bc;
|
||||||
enum pane_lines pane_lines;
|
enum pane_lines pane_lines;
|
||||||
u_int x, y;
|
u_int x, y;
|
||||||
|
int reset = 0;
|
||||||
|
|
||||||
if (!redraw_window_to_scene(bctx, wx, wy, &x, &y))
|
if (!redraw_window_to_scene(bctx, wx, wy, &x, &y))
|
||||||
return;
|
return;
|
||||||
bc = redraw_get_build_cell(bctx, x, y);
|
bc = redraw_get_build_cell(bctx, x, y);
|
||||||
|
|
||||||
if (bc->data.type != REDRAW_SPAN_BORDER) {
|
if (bc->data.type == REDRAW_SPAN_BORDER) {
|
||||||
if (bc->data.type != REDRAW_SPAN_EMPTY && !floating)
|
if (floating && !redraw_data_has_pane(&bc->data, wp))
|
||||||
|
reset = 1;
|
||||||
|
} else {
|
||||||
|
if (!floating && bc->data.type != REDRAW_SPAN_EMPTY)
|
||||||
return;
|
return;
|
||||||
|
reset = 1;
|
||||||
|
}
|
||||||
|
if (reset) {
|
||||||
memset(bc, 0, sizeof *bc);
|
memset(bc, 0, sizeof *bc);
|
||||||
bc->data.type = REDRAW_SPAN_BORDER;
|
bc->data.type = REDRAW_SPAN_BORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
pane_lines = window_pane_get_pane_lines(wp);
|
pane_lines = window_pane_get_pane_lines(wp);
|
||||||
if (top_owner) {
|
if (top_owner) {
|
||||||
bc->data.b.top_wp = wp;
|
bc->data.b.top_wp = wp;
|
||||||
@@ -602,7 +648,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
{
|
{
|
||||||
enum pane_lines pane_lines = window_pane_get_pane_lines(wp);
|
enum pane_lines pane_lines = window_pane_get_pane_lines(wp);
|
||||||
int pane_status, left, right, top, bottom, wx, wy;
|
int pane_status, left, right, top, bottom, wx, wy;
|
||||||
int draw_top, draw_bottom, draw_left, draw_right, mask = 0;
|
int mark_top, mark_bottom, mark_left, mark_right, mask = 0;
|
||||||
int floating = window_pane_is_floating(wp);
|
int floating = window_pane_is_floating(wp);
|
||||||
|
|
||||||
if (floating && pane_lines == PANE_LINES_NONE)
|
if (floating && pane_lines == PANE_LINES_NONE)
|
||||||
@@ -610,7 +656,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
pane_status = window_pane_get_pane_status(wp);
|
pane_status = window_pane_get_pane_status(wp);
|
||||||
|
|
||||||
left = wp->xoff - 1;
|
left = wp->xoff - 1;
|
||||||
right = wp->xoff + (int)wp->sx;
|
right = wp->xoff + wp->sx;
|
||||||
if (sb_w != 0) {
|
if (sb_w != 0) {
|
||||||
if (sb_left)
|
if (sb_left)
|
||||||
left -= sb_w;
|
left -= sb_w;
|
||||||
@@ -618,21 +664,30 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
right += sb_w;
|
right += sb_w;
|
||||||
}
|
}
|
||||||
top = wp->yoff - 1;
|
top = wp->yoff - 1;
|
||||||
bottom = wp->yoff + (int)wp->sy;
|
bottom = wp->yoff + wp->sy;
|
||||||
|
|
||||||
draw_left = (left >= 0);
|
mark_left = (left >= 0);
|
||||||
draw_right = (right <= (int)bctx->w->sx);
|
mark_right = (right <= (int)bctx->w->sx);
|
||||||
draw_top = (top >= 0);
|
mark_top = (top >= 0);
|
||||||
draw_bottom = (bottom <= (int)bctx->w->sy);
|
mark_bottom = (bottom <= (int)bctx->w->sy);
|
||||||
|
|
||||||
if (!floating) {
|
if (floating) {
|
||||||
|
if (left < 0)
|
||||||
|
left = 1;
|
||||||
|
if (right > (int)bctx->w->sx)
|
||||||
|
right = (int)bctx->w->sx - 1;
|
||||||
|
if (top < 0)
|
||||||
|
top = 1;
|
||||||
|
if (bottom > (int)bctx->w->sy)
|
||||||
|
bottom = (int)bctx->w->sy - 1;
|
||||||
|
} else {
|
||||||
if (pane_status == PANE_STATUS_TOP)
|
if (pane_status == PANE_STATUS_TOP)
|
||||||
draw_bottom = 0;
|
mark_bottom = 0;
|
||||||
else if (pane_status == PANE_STATUS_BOTTOM)
|
else if (pane_status == PANE_STATUS_BOTTOM)
|
||||||
draw_top = 0;
|
mark_top = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_top) {
|
if (mark_top) {
|
||||||
for (wx = left; wx <= right; wx++) {
|
for (wx = left; wx <= right; wx++) {
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (wx > left)
|
if (wx > left)
|
||||||
@@ -643,7 +698,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
floating);
|
floating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (draw_bottom) {
|
if (mark_bottom) {
|
||||||
for (wx = left; wx <= right; wx++) {
|
for (wx = left; wx <= right; wx++) {
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (wx > left)
|
if (wx > left)
|
||||||
@@ -654,7 +709,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
mask, floating);
|
mask, floating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (draw_left) {
|
if (mark_left) {
|
||||||
for (wy = top; wy <= bottom; wy++) {
|
for (wy = top; wy <= bottom; wy++) {
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (wy > top)
|
if (wy > top)
|
||||||
@@ -665,7 +720,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
|||||||
floating);
|
floating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (draw_right) {
|
if (mark_right) {
|
||||||
for (wy = top; wy <= bottom; wy++) {
|
for (wy = top; wy <= bottom; wy++) {
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (wy > top)
|
if (wy > top)
|
||||||
@@ -971,21 +1026,6 @@ redraw_get_scene(struct client *c)
|
|||||||
return (scene);
|
return (scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this span adjacent to this pane? */
|
|
||||||
static int
|
|
||||||
redraw_span_has_pane(struct redraw_span *span, struct window_pane *wp)
|
|
||||||
{
|
|
||||||
if (span->data.b.top_wp == wp)
|
|
||||||
return (1);
|
|
||||||
if (span->data.b.bottom_wp == wp)
|
|
||||||
return (1);
|
|
||||||
if (span->data.b.left_wp == wp)
|
|
||||||
return (1);
|
|
||||||
if (span->data.b.right_wp == wp)
|
|
||||||
return (1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw a pane span. */
|
/* Draw a pane span. */
|
||||||
static void
|
static void
|
||||||
redraw_draw_pane_span(struct redraw_draw_ctx *dctx,
|
redraw_draw_pane_span(struct redraw_draw_ctx *dctx,
|
||||||
@@ -1047,7 +1087,7 @@ redraw_get_pane_for_border_style(struct redraw_draw_ctx *dctx,
|
|||||||
|
|
||||||
if (span->data.b.style_wp != NULL)
|
if (span->data.b.style_wp != NULL)
|
||||||
return (span->data.b.style_wp);
|
return (span->data.b.style_wp);
|
||||||
if (active != NULL && redraw_span_has_pane(span, active))
|
if (active != NULL && redraw_data_has_pane(&span->data, active))
|
||||||
return (active);
|
return (active);
|
||||||
|
|
||||||
if (span->data.b.top_wp != NULL)
|
if (span->data.b.top_wp != NULL)
|
||||||
@@ -1123,7 +1163,7 @@ redraw_draw_border_span(struct redraw_draw_ctx *dctx,
|
|||||||
|
|
||||||
if (span->data.type == REDRAW_SPAN_BORDER &&
|
if (span->data.type == REDRAW_SPAN_BORDER &&
|
||||||
dctx->marked != NULL &&
|
dctx->marked != NULL &&
|
||||||
redraw_span_has_pane(span, dctx->marked))
|
redraw_data_has_pane(&span->data, dctx->marked))
|
||||||
gc.attr ^= GRID_ATTR_REVERSE;
|
gc.attr ^= GRID_ATTR_REVERSE;
|
||||||
redraw_draw_border_arrow(dctx, span, &gc);
|
redraw_draw_border_arrow(dctx, span, &gc);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user