mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Change how panes are resized so that the code is clearer and if the pane
is resized multiple times during one event loop, it is forced to resize at the end. Also don't zoom/unzoom in switch-client if the pane hasn't changed. GitHub issue 2260.
This commit is contained in:
parent
03b2998abe
commit
d919fa1ed0
@ -116,7 +116,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||
} else {
|
||||
if (cmdq_get_client(item) == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (wl != NULL && wp != NULL) {
|
||||
if (wl != NULL && wp != NULL && wp != wl->window->active) {
|
||||
w = wl->window;
|
||||
if (window_push_zoom(w, args_has(args, 'Z')))
|
||||
server_redraw_window(w);
|
||||
|
122
server-client.c
122
server-client.c
@ -45,7 +45,6 @@ static void server_client_check_redraw(struct client *);
|
||||
static void server_client_set_title(struct client *);
|
||||
static void server_client_reset_state(struct client *);
|
||||
static int server_client_assume_paste(struct session *);
|
||||
static void server_client_resize_event(int, short, void *);
|
||||
|
||||
static void server_client_dispatch(struct imsg *, void *);
|
||||
static void server_client_dispatch_command(struct client *, struct imsg *);
|
||||
@ -1403,50 +1402,14 @@ server_client_check_window_resize(struct window *w)
|
||||
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)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 100000 };
|
||||
|
||||
/*
|
||||
* If we are resizing to the same size as when we entered the loop
|
||||
* (that is, to the same size the application currently thinks it is),
|
||||
* tmux may have gone through several resizes internally and thrown
|
||||
* away parts of the screen. So we need the application to actually
|
||||
* redraw even though its final size has not changed.
|
||||
*/
|
||||
|
||||
if (wp->flags & PANE_RESIZEFORCE) {
|
||||
wp->flags &= ~PANE_RESIZEFORCE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (wp->sx != wp->osx ||
|
||||
wp->sy != wp->osy ||
|
||||
wp->sx <= 1 ||
|
||||
wp->sy <= 1)
|
||||
return (0);
|
||||
|
||||
log_debug("%s: %%%u forcing resize", __func__, wp->id);
|
||||
window_pane_send_resize(wp, -1);
|
||||
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
wp->flags |= PANE_RESIZEFORCE;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Resize a pane. */
|
||||
/* Resize timer event. */
|
||||
static void
|
||||
server_client_resize_pane(struct window_pane *wp)
|
||||
server_client_resize_timer(__unused int fd, __unused short events, void *data)
|
||||
{
|
||||
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
|
||||
window_pane_send_resize(wp, 0);
|
||||
struct window_pane *wp = data;
|
||||
|
||||
wp->flags &= ~PANE_RESIZE;
|
||||
|
||||
wp->osx = wp->sx;
|
||||
wp->osy = wp->sy;
|
||||
log_debug("%s: %%%u resize timer expired", __func__, wp->id);
|
||||
evtimer_del(&wp->resize_timer);
|
||||
}
|
||||
|
||||
/* Start the resize timer. */
|
||||
@ -1455,49 +1418,74 @@ server_client_start_resize_timer(struct window_pane *wp)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 250000 };
|
||||
|
||||
if (!evtimer_pending(&wp->resize_timer, NULL))
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
log_debug("%s: %%%u resize timer started", __func__, wp->id);
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
}
|
||||
|
||||
/* Resize timer event. */
|
||||
/* Force timer event. */
|
||||
static void
|
||||
server_client_resize_event(__unused int fd, __unused short events, void *data)
|
||||
server_client_force_timer(__unused int fd, __unused short events, void *data)
|
||||
{
|
||||
struct window_pane *wp = data;
|
||||
|
||||
evtimer_del(&wp->resize_timer);
|
||||
log_debug("%s: %%%u force timer expired", __func__, wp->id);
|
||||
evtimer_del(&wp->force_timer);
|
||||
wp->flags |= PANE_RESIZENOW;
|
||||
}
|
||||
|
||||
if (~wp->flags & PANE_RESIZE)
|
||||
return;
|
||||
log_debug("%s: %%%u timer fired (was%s resized)", __func__, wp->id,
|
||||
(wp->flags & PANE_RESIZED) ? "" : " not");
|
||||
/* Start the force timer. */
|
||||
static void
|
||||
server_client_start_force_timer(struct window_pane *wp)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 10000 };
|
||||
|
||||
if (wp->base.saved_grid == NULL && (wp->flags & PANE_RESIZED)) {
|
||||
log_debug("%s: %%%u deferring timer", __func__, wp->id);
|
||||
server_client_start_resize_timer(wp);
|
||||
} else if (!server_client_resize_force(wp)) {
|
||||
log_debug("%s: %%%u resizing pane", __func__, wp->id);
|
||||
server_client_resize_pane(wp);
|
||||
}
|
||||
wp->flags &= ~PANE_RESIZED;
|
||||
log_debug("%s: %%%u force timer started", __func__, wp->id);
|
||||
evtimer_add(&wp->force_timer, &tv);
|
||||
}
|
||||
|
||||
/* Check if pane should be resized. */
|
||||
static void
|
||||
server_client_check_pane_resize(struct window_pane *wp)
|
||||
{
|
||||
if (!event_initialized(&wp->resize_timer))
|
||||
evtimer_set(&wp->resize_timer, server_client_resize_timer, wp);
|
||||
if (!event_initialized(&wp->force_timer))
|
||||
evtimer_set(&wp->force_timer, server_client_force_timer, wp);
|
||||
|
||||
if (~wp->flags & PANE_RESIZE)
|
||||
return;
|
||||
log_debug("%s: %%%u needs to be resized", __func__, wp->id);
|
||||
|
||||
if (!event_initialized(&wp->resize_timer))
|
||||
evtimer_set(&wp->resize_timer, server_client_resize_event, wp);
|
||||
if (evtimer_pending(&wp->resize_timer, NULL)) {
|
||||
log_debug("%s: %%%u resize timer is running", __func__, wp->id);
|
||||
return;
|
||||
}
|
||||
server_client_start_resize_timer(wp);
|
||||
|
||||
if (!evtimer_pending(&wp->resize_timer, NULL)) {
|
||||
log_debug("%s: %%%u starting timer", __func__, wp->id);
|
||||
server_client_resize_pane(wp);
|
||||
server_client_start_resize_timer(wp);
|
||||
} else
|
||||
log_debug("%s: %%%u timer running", __func__, wp->id);
|
||||
if (~wp->flags & PANE_RESIZEFORCE) {
|
||||
/*
|
||||
* The timer is not running and we don't need to force a
|
||||
* resize, so just resize immediately.
|
||||
*/
|
||||
log_debug("%s: resizing %%%u now", __func__, wp->id);
|
||||
window_pane_send_resize(wp, 0);
|
||||
wp->flags &= ~PANE_RESIZE;
|
||||
} else {
|
||||
/*
|
||||
* The timer is not running, but we need to force a resize. If
|
||||
* the force timer has expired, resize to the real size now.
|
||||
* Otherwise resize to the force size and start the timer.
|
||||
*/
|
||||
if (wp->flags & PANE_RESIZENOW) {
|
||||
log_debug("%s: resizing %%%u after forced resize", __func__, wp->id);
|
||||
window_pane_send_resize(wp, 0);
|
||||
wp->flags &= ~(PANE_RESIZE|PANE_RESIZEFORCE|PANE_RESIZENOW);
|
||||
} else if (!evtimer_pending(&wp->force_timer, NULL)) {
|
||||
log_debug("%s: forcing resize of %%%u", __func__, wp->id);
|
||||
window_pane_send_resize(wp, 1);
|
||||
server_client_start_force_timer(wp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check pane buffer size. */
|
||||
|
6
tmux.h
6
tmux.h
@ -928,9 +928,6 @@ struct window_pane {
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
|
||||
u_int osx;
|
||||
u_int osy;
|
||||
|
||||
u_int xoff;
|
||||
u_int yoff;
|
||||
|
||||
@ -951,7 +948,7 @@ struct window_pane {
|
||||
#define PANE_STATUSDRAWN 0x400
|
||||
#define PANE_EMPTY 0x800
|
||||
#define PANE_STYLECHANGED 0x1000
|
||||
#define PANE_RESIZED 0x2000
|
||||
#define PANE_RESIZENOW 0x2000
|
||||
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -969,6 +966,7 @@ struct window_pane {
|
||||
size_t base_offset;
|
||||
|
||||
struct event resize_timer;
|
||||
struct event force_timer;
|
||||
|
||||
struct input_ctx *ictx;
|
||||
|
||||
|
26
window.c
26
window.c
@ -436,14 +436,21 @@ window_resize(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
||||
}
|
||||
|
||||
void
|
||||
window_pane_send_resize(struct window_pane *wp, int yadjust)
|
||||
window_pane_send_resize(struct window_pane *wp, int force)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct winsize ws;
|
||||
u_int sy = wp->sy + yadjust;
|
||||
u_int sy;
|
||||
|
||||
if (wp->fd == -1)
|
||||
return;
|
||||
|
||||
if (!force)
|
||||
sy = wp->sy;
|
||||
else if (wp->sy <= 1)
|
||||
sy = wp->sy + 1;
|
||||
else
|
||||
sy = wp->sy - 1;
|
||||
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, sy);
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
@ -877,8 +884,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
||||
wp->xoff = 0;
|
||||
wp->yoff = 0;
|
||||
|
||||
wp->sx = wp->osx = sx;
|
||||
wp->sy = wp->osx = sy;
|
||||
wp->sx = sx;
|
||||
wp->sy = sy;
|
||||
|
||||
wp->pipe_fd = -1;
|
||||
wp->pipe_event = NULL;
|
||||
@ -918,6 +925,8 @@ window_pane_destroy(struct window_pane *wp)
|
||||
|
||||
if (event_initialized(&wp->resize_timer))
|
||||
event_del(&wp->resize_timer);
|
||||
if (event_initialized(&wp->force_timer))
|
||||
event_del(&wp->force_timer);
|
||||
|
||||
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
|
||||
|
||||
@ -998,7 +1007,14 @@ 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);
|
||||
|
||||
/*
|
||||
* If the pane has already been resized, set the force flag and make
|
||||
* the application resize twice to force it to redraw.
|
||||
*/
|
||||
if (wp->flags & PANE_RESIZE)
|
||||
wp->flags |= PANE_RESIZEFORCE;
|
||||
wp->flags |= PANE_RESIZE;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user