diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index 6dc0f2a8..cc661163 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -31,8 +31,8 @@ const struct cmd_entry cmd_rotate_window_entry = { .name = "rotate-window", .alias = "rotatew", - .args = { "Dt:U", 0, 0 }, - .usage = "[-DU] " CMD_TARGET_WINDOW_USAGE, + .args = { "Dt:UZ", 0, 0 }, + .usage = "[-DUZ] " CMD_TARGET_WINDOW_USAGE, .target = { 't', CMD_FIND_WINDOW, 0 }, @@ -50,7 +50,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) struct layout_cell *lc; u_int sx, sy, xoff, yoff; - server_unzoom_window(w); + window_push_zoom(w, args_has(self->args, 'Z')); if (args_has(self->args, 'D')) { wp = TAILQ_LAST(&w->panes, window_panes); @@ -77,9 +77,6 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) wp = TAILQ_LAST(&w->panes, window_panes); - window_set_active_pane(w, wp, 1); - cmd_find_from_winlink_pane(current, wl, wp, 0); - server_redraw_window(w); } else { wp = TAILQ_FIRST(&w->panes); TAILQ_REMOVE(&w->panes, wp, entry); @@ -105,10 +102,12 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) wp = TAILQ_FIRST(&w->panes); - window_set_active_pane(w, wp, 1); - cmd_find_from_winlink_pane(current, wl, wp, 0); - server_redraw_window(w); } + window_set_active_pane(w, wp, 1); + cmd_find_from_winlink_pane(current, wl, wp, 0); + window_pop_zoom(w); + server_redraw_window(w); + return (CMD_RETURN_NORMAL); } diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 52c58dbc..15f76afe 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -33,8 +33,8 @@ const struct cmd_entry cmd_select_pane_entry = { .name = "select-pane", .alias = "selectp", - .args = { "DdegLlMmP:RT:t:U", 0, 0 }, /* -P and -g deprecated */ - .usage = "[-DdeLlMmRU] [-T title] " CMD_TARGET_PANE_USAGE, + .args = { "DdegLlMmP:RT:t:UZ", 0, 0 }, /* -P and -g deprecated */ + .usage = "[-DdeLlMmRUZ] [-T title] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, @@ -46,8 +46,8 @@ const struct cmd_entry cmd_last_pane_entry = { .name = "last-pane", .alias = "lastp", - .args = { "det:", 0, 0 }, - .usage = "[-de] " CMD_TARGET_WINDOW_USAGE, + .args = { "det:Z", 0, 0 }, + .usage = "[-deZ] " CMD_TARGET_WINDOW_USAGE, .target = { 't', CMD_FIND_WINDOW, 0 }, @@ -111,12 +111,15 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) else if (args_has(self->args, 'd')) lastwp->flags |= PANE_INPUTOFF; else { - server_unzoom_window(w); + if (window_push_zoom(w, args_has(self->args, 'Z'))) + server_redraw_window(w); window_redraw_active_switch(w, lastwp); if (window_set_active_pane(w, lastwp, 1)) { cmd_find_from_winlink(current, wl, 0); cmd_select_pane_redraw(w); } + if (window_pop_zoom(w)) + server_redraw_window(w); } return (CMD_RETURN_NORMAL); } @@ -161,17 +164,21 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) } if (args_has(self->args, 'L')) { - server_unzoom_window(wp->window); + window_push_zoom(w, 1); wp = window_pane_find_left(wp); + window_pop_zoom(w); } else if (args_has(self->args, 'R')) { - server_unzoom_window(wp->window); + window_push_zoom(w, 1); wp = window_pane_find_right(wp); + window_pop_zoom(w); } else if (args_has(self->args, 'U')) { - server_unzoom_window(wp->window); + window_push_zoom(w, 1); wp = window_pane_find_up(wp); + window_pop_zoom(w); } else if (args_has(self->args, 'D')) { - server_unzoom_window(wp->window); + window_push_zoom(w, 1); wp = window_pane_find_down(wp); + window_pop_zoom(w); } if (wp == NULL) return (CMD_RETURN_NORMAL); @@ -196,13 +203,16 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (wp == w->active) return (CMD_RETURN_NORMAL); - server_unzoom_window(wp->window); + if (window_push_zoom(w, args_has(self->args, 'Z'))) + server_redraw_window(w); window_redraw_active_switch(w, wp); if (window_set_active_pane(w, wp, 1)) { cmd_find_from_winlink_pane(current, wl, wp, 0); cmdq_insert_hook(s, item, current, "after-select-pane"); cmd_select_pane_redraw(w); } + if (window_pop_zoom(w)) + server_redraw_window(w); return (CMD_RETURN_NORMAL); } diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index 994ad0e8..3e0e6e60 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -32,8 +32,8 @@ const struct cmd_entry cmd_swap_pane_entry = { .name = "swap-pane", .alias = "swapp", - .args = { "dDs:t:U", 0, 0 }, - .usage = "[-dDU] " CMD_SRCDST_PANE_USAGE, + .args = { "dDs:t:UZ", 0, 0 }, + .usage = "[-dDUZ] " CMD_SRCDST_PANE_USAGE, .source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED }, .target = { 't', CMD_FIND_PANE, 0 }, @@ -45,6 +45,7 @@ const struct cmd_entry cmd_swap_pane_entry = { static enum cmd_retval cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) { + struct args *args = self->args; struct window *src_w, *dst_w; struct window_pane *tmp_wp, *src_wp, *dst_wp; struct layout_cell *src_lc, *dst_lc; @@ -54,23 +55,27 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) dst_wp = item->target.wp; src_w = item->source.wl->window; src_wp = item->source.wp; - server_unzoom_window(dst_w); - if (args_has(self->args, 'D')) { + if (window_push_zoom(dst_w, args_has(args, 'Z'))) + server_redraw_window(dst_w); + + if (args_has(args, 'D')) { src_w = dst_w; src_wp = TAILQ_NEXT(dst_wp, entry); if (src_wp == NULL) src_wp = TAILQ_FIRST(&dst_w->panes); - } else if (args_has(self->args, 'U')) { + } else if (args_has(args, 'U')) { src_w = dst_w; src_wp = TAILQ_PREV(dst_wp, window_panes, entry); if (src_wp == NULL) src_wp = TAILQ_LAST(&dst_w->panes, window_panes); } - server_unzoom_window(src_w); + + if (src_w != dst_w && window_push_zoom(src_w, args_has(args, 'Z'))) + server_redraw_window(src_w); if (src_wp == dst_wp) - return (CMD_RETURN_NORMAL); + goto out; tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry); TAILQ_REMOVE(&dst_w->panes, dst_wp, entry); @@ -103,7 +108,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) dst_wp->xoff = xoff; dst_wp->yoff = yoff; window_pane_resize(dst_wp, sx, sy); - if (!args_has(self->args, 'd')) { + if (!args_has(args, 'd')) { if (src_w != dst_w) { window_set_active_pane(src_w, dst_wp, 1); window_set_active_pane(dst_w, src_wp, 1); @@ -126,5 +131,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) server_redraw_window(src_w); server_redraw_window(dst_w); +out: + if (window_pop_zoom(src_w)) + server_redraw_window(src_w); + if (src_w != dst_w && window_pop_zoom(dst_w)) + server_redraw_window(dst_w); return (CMD_RETURN_NORMAL); } diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 8f51d0fe..309a7e7c 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -34,8 +34,8 @@ const struct cmd_entry cmd_switch_client_entry = { .name = "switch-client", .alias = "switchc", - .args = { "lc:Enpt:rT:", 0, 0 }, - .usage = "[-Elnpr] [-c target-client] [-t target-session] " + .args = { "lc:Enpt:rT:Z", 0, 0 }, + .usage = "[-ElnprZ] [-c target-client] [-t target-session] " "[-T key-table]", /* -t is special */ @@ -54,6 +54,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) struct client *c; struct session *s; struct winlink *wl; + struct window *w; struct window_pane *wp; const char *tablename; struct key_table *table; @@ -72,6 +73,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_ERROR); s = item->target.s; wl = item->target.wl; + w = wl->window; wp = item->target.wp; if (args_has(args, 'r')) @@ -112,12 +114,15 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) } else { if (item->client == NULL) return (CMD_RETURN_NORMAL); + if (wl != NULL && wp != NULL) { + if (window_push_zoom(w, args_has(self->args, 'Z'))) + server_redraw_window(w); + window_redraw_active_switch(w, wp); + window_set_active_pane(w, wp, 1); + if (window_pop_zoom(w)) + server_redraw_window(w); + } if (wl != NULL) { - server_unzoom_window(wl->window); - if (wp != NULL) { - window_redraw_active_switch(wp->window, wp); - window_set_active_pane(wp->window, wp, 1); - } session_set_current(s, wl); cmd_find_from_session(&item->shared->current, s, 0); } diff --git a/tmux.1 b/tmux.1 index 20863dfa..1bac8de8 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1291,7 +1291,7 @@ Suspend a client by sending .Dv SIGTSTP (tty stop). .It Xo Ic switch-client -.Op Fl Elnpr +.Op Fl ElnprZ .Op Fl c Ar target-client .Op Fl t Ar target-session .Op Fl T Ar key-table @@ -1308,7 +1308,10 @@ may refer to a pane (a target that contains .Ql \&. or .Ql % ) , -in which case the session, window and pane are all changed. +to change session, window and pane. +In that case, +.Fl Z +keeps the window zoomed if it was zoomed. If .Fl l , .Fl n @@ -1934,11 +1937,13 @@ The option kills all but the window given with .Fl t . .It Xo Ic last-pane -.Op Fl de +.Op Fl deZ .Op Fl t Ar target-window .Xc .D1 (alias: Ic lastp ) Select the last (previously selected) pane. +.Fl Z +keeps the window zoomed if it was zoomed. .Fl e enables or .Fl d @@ -2320,7 +2325,7 @@ option has the same meaning as for the .Ic new-window command. .It Xo Ic rotate-window -.Op Fl DU +.Op Fl DUZ .Op Fl t Ar target-window .Xc .D1 (alias: Ic rotatew ) @@ -2328,6 +2333,8 @@ Rotate the positions of the panes within a window, either upward (numerically lower) with .Fl U or downward (numerically higher). +.Fl Z +keeps the window zoomed if it was zoomed. .It Xo Ic select-layout .Op Fl Enop .Op Fl t Ar target-pane @@ -2351,7 +2358,7 @@ applies the last set layout if possible (undoes the most recent layout change). .Fl E spreads the current pane and any panes next to it out evenly. .It Xo Ic select-pane -.Op Fl DdeLlMmRU +.Op Fl DdeLlMmRUZ .Op Fl T Ar title .Op Fl t Ar target-pane .Xc @@ -2368,6 +2375,8 @@ or .Fl U is used, respectively the pane below, to the left, to the right, or above the target pane is used. +.Fl Z +keeps the window zoomed if it was zoomed. .Fl l is the same as using the .Ic last-pane @@ -2473,7 +2482,7 @@ All other options have the same meaning as for the .Ic new-window command. .It Xo Ic swap-pane -.Op Fl dDU +.Op Fl dDUZ .Op Fl s Ar src-pane .Op Fl t Ar dst-pane .Xc @@ -2490,7 +2499,9 @@ swaps with the next pane (after it numerically). .Fl d instructs .Nm -not to change the active pane. +not to change the active pane and +.Fl Z +keeps the window zoomed if it was zoomed. .Pp If .Fl s diff --git a/tmux.h b/tmux.h index ef24717b..3bcb120b 100644 --- a/tmux.h +++ b/tmux.h @@ -922,6 +922,7 @@ struct window { #define WINDOW_ACTIVITY 0x2 #define WINDOW_SILENCE 0x4 #define WINDOW_ZOOMED 0x8 +#define WINDOW_WASZOOMED 0x10 #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) int alerts_queued; @@ -2381,6 +2382,8 @@ struct window_pane *window_add_pane(struct window *, struct window_pane *, void window_resize(struct window *, u_int, u_int); int window_zoom(struct window_pane *); int window_unzoom(struct window *); +int window_push_zoom(struct window *, int); +int window_pop_zoom(struct window *); void window_lost_pane(struct window *, struct window_pane *); void window_remove_pane(struct window *, struct window_pane *); struct window_pane *window_pane_at_index(struct window *, u_int); diff --git a/window.c b/window.c index 06145221..bf4fbb70 100644 --- a/window.c +++ b/window.c @@ -587,6 +587,28 @@ window_unzoom(struct window *w) return (0); } +int +window_push_zoom(struct window *w, int flag) +{ + log_debug("%s: @%u %d", __func__, w->id, + flag && (w->flags & WINDOW_ZOOMED)); + if (flag && (w->flags & WINDOW_ZOOMED)) + w->flags |= WINDOW_WASZOOMED; + else + w->flags &= ~WINDOW_WASZOOMED; + return (window_unzoom(w) == 0); +} + +int +window_pop_zoom(struct window *w) +{ + log_debug("%s: @%u %d", __func__, w->id, + !!(w->flags & WINDOW_WASZOOMED)); + if (w->flags & WINDOW_WASZOOMED) + return (window_zoom(w->active) == 0); + return (0); +} + struct window_pane * window_add_pane(struct window *w, struct window_pane *other, u_int hlimit, int flags)