Merge branch 'floating_panes' into floating_panes_staging

This commit is contained in:
Nicholas Marriott
2026-06-01 08:45:28 +01:00
3 changed files with 131 additions and 77 deletions

View File

@@ -55,6 +55,27 @@ cmd_display_panes_args_parse(__unused struct args *args, __unused u_int idx,
return (ARGS_PARSE_COMMANDS_OR_STRING); return (ARGS_PARSE_COMMANDS_OR_STRING);
} }
static void
cmd_display_panes_put(struct screen_redraw_ctx *ctx,
struct window_pane *wp, u_int cx, u_int cy, const char *buf, size_t len)
{
struct client *c = ctx->c;
struct tty *tty = &c->tty;
struct visible_ranges *r;
struct visible_range *ri;
u_int i, j;
r = screen_redraw_get_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++) {
tty_cursor(tty, j - ctx->ox, cy);
tty_putn(tty, &buf[j - ri->px], 1, 1);
}
}
}
static void static void
cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
struct window_pane *wp) struct window_pane *wp)
@@ -66,6 +87,7 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
struct window *w = wp->window; struct window *w = wp->window;
struct grid_cell fgc, bgc; struct grid_cell fgc, bgc;
u_int pane, idx, px, py, i, j, xoff, yoff, sx, sy; u_int pane, idx, px, py, i, j, xoff, yoff, sx, sy;
u_int cx, cy;
int colour, active_colour; int colour, active_colour;
char buf[16], lbuf[16], rbuf[16], *ptr; char buf[16], lbuf[16], rbuf[16], *ptr;
size_t len, llen, rlen; size_t len, llen, rlen;
@@ -147,13 +169,17 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL); tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL);
if (sx >= len + llen + 1) { if (sx >= len + llen + 1) {
len += llen + 1; len += llen + 1;
tty_cursor(tty, xoff + px - len / 2, yoff + py); cx = xoff + px - len / 2;
tty_putn(tty, buf, len, len); cy = yoff + py;
tty_putn(tty, " ", 1, 1); cmd_display_panes_put(ctx, wp, cx, cy, buf, len);
tty_putn(tty, lbuf, llen, llen); cx += len;
cmd_display_panes_put(ctx, wp, cx, cy, " ", 1);
cx++;
cmd_display_panes_put(ctx, wp, cx, cy, lbuf, llen);
} else { } else {
tty_cursor(tty, xoff + px - len / 2, yoff + py); cx = xoff + px - len / 2;
tty_putn(tty, buf, len, len); cy = yoff + py;
cmd_display_panes_put(ctx, wp, cx, cy, buf, len);
} }
goto out; goto out;
} }
@@ -169,9 +195,11 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
for (j = 0; j < 5; j++) { for (j = 0; j < 5; j++) {
for (i = px; i < px + 5; i++) { for (i = px; i < px + 5; i++) {
tty_cursor(tty, xoff + i, yoff + py + j); if (!window_clock_table[idx][j][i - px])
if (window_clock_table[idx][j][i - px]) continue;
tty_putc(tty, ' '); cx = xoff + i;
cy = yoff + py + j;
cmd_display_panes_put(ctx, wp, cx, cy, " ", 1);
} }
} }
px += 6; px += 6;
@@ -181,13 +209,14 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
goto out; goto out;
tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL); tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL);
if (rlen != 0 && sx >= rlen) { if (rlen != 0 && sx >= rlen) {
tty_cursor(tty, xoff + sx - rlen, yoff); cx = xoff + sx - rlen;
tty_putn(tty, rbuf, rlen, rlen); cy = yoff;
cmd_display_panes_put(ctx, wp, cx, cy, rbuf, rlen);
} }
if (llen != 0) { if (llen != 0) {
tty_cursor(tty, xoff + sx / 2 + len * 3 - llen - 1, cx = xoff + sx / 2 + len * 3 - llen - 1;
yoff + py + 5); cy = yoff + py + 5;
tty_putn(tty, lbuf, llen, llen); cmd_display_panes_put(ctx, wp, cx, cy, lbuf, llen);
} }
out: out:

View File

