From 57fe03dc5a132ee131de457afa5724ec735ae811 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 16 May 2020 14:57:36 +0100 Subject: [PATCH] Move lazy resize from the pane to the window, there is no point in resizing the window unless it is the current window, and if we do and don't resize the pane until later there are problems if the size changes from A to B then back to A. --- resize.c | 25 ++++++++++++++++---- server-client.c | 62 ++++++++++++++++++++++++++----------------------- tmux.h | 6 +++++ window.c | 5 ++-- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/resize.c b/resize.c index 15d146d8..68717e35 100644 --- a/resize.c +++ b/resize.c @@ -61,6 +61,7 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel) tty_update_window_offset(w); server_redraw_window(w); notify_window("window-layout-changed", w); + w->flags &= ~WINDOW_RESIZE; } static int @@ -346,16 +347,30 @@ recalculate_size(struct window *w) changed = 0; break; } - if (changed && w->sx == sx && w->sy == sy) - changed = 0; + if (w->flags & WINDOW_RESIZE) { + if (changed && w->new_sx == sx && w->new_sy == sy) + changed = 0; + } else { + if (changed && w->sx == sx && w->sy == sy) + changed = 0; + } if (!changed) { tty_update_window_offset(w); return; } - log_debug("%s: @%u changed to %u,%u (%ux%u)", __func__, w->id, sx, sy, - xpixel, ypixel); - resize_window(w, sx, sy, xpixel, ypixel); + log_debug("%s: @%u new size %u,%u", __func__, w->id, sx, sy); + if (type == WINDOW_SIZE_MANUAL) + resize_window(w, sx, sy, xpixel, ypixel); + else { + w->new_sx = sx; + w->new_sy = sy; + w->new_xpixel = xpixel; + w->new_ypixel = ypixel; + + w->flags |= WINDOW_RESIZE; + tty_update_window_offset(w); + } } void diff --git a/server-client.c b/server-client.c index 87a4f533..24a564c0 100644 --- a/server-client.c +++ b/server-client.c @@ -31,8 +31,9 @@ #include "tmux.h" static void server_client_free(int, short, void *); -static void server_client_check_focus(struct window_pane *); -static void server_client_check_resize(struct window_pane *); +static void server_client_check_pane_focus(struct window_pane *); +static void server_client_check_pane_resize(struct window_pane *); +static void server_client_check_window_resize(struct window *); static key_code server_client_check_mouse(struct client *, struct key_event *); static void server_client_repeat_timer(int, short, void *); static void server_client_click_timer(int, short, void *); @@ -1339,10 +1340,13 @@ server_client_loop(void) struct client *c; struct window *w; struct window_pane *wp; - struct winlink *wl; - struct session *s; - int focus, attached, resize; + int focus; + /* Check for window resize. This is done before redrawing. */ + RB_FOREACH(w, windows, &windows) + server_client_check_window_resize(w); + + /* Check clients. */ TAILQ_FOREACH(c, &clients, entry) { server_client_check_exit(c); if (c->session != NULL) { @@ -1354,34 +1358,14 @@ server_client_loop(void) /* * Any windows will have been redrawn as part of clients, so clear * their flags now. Also check pane focus and resize. - * - * As an optimization, panes in windows that are in an attached session - * but not the current window are not resized (this reduces the amount - * of work needed when, for example, resizing an X terminal a - * lot). Windows in no attached session are resized immediately since - * that is likely to have come from a command like split-window and be - * what the user wanted. */ focus = options_get_number(global_options, "focus-events"); RB_FOREACH(w, windows, &windows) { - attached = resize = 0; - TAILQ_FOREACH(wl, &w->winlinks, wentry) { - s = wl->session; - if (s->attached != 0) - attached = 1; - if (s->attached != 0 && s->curw == wl) { - resize = 1; - break; - } - } - if (!attached) - resize = 1; TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->fd != -1) { if (focus) - server_client_check_focus(wp); - if (resize) - server_client_check_resize(wp); + server_client_check_pane_focus(wp); + server_client_check_pane_resize(wp); } wp->flags &= ~PANE_REDRAW; } @@ -1389,6 +1373,26 @@ server_client_loop(void) } } +/* Check if window needs to be resized. */ +static void +server_client_check_window_resize(struct window *w) +{ + struct winlink *wl; + + if (~w->flags & WINDOW_RESIZE) + return; + + TAILQ_FOREACH(wl, &w->winlinks, wentry) { + if (wl->session->attached != 0 && wl->session->curw == wl) + break; + } + if (wl == NULL) + return; + + log_debug("%s: resizing window @%u", __func__, w->id); + resize_window(w, w->new_sx, w->new_sy, w->new_xpixel, w->new_ypixel); +} + /* Check if we need to force a resize. */ static int server_client_resize_force(struct window_pane *wp) @@ -1470,7 +1474,7 @@ server_client_resize_event(__unused int fd, __unused short events, void *data) /* Check if pane should be resized. */ static void -server_client_check_resize(struct window_pane *wp) +server_client_check_pane_resize(struct window_pane *wp) { if (~wp->flags & PANE_RESIZE) return; @@ -1488,7 +1492,7 @@ server_client_check_resize(struct window_pane *wp) /* Check whether pane should be focused. */ static void -server_client_check_focus(struct window_pane *wp) +server_client_check_pane_focus(struct window_pane *wp) { struct client *c; int push; diff --git a/tmux.h b/tmux.h index 65164ccc..a9786990 100644 --- a/tmux.h +++ b/tmux.h @@ -1012,12 +1012,18 @@ struct window { u_int xpixel; u_int ypixel; + u_int new_sx; + u_int new_sy; + u_int new_xpixel; + u_int new_ypixel; + int flags; #define WINDOW_BELL 0x1 #define WINDOW_ACTIVITY 0x2 #define WINDOW_SILENCE 0x4 #define WINDOW_ZOOMED 0x8 #define WINDOW_WASZOOMED 0x10 +#define WINDOW_RESIZE 0x20 #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) int alerts_queued; diff --git a/window.c b/window.c index 7cb098dd..b35ab8ab 100644 --- a/window.c +++ b/window.c @@ -438,13 +438,15 @@ window_pane_send_resize(struct window_pane *wp, int yadjust) { struct window *w = wp->window; struct winsize ws; + u_int sy = wp->sy + yadjust; if (wp->fd == -1) return; + log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, sy); memset(&ws, 0, sizeof ws); ws.ws_col = wp->sx; - ws.ws_row = wp->sy + yadjust; + ws.ws_row = sy; ws.ws_xpixel = w->xpixel * ws.ws_col; ws.ws_ypixel = w->ypixel * ws.ws_row; if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) @@ -1001,7 +1003,6 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy) wme = TAILQ_FIRST(&wp->modes); if (wme != NULL && wme->mode->resize != NULL) wme->mode->resize(wme, sx, sy); - wp->flags |= (PANE_RESIZE|PANE_RESIZED); }