diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2016-09-28 08:30:45 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2016-09-28 08:30:45 +0000 |
commit | a65bec40aaa8485cbaa570ecebfbace7f1b46498 (patch) | |
tree | 3db4b0bce79cc955b7da66341d389a6eabae7858 /usr.bin | |
parent | 89812eb9ff93d2b5d79583d55e9a7e78905fd24a (diff) |
Rate limit TIOCSWINSZ on a timer to avoid programs getting hammered with
SIGWINCH when the size changes rapidly. To help a problem reported by
Rui Pinheiro.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/server-client.c | 42 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 | ||||
-rw-r--r-- | usr.bin/tmux/window.c | 5 |
3 files changed, 44 insertions, 7 deletions
diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index e71b62682ba..288b5137185 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.187 2016/06/16 10:55:47 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.188 2016/09/28 08:30:44 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -765,11 +765,13 @@ server_client_loop(void) } } -/* Check if pane should be resized. */ -void -server_client_check_resize(struct window_pane *wp) +static void +server_client_resize_event(__unused int fd, __unused short events, void *data) { - struct winsize ws; + struct window_pane *wp = data; + struct winsize ws; + + evtimer_del(&wp->resize_timer); if (!(wp->flags & PANE_RESIZE)) return; @@ -784,6 +786,36 @@ server_client_check_resize(struct window_pane *wp) wp->flags &= ~PANE_RESIZE; } +/* Check if pane should be resized. */ +void +server_client_check_resize(struct window_pane *wp) +{ + struct timeval tv = { .tv_usec = 250000 }; + + if (!(wp->flags & PANE_RESIZE)) + return; + + if (!event_initialized(&wp->resize_timer)) + evtimer_set(&wp->resize_timer, server_client_resize_event, wp); + + /* + * The first resize should happen immediately, so if the timer is not + * running, do it now. + */ + if (!evtimer_pending(&wp->resize_timer, NULL)) + server_client_resize_event(-1, 0, wp); + + /* + * If the pane is in the alternate screen, let the timer expire and + * resize to give the application a chance to redraw. If not, keep + * pushing the timer back. + */ + if (wp->saved_grid != NULL && evtimer_pending(&wp->resize_timer, NULL)) + return; + evtimer_del(&wp->resize_timer); + evtimer_add(&wp->resize_timer, &tv); +} + /* Check whether pane should be focused. */ void server_client_check_focus(struct window_pane *wp) diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 8c0afd61f55..4f98691881c 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.645 2016/09/16 13:43:41 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.646 2016/09/28 08:30:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -894,6 +894,8 @@ struct window_pane { int fd; struct bufferevent *event; + struct event resize_timer; + u_int wmark_size; u_int wmark_hits; diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c index d93bca664c1..125c19df3b4 100644 --- a/usr.bin/tmux/window.c +++ b/usr.bin/tmux/window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.166 2016/09/16 13:43:41 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.167 2016/09/28 08:30:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -803,6 +803,9 @@ window_pane_destroy(struct window_pane *wp) close(wp->pipe_fd); } + if (event_initialized(&wp->resize_timer)) + event_del(&wp->resize_timer); + RB_REMOVE(window_pane_tree, &all_window_panes, wp); free((void *)wp->cwd); |