mirror of
https://github.com/tmux/tmux.git
synced 2026-10-08 02:34:28 +00:00
Instead of redrawing the entire pane or scene when moving or redrawing a
pane, add damage rectangles and redraw only the affected spans. From Michael Grant.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: server-client.c,v 1.516 2026/10/02 12:28:07 nicm Exp $ */
|
||||
/* $OpenBSD: server-client.c,v 1.517 2026/10/02 12:48:52 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -361,7 +361,13 @@ server_client_set_session(struct client *c, struct session *s)
|
||||
tty_update_client_offset(c);
|
||||
status_timer_start(c);
|
||||
server_client_fire_session_changed(c, old);
|
||||
server_redraw_client(c);
|
||||
|
||||
/*
|
||||
* Redraw if the session or displayed window changed. Use the
|
||||
* cached scene because the session's current window is already set.
|
||||
*/
|
||||
if (old != s || !redraw_client_has_window(c, s->curw->window))
|
||||
server_redraw_client(c);
|
||||
}
|
||||
|
||||
server_check_unattached();
|
||||
@@ -1353,10 +1359,11 @@ server_client_key_callback(struct cmdq_item *item, void *data)
|
||||
m->key = key;
|
||||
|
||||
/*
|
||||
* Mouse drag is in progress, so fire the callback (now that
|
||||
* the mouse event is valid).
|
||||
* Synchronize direct drag output with the later damage redraw
|
||||
* before invoking the drag callback.
|
||||
*/
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_DRAGGING) {
|
||||
tty_sync_start(&c->tty);
|
||||
c->tty.mouse_drag_update(c, m);
|
||||
goto out;
|
||||
}
|
||||
@@ -1783,8 +1790,8 @@ server_client_loop(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Any windows will have been redrawn as part of clients, so clear
|
||||
* their flags now.
|
||||
* Clear window redraw state after processing all clients. Deferred
|
||||
* redraws are preserved in client flags.
|
||||
*/
|
||||
RB_FOREACH(w, windows, &windows) {
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
@@ -1795,6 +1802,8 @@ server_client_loop(void)
|
||||
wp->flags &= ~(PANE_REDRAW|PANE_REDRAWSCROLLBAR|
|
||||
PANE_ACTIVITY);
|
||||
}
|
||||
redraw_free_damage(w);
|
||||
|
||||
check_window_name(w);
|
||||
}
|
||||
|
||||
@@ -2340,6 +2349,8 @@ server_client_any_pane_redraw(struct client *c)
|
||||
|
||||
if (c->flags & CLIENT_REDRAWWINDOW)
|
||||
return (1);
|
||||
if (!TAILQ_EMPTY(&w->damage))
|
||||
return (1);
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->flags & (PANE_REDRAW|PANE_REDRAWSCROLLBAR))
|
||||
return (1);
|
||||
@@ -2356,6 +2367,7 @@ server_client_check_redraw(struct client *c)
|
||||
struct window *w = s->curw->window;
|
||||
struct window_pane *wp;
|
||||
int needed, tflags, mode = tty->mode;
|
||||
int damaged = !TAILQ_EMPTY(&w->damage);
|
||||
struct timeval tv = { .tv_usec = 1000 };
|
||||
static struct event ev;
|
||||
size_t n;
|
||||
@@ -2381,12 +2393,12 @@ server_client_check_redraw(struct client *c)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is outstanding data, defer the redraw until it has been
|
||||
* consumed. We can just add a timer to get out of the event loop and
|
||||
* end up back here.
|
||||
*/
|
||||
/* Ignore output queued within the current synchronized frame. */
|
||||
n = EVBUFFER_LENGTH(tty->out);
|
||||
if ((tty->flags & TTY_SYNCING) && n > tty->sync_offset)
|
||||
n = tty->sync_offset;
|
||||
|
||||
/* Defer until output drains, preserving damage in client flags. */
|
||||
if (n != 0 || (tty->flags & TTY_BLOCK)) {
|
||||
if (n != 0)
|
||||
log_debug("%s: redraw deferred (%zu left)", c->name, n);
|
||||
@@ -2398,6 +2410,10 @@ server_client_check_redraw(struct client *c)
|
||||
log_debug("redraw timer started");
|
||||
evtimer_add(&ev, &tv);
|
||||
}
|
||||
if (damaged) {
|
||||
c->flags |= CLIENT_REDRAWWINDOW;
|
||||
return;
|
||||
}
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->flags & PANE_REDRAW) {
|
||||
c->flags |= CLIENT_REDRAWWINDOW;
|
||||
@@ -2431,6 +2447,10 @@ server_client_check_redraw(struct client *c)
|
||||
redraw_pane_scrollbar(c, wp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw damage here if no client redraw flags will handle it. */
|
||||
if (damaged && (c->flags & CLIENT_ALLREDRAWFLAGS) == 0)
|
||||
redraw_client_damage(c);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2444,6 +2464,7 @@ server_client_check_redraw(struct client *c)
|
||||
}
|
||||
server_client_set_progress_bar(c);
|
||||
redraw_screen(c);
|
||||
redraw_client_damage(c);
|
||||
}
|
||||
|
||||
/* Put the tty back how it was. */
|
||||
|
||||
Reference in New Issue
Block a user