diff --git a/screen-redraw.c b/screen-redraw.c index c9e70590..4c017706 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -474,6 +474,7 @@ screen_redraw_pane(struct client *c, struct window_pane *wp) tty_sync_start(&c->tty); screen_redraw_draw_pane(&ctx, wp); + wp->flags &= ~PANE_REDRAW; tty_reset(&c->tty); tty_sync_end(&c->tty); @@ -563,6 +564,7 @@ screen_redraw_draw_panes(struct screen_redraw_ctx *ctx) TAILQ_FOREACH(wp, &w->panes, entry) { if (window_pane_visible(wp)) screen_redraw_draw_pane(ctx, wp); + wp->flags &= ~PANE_REDRAW; } } diff --git a/server-client.c b/server-client.c index cd301bbd..14691fdc 100644 --- a/server-client.c +++ b/server-client.c @@ -1370,7 +1370,6 @@ server_client_loop(void) if (resize) server_client_check_resize(wp); } - wp->flags &= ~PANE_REDRAW; } check_window_name(w); } @@ -1681,7 +1680,7 @@ server_client_check_redraw(struct client *c) struct session *s = c->session; struct tty *tty = &c->tty; struct window_pane *wp; - int needed, flags, mode = tty->mode; + int needed, flags, mode = tty->mode, new_flags = 0; struct timeval tv = { .tv_usec = 1000 }; static struct event ev; size_t left; @@ -1689,11 +1688,12 @@ server_client_check_redraw(struct client *c) if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) return; if (c->flags & CLIENT_ALLREDRAWFLAGS) { - log_debug("%s: redraw%s%s%s%s", c->name, + log_debug("%s: redraw%s%s%s%s%s", c->name, (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "", (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "", (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "", - (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : ""); + (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : "", + (c->flags & CLIENT_REDRAWPANES) ? " panes" : ""); } /* @@ -1711,6 +1711,8 @@ server_client_check_redraw(struct client *c) break; } } + if (needed) + new_flags |= CLIENT_REDRAWPANES; } if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) { log_debug("%s: redraw deferred (%zu left)", c->name, left); @@ -1720,12 +1722,7 @@ server_client_check_redraw(struct client *c) log_debug("redraw timer started"); evtimer_add(&ev, &tv); } - - /* - * We may have got here for a single pane redraw, but force a - * full redraw next time in case other panes have been updated. - */ - c->flags |= CLIENT_ALLREDRAWFLAGS; + c->flags |= new_flags; return; } else if (needed) log_debug("%s: redraw needed", c->name); @@ -1745,6 +1742,7 @@ server_client_check_redraw(struct client *c) screen_redraw_pane(c, wp); } } + c->flags &= ~CLIENT_REDRAWPANES; } if (c->flags & CLIENT_ALLREDRAWFLAGS) { diff --git a/tmux.h b/tmux.h index e5d7be90..64b09abf 100644 --- a/tmux.h +++ b/tmux.h @@ -1542,12 +1542,14 @@ struct client { #define CLIENT_CONTROL_NOOUTPUT 0x4000000 #define CLIENT_DEFAULTSOCKET 0x8000000 #define CLIENT_STARTSERVER 0x10000000 +#define CLIENT_REDRAWPANES 0x20000000 #define CLIENT_ALLREDRAWFLAGS \ (CLIENT_REDRAWWINDOW| \ CLIENT_REDRAWSTATUS| \ CLIENT_REDRAWSTATUSALWAYS| \ CLIENT_REDRAWBORDERS| \ - CLIENT_REDRAWOVERLAY) + CLIENT_REDRAWOVERLAY| \ + CLIENT_REDRAWPANES) #define CLIENT_UNATTACHEDFLAGS \ (CLIENT_DEAD| \ CLIENT_SUSPENDED| \ diff --git a/tty.c b/tty.c index 92827f5d..cdfedf6c 100644 --- a/tty.c +++ b/tty.c @@ -944,6 +944,7 @@ tty_fake_bce(const struct tty *tty, struct window_pane *wp, u_int bg) static void tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) { + struct client *c = tty->client; struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i; @@ -953,6 +954,7 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) * likely to be followed by some more scrolling. */ if (tty_large_region(tty, ctx)) { + log_debug("%s: %s, large redraw of %%%u", __func__, c->name, wp->id); wp->flags |= PANE_REDRAW; return; } @@ -1484,6 +1486,14 @@ tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *), TAILQ_FOREACH(c, &clients, entry) { if (!tty_client_ready(c, wp)) continue; + if (c->flags & CLIENT_REDRAWPANES) { + /* + * Redraw is already deferred to redraw another pane - + * redraw this one also when that happens. + */ + wp->flags |= PANE_REDRAW; + break; + } ctx->bigger = tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);