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.
This commit is contained in:
nicm 2020-05-16 16:50:55 +00:00
parent 844b363baf
commit 574a9e4b6c
6 changed files with 98 additions and 66 deletions

View File

@ -18,7 +18,6 @@
#include <sys/types.h>
#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>

View File

@ -27,7 +27,7 @@
#include "tmux.h"
/*
* Show client message log.
* Show message log.
*/
#define SHOW_MESSAGES_TEMPLATE \

View File

@ -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

View File

@ -33,8 +33,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 *);
@ -1035,14 +1036,14 @@ have_event:
out:
/* Apply modifiers if any. */
if (b & MOUSE_MASK_META)
key |= KEYC_ESCAPE;
key |= KEYC_META;
if (b & MOUSE_MASK_CTRL)
key |= KEYC_CTRL;
if (b & MOUSE_MASK_SHIFT)
key |= KEYC_SHIFT;
if (log_get_level() != 0)
log_debug("mouse key is %s", key_string_lookup_key (key));
log_debug("mouse key is %s", key_string_lookup_key (key, 1));
return (key);
}
@ -1174,7 +1175,7 @@ table_changed:
* The prefix always takes precedence and forces a switch to the prefix
* table, unless we are already there.
*/
key0 = (key & ~KEYC_XTERM);
key0 = (key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS));
if ((key0 == (key_code)options_get_number(s->options, "prefix") ||
key0 == (key_code)options_get_number(s->options, "prefix2")) &&
strcmp(table->name, "prefix") != 0) {
@ -1341,10 +1342,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) {
@ -1356,34 +1360,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;
}
@ -1391,6 +1375,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)
@ -1472,7 +1476,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;
@ -1490,7 +1494,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;

57
tmux.h
View File

@ -112,25 +112,31 @@ struct winlink;
#define VISUAL_BOTH 2
/* Special key codes. */
#define KEYC_NONE 0x00ff000000000ULL
#define KEYC_UNKNOWN 0x00fe000000000ULL
#define KEYC_BASE 0x0001000000000ULL
#define KEYC_USER 0x0002000000000ULL
#define KEYC_NONE 0x00ff000000000ULL
#define KEYC_UNKNOWN 0x00fe000000000ULL
#define KEYC_BASE 0x0001000000000ULL
#define KEYC_USER 0x0002000000000ULL
/* Key modifier bits. */
#define KEYC_ESCAPE 0x0100000000000ULL
#define KEYC_CTRL 0x0200000000000ULL
#define KEYC_SHIFT 0x0400000000000ULL
#define KEYC_XTERM 0x0800000000000ULL
#define KEYC_LITERAL 0x1000000000000ULL
#define KEYC_META 0x00100000000000ULL
#define KEYC_CTRL 0x00200000000000ULL
#define KEYC_SHIFT 0x00400000000000ULL
/* Key flag bits. */
#define KEYC_LITERAL 0x01000000000000ULL
#define KEYC_KEYPAD 0x02000000000000ULL
#define KEYC_CURSOR 0x04000000000000ULL
#define KEYC_IMPLIED_META 0x08000000000000ULL
#define KEYC_BUILD_MODIFIERS 0x10000000000000ULL
/* Masks for key bits. */
#define KEYC_MASK_MODIFIERS 0x00f00000000000ULL
#define KEYC_MASK_FLAGS 0xff000000000000ULL
#define KEYC_MASK_KEY 0x000fffffffffffULL
/* Available user keys. */
#define KEYC_NUSER 1000
/* Mask to obtain key w/o modifiers. */
#define KEYC_MASK_MOD 0xff00000000000ULL
#define KEYC_MASK_KEY 0x00fffffffffffULL
/* Is this a mouse key? */
#define KEYC_IS_MOUSE(key) (((key) & KEYC_MASK_KEY) >= KEYC_MOUSE && \
((key) & KEYC_MASK_KEY) < KEYC_BSPACE)
@ -284,6 +290,7 @@ enum tty_code_code {
TTYC_DL,
TTYC_DL1,
TTYC_DSBP,
TTYC_DSEKS,
TTYC_DSFCS,
TTYC_DSMG,
TTYC_E3,
@ -293,6 +300,7 @@ enum tty_code_code {
TTYC_EL1,
TTYC_ENACS,
TTYC_ENBP,
TTYC_ENEKS,
TTYC_ENFCS,
TTYC_ENMG,
TTYC_FSL,
@ -569,8 +577,8 @@ struct msg_write_close {
#define MODE_CURSOR 0x1
#define MODE_INSERT 0x2
#define MODE_KCURSOR 0x4
#define MODE_KKEYPAD 0x8 /* set = application, clear = number */
#define MODE_WRAP 0x10 /* whether lines wrap */
#define MODE_KKEYPAD 0x8
#define MODE_WRAP 0x10
#define MODE_MOUSE_STANDARD 0x20
#define MODE_MOUSE_BUTTON 0x40
#define MODE_BLINKING 0x80
@ -581,6 +589,7 @@ struct msg_write_close {
#define MODE_MOUSE_ALL 0x1000
#define MODE_ORIGIN 0x2000
#define MODE_CRLF 0x4000
#define MODE_KEXTENDED 0x8000
#define ALL_MODES 0xffffff
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
@ -1001,12 +1010,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;
@ -1278,7 +1293,7 @@ struct tty {
/* 0x8 unused */
#define TTY_STARTED 0x10
#define TTY_OPENED 0x20
#define TTY_FOCUS 0x40
/* 0x40 unused */
#define TTY_BLOCK 0x80
#define TTY_HAVEDA 0x100
#define TTY_HAVEXDA 0x200
@ -2282,7 +2297,7 @@ struct cmdq_item *key_bindings_dispatch(struct key_binding *,
/* key-string.c */
key_code key_string_lookup_string(const char *);
const char *key_string_lookup_key(key_code);
const char *key_string_lookup_key(key_code, int);
/* alerts.c */
void alerts_reset_all(void);
@ -2415,16 +2430,12 @@ void input_parse_screen(struct input_ctx *, struct screen *,
screen_write_init_ctx_cb, void *, u_char *, size_t);
/* input-key.c */
void input_key_build(void);
int input_key_pane(struct window_pane *, key_code, struct mouse_event *);
int input_key(struct window_pane *, struct screen *, struct bufferevent *,
key_code);
int input_key(struct screen *, struct bufferevent *, key_code);
int input_key_get_mouse(struct screen *, struct mouse_event *, u_int,
u_int, const char **, size_t *);
/* xterm-keys.c */
char *xterm_keys_lookup(key_code);
int xterm_keys_find(const char *, size_t, size_t *, key_code *);
/* colour.c */
int colour_find_rgb(u_char, u_char, u_char);
int colour_join_rgb(u_char, u_char, u_char);

View File

@ -440,13 +440,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)
@ -991,7 +993,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);
}
@ -1135,8 +1136,10 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
wme = TAILQ_FIRST(&wp->modes);
if (wme != NULL) {
if (wme->mode->key != NULL && c != NULL)
wme->mode->key(wme, c, s, wl, (key & ~KEYC_XTERM), m);
if (wme->mode->key != NULL && c != NULL) {
key &= ~KEYC_MASK_FLAGS;
wme->mode->key(wme, c, s, wl, key, m);
}
return (0);
}