Redraw only scrollbars not entire pane.

This commit is contained in:
Nicholas Marriott 2024-11-04 09:25:18 +00:00
parent 3fed73d86b
commit 7637afc382
4 changed files with 57 additions and 30 deletions

View File

@ -219,7 +219,6 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
free(title);
return (CMD_RETURN_NORMAL);
}
wp->flags |= PANE_REDRAWSCROLLBAR;
if (c != NULL && c->session != NULL && (c->flags & CLIENT_ACTIVEPANE))
activewp = server_client_get_pane(c);

View File

@ -666,33 +666,33 @@ screen_redraw_screen(struct client *c)
/* Redraw a single pane and its scrollbar. */
void
screen_redraw_pane(struct client *c, struct window_pane *wp)
screen_redraw_pane(struct client *c, struct window_pane *wp,
int redraw_scrollbar_only)
{
struct screen_redraw_ctx ctx;
int pane_scrollbars, mode;
if (!window_pane_visible(wp))
return;
mode = window_pane_mode(wp);
screen_redraw_set_context(c, &ctx);
tty_sync_start(&c->tty);
tty_update_mode(&c->tty, c->tty.mode, NULL);
screen_redraw_draw_pane(&ctx, wp);
if (!redraw_scrollbar_only)
screen_redraw_draw_pane(&ctx, wp);
/*
* Redraw scrollbar if needed. Always redraw scrollbar in a mode because
* if redrawing a pane, it's because pane has scrolled.
*/
mode = window_pane_mode(wp);
if (wp->flags & PANE_REDRAWSCROLLBAR || mode != WINDOW_PANE_NO_MODE) {
pane_scrollbars = ctx.pane_scrollbars;
if (pane_scrollbars == PANE_SCROLLBARS_MODAL &&
mode == WINDOW_PANE_NO_MODE)
pane_scrollbars = PANE_SCROLLBARS_OFF;
if (pane_scrollbars != PANE_SCROLLBARS_OFF)
screen_redraw_draw_pane_scrollbar(&ctx, wp);
}
pane_scrollbars = ctx.pane_scrollbars;
if (pane_scrollbars == PANE_SCROLLBARS_MODAL &&
mode == WINDOW_PANE_NO_MODE)
pane_scrollbars = PANE_SCROLLBARS_OFF;
if (pane_scrollbars != PANE_SCROLLBARS_OFF)
screen_redraw_draw_pane_scrollbar(&ctx, wp);
tty_reset(&c->tty);
}

View File

