Merge branch 'master' into floating_panes

This commit is contained in:
Nicholas Marriott
2026-05-22 10:40:29 +01:00
4 changed files with 78 additions and 69 deletions

View File

@@ -185,7 +185,6 @@ popup_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
if (pd->c->flags & CLIENT_REDRAWOVERLAY)
return (0);
ttyctx->bigger = 0;
ttyctx->wox = 0;
ttyctx->woy = 0;
ttyctx->wsx = c->tty.sx;
@@ -208,6 +207,7 @@ popup_init_ctx_cb(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx)
struct popup_data *pd = ctx->arg;
memcpy(&ttyctx->defaults, &pd->defaults, sizeof ttyctx->defaults);
ttyctx->flags &= ~TTY_CTX_WINDOW_BIGGER;
ttyctx->palette = &pd->palette;
ttyctx->redraw_cb = popup_redraw_cb;
ttyctx->set_client_cb = popup_set_client_cb;

View File

@@ -134,7 +134,7 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
{
struct window_pane *wp = ttyctx->arg;
if (ttyctx->allow_invisible_panes) {
if (ttyctx->flags & TTY_CTX_INVISIBLE_PANES) {
if (session_has(c->session, wp->window))
return (1);
return (0);
@@ -161,8 +161,11 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
return (-1);
}
ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy,
&ttyctx->wsx, &ttyctx->wsy);
if (tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy, &ttyctx->wsx,
&ttyctx->wsy))
ttyctx->flags |= TTY_CTX_WINDOW_BIGGER;
else
ttyctx->flags &= ~TTY_CTX_WINDOW_BIGGER;
ttyctx->xoff = ttyctx->rxoff = wp->xoff;
ttyctx->yoff = ttyctx->ryoff = wp->yoff;
@@ -217,13 +220,14 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
* move the cursor); for other panes, always use it, since the
* cursor will have to move.
*/
if (ctx->wp != NULL) {
if (ctx->wp != ctx->wp->window->active)
ttyctx->num = 1;
else
ttyctx->num = sync;
} else
ttyctx->num = 0x10|sync;
if (ctx->wp != NULL && ctx->wp != ctx->wp->window->active)
ttyctx->flags |= TTY_CTX_SYNC;
else {
if (ctx->wp == NULL)
ttyctx->flags |= TTY_CTX_OVERLAY_SYNC;
if (sync)
ttyctx->flags |= TTY_CTX_SYNC;
}
tty_write(tty_cmd_syncstart, ttyctx);
ctx->flags |= SCREEN_WRITE_SYNC;
}
@@ -576,6 +580,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
struct window_pane *wp = ctx->wp;
struct tty_ctx ttyctx;
struct grid *gd = src->grid;
struct grid_line *gl, *sgl;
struct grid_cell gc;
u_int xx, yy, cx = s->cx, cy = s->cy;
int yoff = 0;
@@ -595,21 +600,20 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
r = screen_redraw_get_visible_ranges(wp, px, s->cy + yoff, nx,
NULL);
for (xx = px; xx < px + nx; xx++) {
if (xx >= grid_get_line(gd, yy)->cellsize &&
s->cx >= grid_get_line(ctx->s->grid,
s->cy)->cellsize)
gl = grid_get_line(gd, yy);
sgl = grid_get_line(ctx->s->grid, s->cy);
if (xx >= gl->cellsize && s->cx >= sgl->cellsize)
break;
grid_get_cell(gd, xx, yy, &gc);
if (xx + gc.data.width > px + nx)
break;
grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc);
if (wp != NULL) {
if (!screen_redraw_is_visible(r, px))
break;
ttyctx.cell = &gc;
ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC);
tty_write(tty_cmd_cell, &ttyctx);
ttyctx.ocx++;
}
s->cx++;
}
s->cy++;
@@ -2469,7 +2473,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
} else
memcpy(&tmp_gc, gc, sizeof tmp_gc);
ttyctx.cell = &tmp_gc;
ttyctx.num = redraw ? 2 : 0;
if (redraw)
ttyctx.flags |= TTY_CTX_CELL_DRAW_LINE;
for (i=0, vis=0; i < r->used; i++) vis += r->ranges[i].nx;
if (vis < width) {
/* Wide character or tab partly obscured. Write
@@ -2619,7 +2624,8 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
screen_write_set_cursor(ctx, cx - n, cy);
screen_write_initctx(ctx, &ttyctx, 0);
ttyctx.cell = &last;
ttyctx.num = force_wide; /* reset cached cursor position */
if (force_wide)
ttyctx.flags |= TTY_CTX_CELL_INVALIDATE;
tty_write(tty_cmd_cell, &ttyctx);
screen_write_set_cursor(ctx, cx, cy);
@@ -2721,9 +2727,10 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0);
if (allow_invisible_panes)
ttyctx.flags |= TTY_CTX_INVISIBLE_PANES;
ttyctx.ptr = str;
ttyctx.num = len;
ttyctx.allow_invisible_panes = allow_invisible_panes;
tty_write(tty_cmd_rawstring, &ttyctx);
}

17
tmux.h
View File