@@ -242,6 +242,34 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
return (SCREEN_REDRAW_OUTSIDE); return (SCREEN_REDRAW_OUTSIDE);
} }
/* Check a single cell position. */
static int
screen_redraw_cell_border1(struct screen_redraw_ctx *ctx, int sb_pos, int sb_w,
struct window_pane *wp, int px, int py)
{
if (sb_pos == PANE_SCROLLBARS_LEFT) {
if ((px < wp->xoff - 1 - sb_w ||
px > wp->xoff + (int)wp->sx) &&
(py < wp->yoff - 1 ||
py > wp->yoff + (int)wp->sy))
return (-1);
} else { /* PANE_SCROLLBARS_RIGHT or off. */
if ((px < wp->xoff - 1 ||
px > wp->xoff + (int)wp->sx + sb_w) &&
(py < wp->yoff - 1 ||
py > wp->yoff + (int)wp->sy))
return (-1);
}
switch (screen_redraw_pane_border(ctx, wp, px, py)) {
case SCREEN_REDRAW_INSIDE:
return (0);
case SCREEN_REDRAW_OUTSIDE:
return (-1);
default:
return (1);
}
}
/* Check if a cell is on a border. */ /* Check if a cell is on a border. */
static int static int
screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
@@ -250,7 +278,7 @@ screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
struct client *c = ctx->c; struct client *c = ctx->c;
struct window *w = c->session->curw->window; struct window *w = c->session->curw->window;
struct window_pane *wp2; struct window_pane *wp2;
int sx = w->sx, sy = w->sy, sb_w, sb_pos, floating; int sx = w->sx, sy = w->sy, sb_w, sb_pos, n;
if (ctx->pane_scrollbars != 0) if (ctx->pane_scrollbars != 0)
sb_pos = ctx->pane_scrollbars_pos; sb_pos = ctx->pane_scrollbars_pos;
@@ -258,57 +286,34 @@ screen_redraw_cell_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
sb_pos = 0; sb_pos = 0;
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad; sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;
/* For floating panes, only check the pane itself. */
if (wp->flags & PANE_FLOATING) {
n = screen_redraw_cell_border1(ctx, sb_pos, sb_w, wp, px, py);
if (n == -1)
return (0);
return (n);
}
/* Outside the window or on the window border? */
if (ctx->pane_status == PANE_STATUS_BOTTOM) if (ctx->pane_status == PANE_STATUS_BOTTOM)
sy--; sy--;
if (px > sx || py > sy)
floating = (wp->flags & PANE_FLOATING); return (0);
if (!floating) { if (px == sx || py == sy)
/* Outside the window? */ return (1);
if (px > sx || py > sy)
return (0);
/* On the window border? */
if (px == sx || py == sy)
return (1);
}
/* /*
* If checking a cell from a tiled pane, ignore floating panes because * If checking a cell from a tiled pane, ignore floating panes because
* tqo side-by-side or top-bottom panes share a border which is used to * two side-by-side or top-bottom panes share a border which is used to
* do split colouring. Essentially, treat all tiled panes as being in a * do split colouring. Essentially, treat all tiled panes as being in a
* single z-index. * single z-index.
*
* If checking a cell from a floating pane, only check cells from this
* floating pane, again, essentially only this z-index.
*/ */
/* Check all the panes. */
TAILQ_FOREACH(wp2, &w->z_index, zentry) { TAILQ_FOREACH(wp2, &w->z_index, zentry) {
if (!window_pane_visible(wp2) || if (!window_pane_visible(wp2) || wp2->flags & PANE_FLOATING)
(!floating && (wp2->flags & PANE_FLOATING)) ||
(floating && wp2 != wp))
continue; continue;
if (sb_pos == PANE_SCROLLBARS_LEFT) { n = screen_redraw_cell_border1(ctx, sb_pos, sb_w, wp2, px, py);
if ((px < wp2->xoff - 1 - sb_w || if (n != -1)
px > wp2->xoff + (int)wp2->sx) && return (n);
(py < wp2->yoff - 1 ||
py > wp2->yoff + (int)wp2->sy))
continue;
} else { /* PANE_SCROLLBARS_RIGHT or off. */
if ((px < wp2->xoff - 1 ||
px > wp2->xoff + (int)wp2->sx + sb_w) &&
(py < wp2->yoff - 1 ||
py > wp2->yoff + (int)wp2->sy))
continue;
}
switch (screen_redraw_pane_border(ctx, wp2, px, py)) {
case SCREEN_REDRAW_INSIDE:
return (0);
case SCREEN_REDRAW_OUTSIDE:
break;
default:
return (1);
}
} }
return (0); return (0);
@@ -440,7 +445,7 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, int px, int py,
if (px > sx || py > sy) if (px > sx || py > sy)
return (CELL_OUTSIDE); return (CELL_OUTSIDE);
/* Find pane higest in z-index at this point. */ /* Find pane highest 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)) { if (wp->flags & PANE_FLOATING && (px >= sx || py >= sy)) {
/* Clip floating panes to window. */ /* Clip floating panes to window. */
@@ -479,9 +484,10 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, int px, int py,
*/ */
if (~wp->flags & PANE_FLOATING) if (~wp->flags & PANE_FLOATING)
tiled_only = 1; tiled_only = 1;
do { /* Loop until back to wp == start.*/ do { /* loop until back to wp == start */
if (!window_pane_visible(wp) || if (!window_pane_visible(wp))
(tiled_only && (wp->flags & PANE_FLOATING))) goto next;
if (tiled_only && (wp->flags & PANE_FLOATING))
goto next; goto next;
*wpp = wp; *wpp = wp;
@@ -492,7 +498,7 @@ screen_redraw_check_cell(struct screen_redraw_ctx *ctx, int px, int py,
(py < wp->yoff - 1 || (py < wp->yoff - 1 ||
py > wp->yoff + (int)wp->sy)) py > wp->yoff + (int)wp->sy))
goto next; goto next;
} else { /* PANE_SCROLLBARS_RIGHT or none. */ } else { /* PANE_SCROLLBARS_RIGHT or none */
if ((px < wp->xoff - 1 || if ((px < wp->xoff - 1 ||
px > wp->xoff + (int)wp->sx + sb_w) && px > wp->xoff + (int)wp->sx + sb_w) &&
(py < wp->yoff - 1 || (py < wp->yoff - 1 ||
@@ -568,7 +574,7 @@ screen_redraw_check_is(struct screen_redraw_ctx *ctx, int px, int py,
enum screen_redraw_border_type border; enum screen_redraw_border_type border;
if (wp == NULL) if (wp == NULL)
return (0); /* No active pane. */ return (0); /* no active pane */
border = screen_redraw_pane_border(ctx, wp, px, py); border = screen_redraw_pane_border(ctx, wp, px, py);
if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE) if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE)
return (1); return (1);
@@ -914,6 +920,13 @@ screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, int i,
if (i != wp->xoff + 1 && j != wp->yoff + 1) if (i != wp->xoff + 1 && j != wp->yoff + 1)
return; return;
if (wp != active) {
if (active->flags & PANE_FLOATING)
return;
if (wp->flags & PANE_FLOATING)
return;
}
value = options_get_number(oo, "pane-border-indicators"); value = options_get_number(oo, "pane-border-indicators");
if (value != PANE_BORDER_ARROWS && value != PANE_BORDER_BOTH) if (value != PANE_BORDER_ARROWS && value != PANE_BORDER_BOTH)
return; return;
@@ -1131,17 +1144,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
u_int lb, rb, tb, bb; u_int lb, rb, tb, bb;
u_int i, s; u_int i, s;
if (px + width <= 0 || py < 0) { if (px + width <= 0 || py < 0)
if (r == NULL) { goto empty;
if (sr.ranges == NULL)
sr.ranges = xcalloc(1, sizeof *sr.ranges);
sr.size = 1;
sr.used = 0;
return (&sr);
}
r->used = 0;
return (r);
}
if (px < 0) { if (px < 0) {
px = 0; px = 0;
width += px; width += px;
@@ -1160,6 +1164,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
} }
w = base_wp->window; w = base_wp->window;
if ((u_int)py >= w->sy)
goto empty;
if (px + width > w->sx) if (px + width > w->sx)
width = w->sx - px; width = w->sx - px;
@@ -1271,6 +1277,17 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
} }
} }
return (r); 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. */
@@ -1300,7 +1317,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
* tty_x = window_x - ctx->ox * tty_x = window_x - ctx->ox
* *
* window <-> tty (y-axis): * window <-> tty (y-axis):
* woy = (ctx->statustop) ? ctx->statuslines : 0 * woy = ctx->statustop ? ctx->statuslines : 0
* window_y = tty_y + ctx->oy - woy * window_y = tty_y + ctx->oy - woy
* tty_y = woy + window_y - ctx->oy * tty_y = woy + window_y - ctx->oy
* *

