mirror of
https://github.com/tmux/tmux.git
synced 2024-11-16 09:28:51 +00:00
Because we defer actually resizing applications (calling TIOCSWINSZ)
until the end of the server loop, tmux may have gone through several internal resizes in between. This can be a problem if the final size is the same as the initial size (what the application things it currently is), because the application may choose not to redraw, assuming the screen state is unchanged, when in fact tmux has thrown away parts of the screen, assuming the application will redraw them. To avoid this, do an extra resize if the new size is the same size as the initial size. This should force the application to redraw when tmux needs it to, while retaining the benefits of deferring (so we now resize at most two times instead of at most one - and only two very rarely). Fixes a problem with break-pane and zoomed panes reported by Michal Mazurek.
This commit is contained in:
parent
7eb496c00c
commit
80c6b487dc
@ -1050,14 +1050,36 @@ server_client_resize_event(__unused int fd, __unused short events, void *data)
|
|||||||
if (!(wp->flags & PANE_RESIZE))
|
if (!(wp->flags & PANE_RESIZE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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->sx == wp->osx &&
|
||||||
|
wp->sy == wp->osy &&
|
||||||
|
wp->sx > 1 &&
|
||||||
|
wp->sy > 1) {
|
||||||
|
memset(&ws, 0, sizeof ws);
|
||||||
|
ws.ws_col = wp->sx - 1;
|
||||||
|
ws.ws_row = wp->sy - 1;
|
||||||
|
if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
||||||
|
fatal("ioctl failed");
|
||||||
|
log_debug("%s: %%%u forcing resize", __func__, wp->id);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&ws, 0, sizeof ws);
|
memset(&ws, 0, sizeof ws);
|
||||||
ws.ws_col = wp->sx;
|
ws.ws_col = wp->sx;
|
||||||
ws.ws_row = wp->sy;
|
ws.ws_row = wp->sy;
|
||||||
|
|
||||||
if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
||||||
fatal("ioctl failed");
|
fatal("ioctl failed");
|
||||||
|
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
|
||||||
|
|
||||||
wp->flags &= ~PANE_RESIZE;
|
wp->flags &= ~PANE_RESIZE;
|
||||||
|
|
||||||
|
wp->osx = wp->sx;
|
||||||
|
wp->osy = wp->sy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if pane should be resized. */
|
/* Check if pane should be resized. */
|
||||||
@ -1068,6 +1090,7 @@ server_client_check_resize(struct window_pane *wp)
|
|||||||
|
|
||||||
if (!(wp->flags & PANE_RESIZE))
|
if (!(wp->flags & PANE_RESIZE))
|
||||||
return;
|
return;
|
||||||
|
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
|
||||||
|
|
||||||
if (!event_initialized(&wp->resize_timer))
|
if (!event_initialized(&wp->resize_timer))
|
||||||
evtimer_set(&wp->resize_timer, server_client_resize_event, wp);
|
evtimer_set(&wp->resize_timer, server_client_resize_event, wp);
|
||||||
|
3
tmux.h
3
tmux.h
@ -745,6 +745,9 @@ struct window_pane {
|
|||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
|
u_int osx;
|
||||||
|
u_int osy;
|
||||||
|
|
||||||
u_int xoff;
|
u_int xoff;
|
||||||
u_int yoff;
|
u_int yoff;
|
||||||
|
|
||||||
|
4
window.c
4
window.c
@ -800,8 +800,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
wp->xoff = 0;
|
wp->xoff = 0;
|
||||||
wp->yoff = 0;
|
wp->yoff = 0;
|
||||||
|
|
||||||
wp->sx = sx;
|
wp->sx = wp->osx = sx;
|
||||||
wp->sy = sy;
|
wp->sy = wp->osx = sy;
|
||||||
|
|
||||||
wp->pipe_fd = -1;
|
wp->pipe_fd = -1;
|
||||||
wp->pipe_off = 0;
|
wp->pipe_off = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user