diff --git a/popup.c b/popup.c index 2092e185..cb8dbf06 100644 --- a/popup.c +++ b/popup.c @@ -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; diff --git a/screen-write.c b/screen-write.c index 30f73d86..e6cc0d59 100644 --- a/screen-write.c +++ b/screen-write.c @@ -133,7 +133,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); @@ -157,8 +157,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; @@ -213,13 +216,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; } @@ -572,6 +576,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; @@ -585,18 +590,22 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, if (wp != NULL) screen_write_initctx(ctx, &ttyctx, 0); 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) { - ttyctx.cell = &gc; - tty_write(tty_cmd_cell, &ttyctx); - ttyctx.ocx++; + if (wp == NULL) { + s->cx++; + continue; } + ttyctx.cell = &gc; + ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC); + tty_write(tty_cmd_cell, &ttyctx); + ttyctx.ocx++; s->cx++; } s->cy++; @@ -1871,7 +1880,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, } else { screen_write_initctx(ctx, &ttyctx, 0); ttyctx.cell = &ci->gc; - ttyctx.wrapped = ci->wrapped; + if (ci->wrapped) + ttyctx.flags |= TTY_CTX_WRAPPED; ttyctx.ptr = cl->data + ci->x; ttyctx.num = ci->used; tty_write(tty_cmd_cells, &ttyctx); @@ -2177,7 +2187,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) ttyctx.cell = &tmp_gc; } else ttyctx.cell = gc; - ttyctx.num = redraw ? 2 : 0; + if (redraw) + ttyctx.flags |= TTY_CTX_CELL_DRAW_LINE; tty_write(tty_cmd_cell, &ttyctx); } } @@ -2245,7 +2256,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) if (utf8_should_combine(&last.data, ud)) force_wide = 1; else if (utf8_should_combine(ud, &last.data)) - force_wide = 1; + force_wide = 1; else if (!utf8_has_zwj(&last.data)) return (0); break; @@ -2289,7 +2300,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); @@ -2391,9 +2403,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); } diff --git a/tmux.h b/tmux.h index 0b2afbe9..47228afb 100644 --- a/tmux.h +++ b/tmux.h @@ -1732,18 +1732,18 @@ 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; + u_int num; + void *ptr; + void *ptr2; /* * Cursor and region position before the screen was updated - this is @@ -1772,7 +1772,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; diff --git a/tty.c b/tty.c index 1fdd5c2f..fd22df11 100644 --- a/tty.c +++ b/tty.c @@ -1109,7 +1109,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 || @@ -1377,9 +1377,9 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) struct visible_ranges *r; struct visible_range *rr; - 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) { r = tty_check_overlay_range(tty, ctx->xoff, ctx->yoff + py, nx); for (j = 0; j < r->used; j++) { rr = &r->ranges[j]; @@ -1561,7 +1561,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) @@ -1610,7 +1610,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) && @@ -1633,7 +1633,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) && @@ -1665,7 +1665,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) || @@ -1693,7 +1693,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) || @@ -1753,7 +1753,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) || @@ -1787,7 +1787,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) || @@ -1828,7 +1828,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) || @@ -1867,7 +1867,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) || @@ -1969,7 +1969,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; } @@ -2001,7 +2001,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; @@ -2030,7 +2030,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); } @@ -2045,10 +2045,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 || @@ -2172,20 +2172,23 @@ 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) { - /* - * This is an overlay and a command that moves the cursor so - * start synchronized updates. - */ - tty_sync_start(tty); - } else if (~ctx->num & 0x10) { - /* - * This is a pane. If there is an overlay, always start; - * otherwise, only if requested. - */ - if (ctx->num || tty->client->overlay_draw != NULL) - tty_sync_start(tty); - } + 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->flags & TTY_CTX_OVERLAY_SYNC) { + /* + * This is a pane. If there is an overlay, always start; + * otherwise, only if requested. + */ + if ((ctx->flags & TTY_CTX_SYNC) || c->overlay_draw != NULL) + tty_sync_start(tty); + } } void @@ -2351,7 +2354,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 ||