mirror of
https://github.com/tmux/tmux.git
synced 2026-07-03 10:12:31 +00:00
Deferred redraw entering alternate screen:
- Immediately sends the new PTY size. - Suppresses incremental and full-window redraws during the transition. - Releases redraw after the next PTY read. - Uses a 50 ms fallback timer to avoid leaving the pane frozen
This commit is contained in:
@@ -146,7 +146,7 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|||||||
if (wp->layout_cell == NULL)
|
if (wp->layout_cell == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (wp->flags & (PANE_REDRAW|PANE_DROP))
|
if (wp->flags & (PANE_REDRAW|PANE_DROP|PANE_REDRAWDEFER))
|
||||||
return (-1);
|
return (-1);
|
||||||
if (c->flags & CLIENT_REDRAWWINDOW) {
|
if (c->flags & CLIENT_REDRAWWINDOW) {
|
||||||
/*
|
/*
|
||||||
@@ -3017,6 +3017,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|||||||
if (!TAILQ_EMPTY(&wp->resize_queue)) {
|
if (!TAILQ_EMPTY(&wp->resize_queue)) {
|
||||||
window_pane_send_resize(wp, wp->sx, wp->sy);
|
window_pane_send_resize(wp, wp->sx, wp->sy);
|
||||||
window_pane_clear_resizes(wp, NULL);
|
window_pane_clear_resizes(wp, NULL);
|
||||||
|
window_pane_defer_redraw(wp);
|
||||||
}
|
}
|
||||||
server_redraw_window_borders(wp->window);
|
server_redraw_window_borders(wp->window);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2245,6 +2245,18 @@ server_client_any_pane_redraw(struct client *c)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
server_client_redraw_deferred(struct window *w)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
|
if (wp->flags & PANE_REDRAWDEFER)
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for client redraws. */
|
/* Check for client redraws. */
|
||||||
static void
|
static void
|
||||||
server_client_check_redraw(struct client *c)
|
server_client_check_redraw(struct client *c)
|
||||||
@@ -2260,6 +2272,8 @@ server_client_check_redraw(struct client *c)
|
|||||||
|
|
||||||
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
||||||
return;
|
return;
|
||||||
|
if (server_client_redraw_deferred(w))
|
||||||
|
return;
|
||||||
if (c->flags & CLIENT_ALLREDRAWFLAGS) {
|
if (c->flags & CLIENT_ALLREDRAWFLAGS) {
|
||||||
log_debug("%s: redraw%s%s%s%s", c->name,
|
log_debug("%s: redraw%s%s%s%s", c->name,
|
||||||
(c->flags & CLIENT_REDRAWWINDOW) ? " window" : "",
|
(c->flags & CLIENT_REDRAWWINDOW) ? " window" : "",
|
||||||
|
|||||||
4
tmux.h
4
tmux.h
@@ -1293,6 +1293,7 @@ struct window_pane {
|
|||||||
#define PANE_THEMECHANGED 0x2000
|
#define PANE_THEMECHANGED 0x2000
|
||||||
#define PANE_UNSEENCHANGES 0x4000
|
#define PANE_UNSEENCHANGES 0x4000
|
||||||
#define PANE_REDRAWSCROLLBAR 0x8000
|
#define PANE_REDRAWSCROLLBAR 0x8000
|
||||||
|
#define PANE_REDRAWDEFER 0x10000
|
||||||
|
|
||||||
u_int sb_slider_y;
|
u_int sb_slider_y;
|
||||||
u_int sb_slider_h;
|
u_int sb_slider_h;
|
||||||
@@ -1320,6 +1321,7 @@ struct window_pane {
|
|||||||
|
|
||||||
struct window_pane_resizes resize_queue;
|
struct window_pane_resizes resize_queue;
|
||||||
struct event resize_timer;
|
struct event resize_timer;
|
||||||
|
struct event redraw_timer;
|
||||||
struct event sync_timer;
|
struct event sync_timer;
|
||||||
|
|
||||||
struct input_ctx *ictx;
|
struct input_ctx *ictx;
|
||||||
@@ -3584,6 +3586,8 @@ int window_pane_destroy_ready(struct window_pane *);
|
|||||||
void window_pane_resize(struct window_pane *, u_int, u_int);
|
void window_pane_resize(struct window_pane *, u_int, u_int);
|
||||||
void window_pane_clear_resizes(struct window_pane *,
|
void window_pane_clear_resizes(struct window_pane *,
|
||||||
struct window_pane_resize *);
|
struct window_pane_resize *);
|
||||||
|
void window_pane_defer_redraw(struct window_pane *);
|
||||||
|
void window_pane_finish_redraw(struct window_pane *);
|
||||||
int window_pane_set_mode(struct window_pane *,
|
int window_pane_set_mode(struct window_pane *,
|
||||||
struct window_pane *, const struct window_mode *,
|
struct window_pane *, const struct window_mode *,
|
||||||
struct cmd_find_state *, struct args *);
|
struct cmd_find_state *, struct args *);
|
||||||
|
|||||||
37
window.c
37
window.c
@@ -72,6 +72,7 @@ static struct window_pane *window_pane_create(struct window *, u_int, u_int,
|
|||||||
u_int);
|
u_int);
|
||||||
static void window_pane_destroy(struct window_pane *);
|
static void window_pane_destroy(struct window_pane *);
|
||||||
static void window_pane_scrollbar_timer(int, short, void *);
|
static void window_pane_scrollbar_timer(int, short, void *);
|
||||||
|
static void window_pane_redraw_timer(int, short, void *);
|
||||||
static void window_pane_full_size_offset(struct window_pane *wp,
|
static void window_pane_full_size_offset(struct window_pane *wp,
|
||||||
int *xoff, int *yoff, u_int *sx, u_int *sy);
|
int *xoff, int *yoff, u_int *sx, u_int *sy);
|
||||||
|
|
||||||
@@ -1234,6 +1235,8 @@ window_pane_destroy(struct window_pane *wp)
|
|||||||
|
|
||||||
if (event_initialized(&wp->resize_timer))
|
if (event_initialized(&wp->resize_timer))
|
||||||
event_del(&wp->resize_timer);
|
event_del(&wp->resize_timer);
|
||||||
|
if (event_initialized(&wp->redraw_timer))
|
||||||
|
event_del(&wp->redraw_timer);
|
||||||
if (event_initialized(&wp->sync_timer))
|
if (event_initialized(&wp->sync_timer))
|
||||||
event_del(&wp->sync_timer);
|
event_del(&wp->sync_timer);
|
||||||
if (event_initialized(&wp->sb_auto_timer))
|
if (event_initialized(&wp->sb_auto_timer))
|
||||||
@@ -1261,6 +1264,9 @@ window_pane_read_callback(__unused struct bufferevent *bufev, void *data)
|
|||||||
char *new_data;
|
char *new_data;
|
||||||
size_t new_size;
|
size_t new_size;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
int deferred;
|
||||||
|
|
||||||
|
deferred = (wp->flags & PANE_REDRAWDEFER);
|
||||||
|
|
||||||
if (wp->pipe_fd != -1) {
|
if (wp->pipe_fd != -1) {
|
||||||
new_data = window_pane_get_new_data(wp, wpo, &new_size);
|
new_data = window_pane_get_new_data(wp, wpo, &new_size);
|
||||||
@@ -1276,6 +1282,8 @@ window_pane_read_callback(__unused struct bufferevent *bufev, void *data)
|
|||||||
control_write_output(c, wp);
|
control_write_output(c, wp);
|
||||||
}
|
}
|
||||||
input_parse_pane(wp);
|
input_parse_pane(wp);
|
||||||
|
if (deferred)
|
||||||
|
window_pane_finish_redraw(wp);
|
||||||
bufferevent_disable(wp->event, EV_READ);
|
bufferevent_disable(wp->event, EV_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1320,6 +1328,35 @@ window_pane_clear_resizes(struct window_pane *wp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_pane_redraw_timer(__unused int fd, __unused short events, void *arg)
|
||||||
|
{
|
||||||
|
window_pane_finish_redraw(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_pane_defer_redraw(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct timeval tv = { .tv_usec = 50000 };
|
||||||
|
|
||||||
|
wp->flags |= PANE_REDRAWDEFER;
|
||||||
|
if (!event_initialized(&wp->redraw_timer))
|
||||||
|
evtimer_set(&wp->redraw_timer, window_pane_redraw_timer, wp);
|
||||||
|
evtimer_del(&wp->redraw_timer);
|
||||||
|
evtimer_add(&wp->redraw_timer, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_pane_finish_redraw(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (~wp->flags & PANE_REDRAWDEFER)
|
||||||
|
return;
|
||||||
|
evtimer_del(&wp->redraw_timer);
|
||||||
|
wp->flags &= ~PANE_REDRAWDEFER;
|
||||||
|
wp->flags |= PANE_REDRAW;
|
||||||
|
server_redraw_window(wp->window);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user