@@ -1743,19 +1743,19 @@ struct tty_ctx {
void *arg;
const struct grid_cell *cell;
int wrapped;
int flags;
#define TTY_CTX_WRAPPED 0x1
#define TTY_CTX_INVISIBLE_PANES 0x2
#define TTY_CTX_WINDOW_BIGGER 0x4
#define TTY_CTX_SYNC 0x8
#define TTY_CTX_OVERLAY_SYNC 0x10
#define TTY_CTX_CELL_DRAW_LINE 0x20
#define TTY_CTX_CELL_INVALIDATE 0x40
u_int num;
void *ptr;
void *ptr2;
/*
* Whether this command should be sent even when the pane is not
* visible (used for a passthrough sequence when allow-passthrough is
* "all").
*/
int allow_invisible_panes;
/*
* Cursor and region position before the screen was updated - this is
* where the command should be applied; the values in the screen have
@@ -1783,7 +1783,6 @@ struct tty_ctx {
struct colour_palette *palette;
/* Containing region (usually window) offset and size. */
int bigger;
u_int wox;
u_int woy;
u_int wsx;

45
tty.c
View File

@@ -1118,7 +1118,7 @@ tty_is_visible(__unused struct tty *tty, const struct tty_ctx *ctx, u_int px,
{
u_int xoff = ctx->rxoff + px, yoff = ctx->ryoff + py;
if (!ctx->bigger)
if (~ctx->flags & TTY_CTX_WINDOW_BIGGER)
return (1);
if (xoff + nx <= ctx->wox || xoff >= ctx->wox + ctx->wsx ||
@@ -1429,9 +1429,9 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py)
struct visible_range *ri;
u_int nx = ctx->sx, i, px, x, rx, ry;
log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger);
log_debug("%s: %s %u", __func__, tty->client->name, py);
if (!ctx->bigger) {
if (~ctx->flags & TTY_CTX_WINDOW_BIGGER) {
if (wp) {
if (ctx->obscured) {
/*
@@ -1644,7 +1644,7 @@ tty_client_ready(const struct tty_ctx *ctx, struct client *c)
* If invisible panes are allowed (used for passthrough), don't care if
* redrawing or frozen.
*/
if (ctx->allow_invisible_panes)
if (ctx->flags & TTY_CTX_INVISIBLE_PANES)
return (1);
if (c->flags & CLIENT_REDRAWWINDOW)
@@ -1693,7 +1693,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct client *c = tty->client;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
(!tty_term_has(tty->term, TTYC_ICH) &&
@@ -1717,7 +1717,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct client *c = tty->client;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
@@ -1750,7 +1750,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
struct client *c = tty->client;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -1779,7 +1779,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
struct client *c = tty->client;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -1840,7 +1840,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orupper)
return;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -1874,7 +1874,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orlower)
return;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -1915,7 +1915,7 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
struct client *c = tty->client;
u_int i;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -1955,7 +1955,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
u_int i;
struct client *c = tty->client;
if (ctx->bigger ||
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
@@ -2058,7 +2058,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i, j;
if (ctx->bigger) {
if (ctx->flags & TTY_CTX_WINDOW_BIGGER) {
ctx->redraw_cb(ctx);
return;
}
@@ -2090,7 +2090,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
(gcp->data.width == 1 && !tty_check_overlay(tty, px, py)))
return;
if (ctx->num == 2) {
if (ctx->flags & TTY_CTX_CELL_DRAW_LINE) {
tty_draw_line(tty, s, 0, s->cy, screen_size_x(s),
ctx->xoff - ctx->wox, py, &ctx->defaults, ctx->palette);
return;
@@ -2120,7 +2120,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette,
ctx->s->hyperlinks);
if (ctx->num == 1)
if (ctx->flags & TTY_CTX_CELL_INVALIDATE)
tty_invalidate(tty);
}
@@ -2135,10 +2135,10 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1))
return;
if (ctx->bigger &&
if ((ctx->flags & TTY_CTX_WINDOW_BIGGER) &&
(ctx->xoff + ctx->ocx < ctx->wox ||
ctx->xoff + ctx->ocx + ctx->num > ctx->wox + ctx->wsx)) {
if (!ctx->wrapped ||
if ((~ctx->flags & TTY_CTX_WRAPPED) ||
!tty_full_width(tty, ctx) ||
(tty->term->flags & TERM_NOAM) ||
ctx->xoff + ctx->ocx != 0 ||
@@ -2401,18 +2401,21 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx)
{
if (ctx->num == 0x11) {
struct client *c = tty->client;
if ((ctx->flags & TTY_CTX_OVERLAY_SYNC) &&
(ctx->flags & TTY_CTX_SYNC)) {
/*
* This is an overlay and a command that moves the cursor so
* start synchronized updates.
*/
tty_sync_start(tty);
} else if (~ctx->num & 0x10) {
} else if (~ctx->flags & TTY_CTX_OVERLAY_SYNC) {
/*
* This is a pane. If there is an overlay, always start;
* otherwise, only if requested.
*/
if (ctx->num || tty->client->overlay_draw != NULL)
if ((ctx->flags & TTY_CTX_SYNC) || c->overlay_draw != NULL)
tty_sync_start(tty);
}
}
@@ -2593,7 +2596,7 @@ static void
tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx,
u_int cx, u_int cy)
{
if (!ctx->wrapped ||
if ((~ctx->flags & TTY_CTX_WRAPPED) ||
!tty_full_width(tty, ctx) ||
(tty->term->flags & TERM_NOAM) ||
ctx->xoff + cx != 0 ||