@ -2658,7 +2658,7 @@ server_client_check_redraw(struct client *c)
struct window_pane *wp;
int needed, tty_flags, mode = tty->mode;
uint64_t client_flags = 0;
int redraw;
int redraw_pane, redraw_scrollbar_only;
u_int bit = 0;
struct timeval tv = { .tv_usec = 1000 };
static struct event ev;
@ -2667,12 +2667,13 @@ 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%s", c->name,
log_debug("%s: redraw%s%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_REDRAWPANES) ? " panes" : "");
(c->flags & CLIENT_REDRAWPANES) ? " panes" : "",
(c->flags & CLIENT_REDRAWSCROLLBARS) ? " scrollbars" : "");
}
/*
@ -2685,13 +2686,17 @@ server_client_check_redraw(struct client *c)
needed = 1;
else {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & (PANE_REDRAW|PANE_REDRAWSCROLLBAR)) {
if (wp->flags & PANE_REDRAW) {
needed = 1;
client_flags |= CLIENT_REDRAWPANES;
break;
}
if (wp->flags & PANE_REDRAWSCROLLBAR) {
needed = 1;
client_flags |= CLIENT_REDRAWSCROLLBARS;
/* no break - later panes may need redraw */
}
}
if (needed)
client_flags |= CLIENT_REDRAWPANES;
}
if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) {
log_debug("%s: redraw deferred (%zu left)", c->name, left);
@ -2704,23 +2709,30 @@ server_client_check_redraw(struct client *c)
if (~c->flags & CLIENT_REDRAWWINDOW) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & (PANE_REDRAW|PANE_REDRAWSCROLLBAR)) {
if (wp->flags & (PANE_REDRAW)) {
log_debug("%s: pane %%%u needs redraw",
c->name, wp->id);
c->redraw_panes |= (1 << bit);
} else if (wp->flags & PANE_REDRAWSCROLLBAR) {
log_debug("%s: pane %%%u scrollbar "
"needs redraw", c->name, wp->id);
c->redraw_scrollbars |= (1 << bit);
}
if (++bit == 64) {
/*
* If more that 64 panes, give up and
* just redraw the window.
*/
client_flags &= CLIENT_REDRAWPANES;
client_flags &= ~(CLIENT_REDRAWPANES|
CLIENT_REDRAWSCROLLBARS);
client_flags |= CLIENT_REDRAWWINDOW;
break;
}
}
if (c->redraw_panes != 0)
c->flags |= CLIENT_REDRAWPANES;
if (c->redraw_scrollbars != 0)
c->flags |= CLIENT_REDRAWSCROLLBARS;
}
c->flags |= client_flags;
return;
@ -2736,19 +2748,32 @@ server_client_check_redraw(struct client *c)
* needs to be redrawn.
*/
TAILQ_FOREACH(wp, &w->panes, entry) {
redraw = 0;
redraw_pane = 0;
redraw_scrollbar_only = 0;
if (wp->flags & PANE_REDRAW)
redraw = 1;
else if (c->flags & CLIENT_REDRAWPANES)
redraw = !!(c->redraw_panes & (1 << bit));
redraw_pane = 1;
else if (c->flags & CLIENT_REDRAWPANES) {
if (c->redraw_panes & (1 << bit))
redraw_pane = 1;
} else if (c->flags & CLIENT_REDRAWSCROLLBARS) {
if (c->redraw_scrollbars & (1 << bit))
redraw_scrollbar_only = 1;
}
bit++;
if (!redraw)
if (!redraw_pane && !redraw_scrollbar_only)
continue;
log_debug("%s: redrawing pane %%%u", __func__, wp->id);
screen_redraw_pane(c, wp);
if (redraw_scrollbar_only) {
log_debug("%s: redrawing (scrollbar only) pane "
"%%%u", __func__, wp->id);
} else {
log_debug("%s: redrawing pane %%%u", __func__,
wp->id);
}
screen_redraw_pane(c, wp, redraw_scrollbar_only);
}
c->redraw_panes = 0;
c->flags &= ~CLIENT_REDRAWPANES;
c->redraw_scrollbars = 0;
c->flags &= ~(CLIENT_REDRAWPANES|CLIENT_REDRAWSCROLLBARS);
}
if (c->flags & CLIENT_ALLREDRAWFLAGS) {

7
tmux.h
View File

@ -1932,13 +1932,15 @@ struct client {
#define CLIENT_CLIPBOARDBUFFER 0x800000000ULL
#define CLIENT_BRACKETPASTING 0x1000000000ULL
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
#define CLIENT_REDRAWSCROLLBARS 0x4000000000ULL
#define CLIENT_ALLREDRAWFLAGS \
(CLIENT_REDRAWWINDOW| \
CLIENT_REDRAWSTATUS| \
CLIENT_REDRAWSTATUSALWAYS| \
CLIENT_REDRAWBORDERS| \
CLIENT_REDRAWOVERLAY| \
CLIENT_REDRAWPANES)
CLIENT_REDRAWPANES| \
CLIENT_REDRAWSCROLLBARS)
#define CLIENT_UNATTACHEDFLAGS \
(CLIENT_DEAD| \
CLIENT_SUSPENDED| \
@ -1965,6 +1967,7 @@ struct client {
key_code last_key;
uint64_t redraw_panes;
uint64_t redraw_scrollbars;
int message_ignore_keys;
int message_ignore_styles;
@ -3080,7 +3083,7 @@ void screen_write_alternateoff(struct screen_write_ctx *,
/* screen-redraw.c */
void screen_redraw_screen(struct client *);
void screen_redraw_pane(struct client *, struct window_pane *);
void screen_redraw_pane(struct client *, struct window_pane *, int);
/* screen.c */
void screen_init(struct screen *, u_int, u_int, u_int);