View File

@@ -2137,7 +2137,7 @@ window_pane_floating_geometry(struct window *w, __unused struct window_pane *wp,
u_int *out_x, u_int *out_y, u_int *out_sx, u_int *out_sy, u_int *out_x, u_int *out_y, u_int *out_sx, u_int *out_sy,
struct cmdq_item *item, struct args *args, char **cause) struct cmdq_item *item, struct args *args, char **cause)
{ {
u_int x, y, sx = w->sx / 2, sy = w->sy / 2; u_int x, y, sx = w->sx / 2, sy = w->sy / 4;
if (args_has(args, 'x')) { if (args_has(args, 'x')) {
sx = args_percentage_and_expand(args, 'x', 0, USHRT_MAX, w->sx, sx = args_percentage_and_expand(args, 'x', 0, USHRT_MAX, w->sx,
@@ -2162,8 +2162,12 @@ window_pane_floating_geometry(struct window *w, __unused struct window_pane *wp,
x = 4; x = 4;
else { else {
x = w->last_new_pane_x + 4; x = w->last_new_pane_x + 4;
if (w->last_new_pane_x > w->sx) if (x + sx >= w->sx) {
w->last_new_pane_x = 0;
w->last_new_pane_y = 0;
x = 4; x = 4;
y = 2;
}
} }
w->last_new_pane_x = x; w->last_new_pane_x = x;
} }
@@ -2177,8 +2181,12 @@ window_pane_floating_geometry(struct window *w, __unused struct window_pane *wp,
y = 2; y = 2;
else { else {
y = w->last_new_pane_y + 2; y = w->last_new_pane_y + 2;
if (w->last_new_pane_y > w->sy) if (y + sy >= w->sy) {
w->last_new_pane_x = 0;
w->last_new_pane_y = 0;
x = 4;
y = 2; y = 2;
}
} }
w->last_new_pane_y = y; w->last_new_pane_y = y;
} }