mirror of
https://github.com/tmux/tmux.git
synced 2026-10-07 10:14:28 +00:00
Merge branch 'master' into command_parser
# Conflicts: # cmd-parse.y # regress/control-client-exit.sh # regress/if-shell-error.sh # tmux.h
This commit is contained in:
313
screen-write.c
313
screen-write.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: screen-write.c,v 1.290 2026/08/24 15:05:26 nicm Exp $ */
|
||||
/* $OpenBSD: screen-write.c,v 1.299 2026/10/05 08:41:23 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -38,7 +38,9 @@ static int screen_write_overwrite(struct screen_write_ctx *,
|
||||
struct grid_cell *, u_int);
|
||||
static int screen_write_combine(struct screen_write_ctx *,
|
||||
const struct grid_cell *);
|
||||
static void screen_write_flush_dirty(struct window_pane *);
|
||||
static void screen_write_sync_flush_dirty(struct window_pane *);
|
||||
static void screen_write_sync_apply_scroll(struct screen_write_ctx *,
|
||||
struct tty_ctx *);
|
||||
|
||||
struct screen_write_citem {
|
||||
u_int x;
|
||||
@@ -120,14 +122,26 @@ screen_write_set_cursor(struct screen_write_ctx *ctx, int cx, int cy)
|
||||
evtimer_add(&w->offset_timer, &tv);
|
||||
}
|
||||
|
||||
/* Do a full redraw. */
|
||||
/* Redraw lines. */
|
||||
static void
|
||||
screen_write_redraw_cb(const struct tty_ctx *ttyctx)
|
||||
screen_write_redraw_cb(const struct tty_ctx *ttyctx, u_int py, u_int ny)
|
||||
{
|
||||
struct window_pane *wp = ttyctx->arg;
|
||||
int x0, y0, x1, y1;
|
||||
|
||||
if (wp != NULL)
|
||||
wp->flags |= PANE_REDRAW;
|
||||
if (wp == NULL)
|
||||
return;
|
||||
|
||||
x0 = wp->xoff;
|
||||
y0 = wp->yoff + (int)py;
|
||||
x1 = x0 + (int)wp->sx;
|
||||
y1 = y0 + (int)ny;
|
||||
if (x0 < 0)
|
||||
x0 = 0;
|
||||
if (y0 < 0)
|
||||
y0 = 0;
|
||||
if (x1 > x0 && y1 > y0)
|
||||
redraw_damage_window(wp->window, x0, y0, x1 - x0, y1 - y0);
|
||||
}
|
||||
|
||||
/* Update context for client. */
|
||||
@@ -175,11 +189,12 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Return 1 if there is a floating window pane overlapping this pane. */
|
||||
/* Return 1 if a menu or floating pane overlaps this pane. */
|
||||
static int
|
||||
screen_write_pane_is_obscured(struct screen_write_ctx *ctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct menu_data *md;
|
||||
|
||||
if (ctx->wp == NULL)
|
||||
return (0);
|
||||
@@ -190,6 +205,16 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx)
|
||||
}
|
||||
ctx->flags |= SCREEN_WRITE_CHECKED_IF_OBSCURED;
|
||||
|
||||
md = wp->window->menu;
|
||||
if (md != NULL &&
|
||||
(int)menu_x(md) < wp->xoff + (int)wp->sx &&
|
||||
(int)(menu_x(md) + menu_width(md)) > wp->xoff &&
|
||||
(int)menu_y(md) < wp->yoff + (int)wp->sy &&
|
||||
(int)(menu_y(md) + menu_height(md)) > wp->yoff) {
|
||||
ctx->flags |= SCREEN_WRITE_OBSCURED;
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (ctx->wp->xoff < 0 ||
|
||||
ctx->wp->yoff < 0 ||
|
||||
ctx->wp->xoff + ctx->wp->sx > ctx->wp->window->sx ||
|
||||
@@ -199,15 +224,7 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx)
|
||||
}
|
||||
|
||||
while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) {
|
||||
if (window_pane_is_floating(wp) &&
|
||||
((wp->yoff >= ctx->wp->yoff &&
|
||||
wp->yoff <= ctx->wp->yoff + (int)ctx->wp->sy) ||
|
||||
(wp->yoff + (int)wp->sy >= ctx->wp->yoff &&
|
||||
wp->yoff + wp->sy <= ctx->wp->yoff + ctx->wp->sy)) &&
|
||||
((wp->xoff >= ctx->wp->xoff &&
|
||||
wp->xoff <= ctx->wp->xoff + (int)ctx->wp->sx) ||
|
||||
(wp->xoff + (int)wp->sx >= ctx->wp->xoff &&
|
||||
wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) {
|
||||
if (window_pane_floating_overlaps(wp, ctx->wp)) {
|
||||
ctx->flags |= SCREEN_WRITE_OBSCURED;
|
||||
return (1);
|
||||
}
|
||||
@@ -215,6 +232,27 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Allocate dirty lines for this screen size. */
|
||||
static bitstr_t *
|
||||
screen_write_sync_allocate_dirty(struct window_pane *wp, u_int sy)
|
||||
{
|
||||
bitstr_t *bs = wp->sync_dirty;
|
||||
|
||||
if (bs != NULL && wp->sync_dirty_size == sy)
|
||||
return (bs);
|
||||
|
||||
free(bs);
|
||||
bs = wp->sync_dirty = bit_alloc(sy);
|
||||
if (bs == NULL)
|
||||
fatal("bit_alloc failed");
|
||||
if (wp->sync_dirty_size != 0) {
|
||||
bit_nset(bs, 0, sy - 1);
|
||||
wp->sync_scrolled = 0;
|
||||
}
|
||||
wp->sync_dirty_size = sy;
|
||||
return (bs);
|
||||
}
|
||||
|
||||
/* Should we draw to the TTY? */
|
||||
static int
|
||||
screen_write_should_draw_lines(struct screen_write_ctx *ctx, u_int y, u_int ny)
|
||||
@@ -228,21 +266,9 @@ screen_write_should_draw_lines(struct screen_write_ctx *ctx, u_int y, u_int ny)
|
||||
return (0);
|
||||
if (s->mode & MODE_SYNC) {
|
||||
if (wp != NULL && y < sy && ny != 0) {
|
||||
bs = wp->sync_dirty;
|
||||
if (ny > sy - y)
|
||||
ny = sy - y;
|
||||
if (bs == NULL || wp->sync_dirty_size != sy) {
|
||||
if (bs != NULL && wp->sync_dirty_size != sy) {
|
||||
y = 0;
|
||||
ny = sy;
|
||||
}
|
||||
free(bs);
|
||||
|
||||
bs = wp->sync_dirty = bit_alloc(sy);
|
||||
if (bs == NULL)
|
||||
fatal("bit_alloc failed");
|
||||
wp->sync_dirty_size = sy;
|
||||
}
|
||||
bs = screen_write_sync_allocate_dirty(wp, sy);
|
||||
bit_nset(bs, y, y + ny - 1);
|
||||
}
|
||||
return (0);
|
||||
@@ -305,21 +331,16 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
||||
|
||||
if (~ctx->flags & SCREEN_WRITE_SYNC) {
|
||||
/*
|
||||
* For the active pane showing its base screen or for an
|
||||
* overlay (no pane), only use synchronized updates if
|
||||
* requested (commands that move the cursor); for other panes
|
||||
* or a pane in a mode, always use it, since the cursor will
|
||||
* have to move.
|
||||
* For the active pane showing its base screen, only use
|
||||
* synchronized updates if requested (commands that move the
|
||||
* cursor); for other panes or a pane in a mode, always use it,
|
||||
* since the cursor will have to move.
|
||||
*/
|
||||
if (ctx->wp != NULL && (ctx->wp != ctx->wp->window->active ||
|
||||
ctx->wp->screen != &ctx->wp->base))
|
||||
ttyctx->flags |= TTY_CTX_SYNC;
|
||||
else {
|
||||
if (ctx->wp == NULL)
|
||||
ttyctx->flags |= TTY_CTX_OVERLAY_SYNC;
|
||||
if (is_sync)
|
||||
ttyctx->flags |= TTY_CTX_SYNC;
|
||||
}
|
||||
else if (is_sync)
|
||||
ttyctx->flags |= TTY_CTX_SYNC;
|
||||
tty_write(tty_cmd_syncstart, ttyctx);
|
||||
ctx->flags |= SCREEN_WRITE_SYNC;
|
||||
}
|
||||
@@ -731,7 +752,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
||||
if (!window_position_is_visible(r, xoff + s->cx))
|
||||
break;
|
||||
ttyctx.cell = &gc;
|
||||
ttyctx.flags &= (TTY_CTX_OVERLAY_SYNC|TTY_CTX_SYNC);
|
||||
ttyctx.flags &= TTY_CTX_SYNC;
|
||||
tty_write(tty_cmd_cell, &ttyctx);
|
||||
ttyctx.ocx++;
|
||||
|
||||
@@ -855,34 +876,39 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
|
||||
struct screen *s = ctx->s;
|
||||
struct grid_cell default_gc;
|
||||
const struct grid_cell *gc = &default_gc;
|
||||
u_int cx, cy, i, j, width = menu->width;
|
||||
u_int border, cx = s->cx, cy = s->cy, i, j, width;
|
||||
const char *name;
|
||||
|
||||
cx = s->cx;
|
||||
cy = s->cy;
|
||||
|
||||
memcpy(&default_gc, menu_gc, sizeof default_gc);
|
||||
|
||||
screen_write_box(ctx, menu->width + 4, menu->count + 2, lines,
|
||||
border_gc, menu->title);
|
||||
if (lines == BOX_LINES_NONE) {
|
||||
border = 0;
|
||||
width = menu->item_width;
|
||||
} else {
|
||||
border = 1;
|
||||
width = menu->width;
|
||||
screen_write_box(ctx, width + 4, menu->count + 2, lines,
|
||||
border_gc, menu->title);
|
||||
}
|
||||
|
||||
for (i = 0; i < menu->count; i++) {
|
||||
name = menu->items[i].name;
|
||||
if (name == NULL) {
|
||||
screen_write_cursormove(ctx, cx, cy + 1 + i, 0);
|
||||
screen_write_hline(ctx, width + 4, 1, 1, lines,
|
||||
border_gc);
|
||||
screen_write_cursormove(ctx, cx, cy + border + i, 0);
|
||||
screen_write_hline(ctx, width + 2 + (2 * border), 1, 1,
|
||||
lines, border_gc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice >= 0 && i == (u_int)choice && *name != '-')
|
||||
gc = choice_gc;
|
||||
|
||||
screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0);
|
||||
screen_write_cursormove(ctx, cx + border, cy + border + i, 0);
|
||||
for (j = 0; j < width + 2; j++)
|
||||
screen_write_putc(ctx, gc, ' ');
|
||||
|
||||
screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
|
||||
screen_write_cursormove(ctx, cx + border + 1, cy + border + i,
|
||||
0);
|
||||
if (*name == '-') {
|
||||
default_gc.attr |= GRID_ATTR_DIM;
|
||||
format_draw(ctx, gc, width, name + 1, NULL, 0);
|
||||
@@ -1049,7 +1075,7 @@ screen_write_sync_callback(__unused int fd, __unused short events, void *arg)
|
||||
|
||||
if (wp->base.mode & MODE_SYNC) {
|
||||
wp->base.mode &= ~MODE_SYNC;
|
||||
screen_write_flush_dirty(wp);
|
||||
screen_write_sync_flush_dirty(wp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,7 +1107,7 @@ screen_write_stop_sync(struct window_pane *wp)
|
||||
evtimer_del(&wp->sync_timer);
|
||||
wp->base.mode &= ~MODE_SYNC;
|
||||
|
||||
screen_write_flush_dirty(wp);
|
||||
screen_write_sync_flush_dirty(wp);
|
||||
|
||||
log_debug("%s: %%%u stopped sync mode", __func__, wp->id);
|
||||
}
|
||||
@@ -1289,7 +1315,7 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
||||
|
||||
/* Redraw dirty lines. */
|
||||
static void
|
||||
screen_write_flush_dirty(struct window_pane *wp)
|
||||
screen_write_sync_flush_dirty(struct window_pane *wp)
|
||||
{
|
||||
struct screen_write_ctx ctx;
|
||||
struct tty_ctx ttyctx;
|
||||
@@ -1302,29 +1328,143 @@ screen_write_flush_dirty(struct window_pane *wp)
|
||||
screen_write_start_pane(&ctx, wp, s);
|
||||
screen_write_initctx(&ctx, &ttyctx, 1, 1);
|
||||
|
||||
for (y = 0; y < sy; y++) {
|
||||
if (bit_test(wp->sync_dirty, y)) {
|
||||
screen_write_redraw_line(&ctx, &ttyctx, y);
|
||||
lines++;
|
||||
if (wp->sync_scrolled != 0)
|
||||
screen_write_sync_apply_scroll(&ctx, &ttyctx);
|
||||
|
||||
if (~wp->flags & PANE_REDRAW) {
|
||||
for (y = 0; y < sy; y++) {
|
||||
if (bit_test(wp->sync_dirty, y)) {
|
||||
screen_write_redraw_line(&ctx, &ttyctx, y);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_debug("%s: %%%u had %u dirty lines", __func__, wp->id, lines);
|
||||
|
||||
screen_write_stop(&ctx);
|
||||
screen_write_clear_dirty(wp);
|
||||
screen_write_sync_clear_dirty(wp);
|
||||
}
|
||||
|
||||
/* Clear any dirty lines. */
|
||||
/* Clear pending synchronized output. */
|
||||
void
|
||||
screen_write_clear_dirty(struct window_pane *wp)
|
||||
screen_write_sync_clear_dirty(struct window_pane *wp)
|
||||
{
|
||||
if (wp != NULL && wp->sync_dirty != NULL) {
|
||||
if (wp != NULL) {
|
||||
free(wp->sync_dirty);
|
||||
wp->sync_dirty = NULL;
|
||||
wp->sync_dirty_size = 0;
|
||||
wp->sync_scrolled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Defer scrolling until the synchronized update ends. */
|
||||
static void
|
||||
screen_write_sync_scroll_dirty(struct screen_write_ctx *ctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = ctx->s;
|
||||
u_int n = ctx->scrolled, y, sy = screen_size_y(s);
|
||||
u_int ry = s->rlower + 1 - s->rupper;
|
||||
bitstr_t *bs;
|
||||
|
||||
if (n > ry)
|
||||
n = ry;
|
||||
if (wp == NULL ||
|
||||
n == ry ||
|
||||
s->rlower >= sy ||
|
||||
window_pane_scrollbar_overlay_visible(wp)) {
|
||||
screen_write_should_draw_lines(ctx, s->rupper, ry);
|
||||
return;
|
||||
}
|
||||
if (wp->flags & (PANE_REDRAW|PANE_DROP))
|
||||
return;
|
||||
bs = screen_write_sync_allocate_dirty(wp, sy);
|
||||
|
||||
if (wp->sync_scrolled != 0 &&
|
||||
(wp->sync_rupper != s->rupper ||
|
||||
wp->sync_rlower != s->rlower ||
|
||||
wp->sync_bg != ctx->bg)) {
|
||||
log_debug("%s: %%%u region changed, redrawing all", __func__,
|
||||
wp->id);
|
||||
bit_nset(bs, 0, sy - 1);
|
||||
wp->sync_scrolled = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Keep dirty lines aligned with the scrolled grid. */
|
||||
for (y = s->rupper; y + n <= s->rlower; y++) {
|
||||
if (bit_test(bs, y + n))
|
||||
bit_set(bs, y);
|
||||
else
|
||||
bit_clear(bs, y);
|
||||
}
|
||||
bit_nset(bs, s->rlower + 1 - n, s->rlower);
|
||||
|
||||
wp->sync_rupper = s->rupper;
|
||||
wp->sync_rlower = s->rlower;
|
||||
wp->sync_bg = ctx->bg;
|
||||
wp->sync_scrolled += n;
|
||||
if (wp->sync_scrolled >= ry) {
|
||||
bit_nset(bs, s->rupper, s->rlower);
|
||||
wp->sync_scrolled = 0;
|
||||
}
|
||||
window_pane_scrollbar_redraw(wp);
|
||||
|
||||
log_debug("%s: %%%u deferred scroll of %u (region %u-%u)", __func__,
|
||||
wp->id, wp->sync_scrolled, s->rupper, s->rlower);
|
||||
}
|
||||
|
||||
/* Redraw the scrolled lines for a client which cannot scroll them. */
|
||||
static void
|
||||
screen_write_sync_redraw_cb(const struct tty_ctx *ttyctx, u_int py, u_int ny)
|
||||
{
|
||||
struct window_pane *wp = ttyctx->arg;
|
||||
|
||||
bit_nset(wp->sync_dirty, py, py + ny - 1);
|
||||
}
|
||||
|
||||
/* Send the deferred scroll to the client. */
|
||||
static void
|
||||
screen_write_sync_apply_scroll(struct screen_write_ctx *ctx,
|
||||
struct tty_ctx *ttyctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = ctx->s;
|
||||
u_int sy = screen_size_y(s), n = wp->sync_scrolled;
|
||||
tty_ctx_redraw_cb redraw_cb;
|
||||
|
||||
wp->sync_scrolled = 0;
|
||||
if (wp->flags & PANE_REDRAW)
|
||||
return;
|
||||
if (wp->sync_rlower >= sy || wp->sync_rupper > wp->sync_rlower) {
|
||||
bit_nset(wp->sync_dirty, 0, sy - 1);
|
||||
return;
|
||||
}
|
||||
if ((ttyctx->flags & TTY_CTX_PANE_OBSCURED) ||
|
||||
window_pane_scrollbar_overlay_visible(wp)) {
|
||||
bit_nset(wp->sync_dirty, wp->sync_rupper, wp->sync_rlower);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("%s: %%%u scroll of %u (region %u-%u)", __func__, wp->id, n,
|
||||
wp->sync_rupper, wp->sync_rlower);
|
||||
|
||||
ttyctx->orupper = wp->sync_rupper;
|
||||
ttyctx->orlower = wp->sync_rlower;
|
||||
if (wp->yoff + wp->sy > wp->window->sy)
|
||||
ttyctx->orlower -= (wp->yoff + wp->sy - wp->window->sy);
|
||||
ttyctx->n = n;
|
||||
ttyctx->bg = wp->sync_bg;
|
||||
redraw_cb = ttyctx->redraw_cb;
|
||||
ttyctx->redraw_cb = screen_write_sync_redraw_cb;
|
||||
tty_write(tty_cmd_scrollup, ttyctx);
|
||||
|
||||
ttyctx->redraw_cb = redraw_cb;
|
||||
ttyctx->orupper = s->rupper;
|
||||
ttyctx->orlower = s->rlower;
|
||||
ttyctx->n = 0;
|
||||
}
|
||||
|
||||
/* Redraw all visible cells in a pane. */
|
||||
static void
|
||||
screen_write_redraw_pane(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx)
|
||||
@@ -2172,7 +2312,7 @@ screen_write_fullredraw(struct screen_write_ctx *ctx)
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
/* Trim collected items. */
|
||||
@@ -2410,13 +2550,18 @@ screen_write_collect_flush_line(struct screen_write_ctx *ctx, u_int y)
|
||||
ttyctx.n = w_length;
|
||||
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
||||
} else {
|
||||
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
||||
ttyctx.cell = &ci->gc;
|
||||
if (ci->wrapped)
|
||||
ttyctx.flags |= TTY_CTX_WRAPPED;
|
||||
ttyctx.data.data = cl->data + w_start;
|
||||
ttyctx.data.size = w_length;
|
||||
tty_write(tty_cmd_cells, &ttyctx);
|
||||
screen_write_initctx(ctx, &ttyctx, 0, 1);
|
||||
if (ttyctx.flags & TTY_CTX_PANE_OBSCURED) {
|
||||
ttyctx.n = w_length;
|
||||
tty_write(tty_cmd_redrawline, &ttyctx);
|
||||
} else {
|
||||
ttyctx.cell = &ci->gc;
|
||||
if (ci->wrapped)
|
||||
ttyctx.flags |= TTY_CTX_WRAPPED;
|
||||
ttyctx.data.data = cl->data + w_start;
|
||||
ttyctx.data.size = w_length;
|
||||
tty_write(tty_cmd_cells, &ttyctx);
|
||||
}
|
||||
}
|
||||
items++;
|
||||
written = 1;
|
||||
@@ -2444,10 +2589,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
||||
if (wp != NULL && (wp->flags & (PANE_REDRAW|PANE_DROP)))
|
||||
goto discard;
|
||||
if (s->mode & MODE_SYNC) {
|
||||
if (ctx->scrolled != 0) {
|
||||
screen_write_should_draw_lines(ctx, s->rupper,
|
||||
s->rlower + 1 - s->rupper);
|
||||
}
|
||||
if (ctx->scrolled != 0)
|
||||
screen_write_sync_scroll_dirty(ctx);
|
||||
for (y = 0; y < screen_size_y(s); y++) {
|
||||
cl = &s->write_list[y];
|
||||
if (!TAILQ_EMPTY(&cl->items))
|
||||
@@ -2646,6 +2789,10 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
||||
* Don't need to check that the attributes and whatnot are still the
|
||||
* same - input_parse will end the collection when anything that isn't
|
||||
* a plain character is encountered.
|
||||
*
|
||||
* Without wrapping, collect up to but not including the last column.
|
||||
* Leave that cell to screen_write_cell so repeated writes overwrite it
|
||||
* and the cursor remains at the right edge.
|
||||
*/
|
||||
|
||||
collect = 1;
|
||||
@@ -2655,7 +2802,8 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
||||
collect = 0;
|
||||
else if (gc->attr & GRID_ATTR_CHARSET)
|
||||
collect = 0;
|
||||
else if (~s->mode & MODE_WRAP)
|
||||
else if ((~s->mode & MODE_WRAP) &&
|
||||
s->cx + ctx->item->used >= sx - 1)
|
||||
collect = 0;
|
||||
else if (s->mode & MODE_INSERT)
|
||||
collect = 0;
|
||||
@@ -2821,6 +2969,11 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
/* Create space for character in insert mode. */
|
||||
if (s->mode & MODE_INSERT) {
|
||||
screen_write_collect_flush(ctx, 0, __func__);
|
||||
if (wp != NULL && screen_write_pane_is_obscured(ctx)) {
|
||||
if (screen_write_should_draw_line(ctx, s->cy))
|
||||
screen_write_redraw_line(ctx, &ttyctx, s->cy);
|
||||
return;
|
||||
}
|
||||
ttyctx.n = width;
|
||||
if (screen_write_should_draw_line(ctx, s->cy))
|
||||
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
||||
@@ -3170,6 +3323,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
{
|
||||
struct tty_ctx ttyctx;
|
||||
struct window_pane *wp = ctx->wp;
|
||||
int pending;
|
||||
|
||||
if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
|
||||
return;
|
||||
@@ -3179,11 +3333,12 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
return;
|
||||
|
||||
if (wp != NULL) {
|
||||
pending = !TAILQ_EMPTY(&wp->resize_queue);
|
||||
window_pane_clear_resizes(wp, NULL);
|
||||
if (event_initialized(&wp->resize_timer))
|
||||
evtimer_del(&wp->resize_timer);
|
||||
layout_fix_panes(wp->window, NULL);
|
||||
if (!TAILQ_EMPTY(&wp->resize_queue)) {
|
||||
if (pending || !TAILQ_EMPTY(&wp->resize_queue)) {
|
||||
window_pane_send_resize(wp, wp->sx, wp->sy);
|
||||
window_pane_clear_resizes(wp, NULL);
|
||||
}
|
||||
@@ -3192,7 +3347,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
/* Turn alternate screen off. */
|
||||
@@ -3217,5 +3372,5 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1, 0);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
ttyctx.redraw_cb(&ttyctx);
|
||||
ttyctx.redraw_cb(&ttyctx, 0, ttyctx.sy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user