Add -Z flag to rotate-window, select-pane, swap-pane, switch-client to

preserve zoomed state. GitHub issue 1839.
pull/1875/head
nicm 2019-08-14 09:58:31 +00:00
parent 45f4ff5485
commit 0f243f0388
7 changed files with 101 additions and 41 deletions

View File

@ -31,8 +31,8 @@ const struct cmd_entry cmd_rotate_window_entry = {
.name = "rotate-window", .name = "rotate-window",
.alias = "rotatew", .alias = "rotatew",
.args = { "Dt:U", 0, 0 }, .args = { "Dt:UZ", 0, 0 },
.usage = "[-DU] " CMD_TARGET_WINDOW_USAGE, .usage = "[-DUZ] " CMD_TARGET_WINDOW_USAGE,
.target = { 't', CMD_FIND_WINDOW, 0 }, .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; struct layout_cell *lc;
u_int sx, sy, xoff, yoff; 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')) { if (args_has(self->args, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes); 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) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
wp = TAILQ_LAST(&w->panes, window_panes); 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 { } else {
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry); 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) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
wp = TAILQ_FIRST(&w->panes); 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); return (CMD_RETURN_NORMAL);
} }

View File

@ -33,8 +33,8 @@ const struct cmd_entry cmd_select_pane_entry = {
.name = "select-pane", .name = "select-pane",
.alias = "selectp", .alias = "selectp",
.args = { "DdegLlMmP:RT:t:U", 0, 0 }, /* -P and -g deprecated */ .args = { "DdegLlMmP:RT:t:UZ", 0, 0 }, /* -P and -g deprecated */
.usage = "[-DdeLlMmRU] [-T title] " CMD_TARGET_PANE_USAGE, .usage = "[-DdeLlMmRUZ] [-T title] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -46,8 +46,8 @@ const struct cmd_entry cmd_last_pane_entry = {
.name = "last-pane", .name = "last-pane",
.alias = "lastp", .alias = "lastp",
.args = { "det:", 0, 0 }, .args = { "det:Z", 0, 0 },
.usage = "[-de] " CMD_TARGET_WINDOW_USAGE, .usage = "[-deZ] " CMD_TARGET_WINDOW_USAGE,
.target = { 't', CMD_FIND_WINDOW, 0 }, .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')) else if (args_has(self->args, 'd'))
lastwp->flags |= PANE_INPUTOFF; lastwp->flags |= PANE_INPUTOFF;
else { 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); window_redraw_active_switch(w, lastwp);
if (window_set_active_pane(w, lastwp, 1)) { if (window_set_active_pane(w, lastwp, 1)) {
cmd_find_from_winlink(current, wl, 0); cmd_find_from_winlink(current, wl, 0);
cmd_select_pane_redraw(w); cmd_select_pane_redraw(w);
} }
if (window_pop_zoom(w))
server_redraw_window(w);
} }
return (CMD_RETURN_NORMAL); 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')) { if (args_has(self->args, 'L')) {
server_unzoom_window(wp->window); window_push_zoom(w, 1);
wp = window_pane_find_left(wp); wp = window_pane_find_left(wp);
window_pop_zoom(w);
} else if (args_has(self->args, 'R')) { } else if (args_has(self->args, 'R')) {
server_unzoom_window(wp->window); window_push_zoom(w, 1);
wp = window_pane_find_right(wp); wp = window_pane_find_right(wp);
window_pop_zoom(w);
} else if (args_has(self->args, 'U')) { } else if (args_has(self->args, 'U')) {
server_unzoom_window(wp->window); window_push_zoom(w, 1);
wp = window_pane_find_up(wp); wp = window_pane_find_up(wp);
window_pop_zoom(w);
} else if (args_has(self->args, 'D')) { } else if (args_has(self->args, 'D')) {
server_unzoom_window(wp->window); window_push_zoom(w, 1);
wp = window_pane_find_down(wp); wp = window_pane_find_down(wp);
window_pop_zoom(w);
} }
if (wp == NULL) if (wp == NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
@ -196,13 +203,16 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
if (wp == w->active) if (wp == w->active)
return (CMD_RETURN_NORMAL); 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); window_redraw_active_switch(w, wp);
if (window_set_active_pane(w, wp, 1)) { if (window_set_active_pane(w, wp, 1)) {
cmd_find_from_winlink_pane(current, wl, wp, 0); cmd_find_from_winlink_pane(current, wl, wp, 0);
cmdq_insert_hook(s, item, current, "after-select-pane"); cmdq_insert_hook(s, item, current, "after-select-pane");
cmd_select_pane_redraw(w); cmd_select_pane_redraw(w);
} }
if (window_pop_zoom(w))
server_redraw_window(w);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@ -32,8 +32,8 @@ const struct cmd_entry cmd_swap_pane_entry = {
.name = "swap-pane", .name = "swap-pane",
.alias = "swapp", .alias = "swapp",
.args = { "dDs:t:U", 0, 0 }, .args = { "dDs:t:UZ", 0, 0 },
.usage = "[-dDU] " CMD_SRCDST_PANE_USAGE, .usage = "[-dDUZ] " CMD_SRCDST_PANE_USAGE,
.source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED }, .source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED },
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -45,6 +45,7 @@ const struct cmd_entry cmd_swap_pane_entry = {
static enum cmd_retval static enum cmd_retval
cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args;
struct window *src_w, *dst_w; struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc; 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; dst_wp = item->target.wp;
src_w = item->source.wl->window; src_w = item->source.wl->window;
src_wp = item->source.wp; 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_w = dst_w;
src_wp = TAILQ_NEXT(dst_wp, entry); src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes); 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_w = dst_w;
src_wp = TAILQ_PREV(dst_wp, window_panes, entry); src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes); 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) if (src_wp == dst_wp)
return (CMD_RETURN_NORMAL); goto out;
tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry); tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
TAILQ_REMOVE(&dst_w->panes, dst_wp, 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; dst_wp->xoff = xoff; dst_wp->yoff = yoff;
window_pane_resize(dst_wp, sx, sy); window_pane_resize(dst_wp, sx, sy);
if (!args_has(self->args, 'd')) { if (!args_has(args, 'd')) {
if (src_w != dst_w) { if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp, 1); window_set_active_pane(src_w, dst_wp, 1);
window_set_active_pane(dst_w, src_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(src_w);
server_redraw_window(dst_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); return (CMD_RETURN_NORMAL);
} }

View File

@ -34,8 +34,8 @@ const struct cmd_entry cmd_switch_client_entry = {
.name = "switch-client", .name = "switch-client",
.alias = "switchc", .alias = "switchc",
.args = { "lc:Enpt:rT:", 0, 0 }, .args = { "lc:Enpt:rT:Z", 0, 0 },
.usage = "[-Elnpr] [-c target-client] [-t target-session] " .usage = "[-ElnprZ] [-c target-client] [-t target-session] "
"[-T key-table]", "[-T key-table]",
/* -t is special */ /* -t is special */
@ -54,6 +54,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
struct client *c; struct client *c;
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
struct window *w;
struct window_pane *wp; struct window_pane *wp;
const char *tablename; const char *tablename;
struct key_table *table; struct key_table *table;
@ -72,6 +73,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
s = item->target.s; s = item->target.s;
wl = item->target.wl; wl = item->target.wl;
w = wl->window;
wp = item->target.wp; wp = item->target.wp;
if (args_has(args, 'r')) if (args_has(args, 'r'))
@ -112,12 +114,15 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
} else { } else {
if (item->client == NULL) if (item->client == NULL)
return (CMD_RETURN_NORMAL); 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) { 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); session_set_current(s, wl);
cmd_find_from_session(&item->shared->current, s, 0); cmd_find_from_session(&item->shared->current, s, 0);
} }

25
tmux.1
View File

@ -1291,7 +1291,7 @@ Suspend a client by sending
.Dv SIGTSTP .Dv SIGTSTP
(tty stop). (tty stop).
.It Xo Ic switch-client .It Xo Ic switch-client
.Op Fl Elnpr .Op Fl ElnprZ
.Op Fl c Ar target-client .Op Fl c Ar target-client
.Op Fl t Ar target-session .Op Fl t Ar target-session
.Op Fl T Ar key-table .Op Fl T Ar key-table
@ -1308,7 +1308,10 @@ may refer to a pane (a target that contains
.Ql \&. .Ql \&.
or or
.Ql % ) , .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 If
.Fl l , .Fl l ,
.Fl n .Fl n
@ -1934,11 +1937,13 @@ The
option kills all but the window given with option kills all but the window given with
.Fl t . .Fl t .
.It Xo Ic last-pane .It Xo Ic last-pane
.Op Fl de .Op Fl deZ
.Op Fl t Ar target-window .Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic lastp ) .D1 (alias: Ic lastp )
Select the last (previously selected) pane. Select the last (previously selected) pane.
.Fl Z
keeps the window zoomed if it was zoomed.
.Fl e .Fl e
enables or enables or
.Fl d .Fl d
@ -2320,7 +2325,7 @@ option has the same meaning as for the
.Ic new-window .Ic new-window
command. command.
.It Xo Ic rotate-window .It Xo Ic rotate-window
.Op Fl DU .Op Fl DUZ
.Op Fl t Ar target-window .Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic rotatew ) .D1 (alias: Ic rotatew )
@ -2328,6 +2333,8 @@ Rotate the positions of the panes within a window, either upward (numerically
lower) with lower) with
.Fl U .Fl U
or downward (numerically higher). or downward (numerically higher).
.Fl Z
keeps the window zoomed if it was zoomed.
.It Xo Ic select-layout .It Xo Ic select-layout
.Op Fl Enop .Op Fl Enop
.Op Fl t Ar target-pane .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 .Fl E
spreads the current pane and any panes next to it out evenly. spreads the current pane and any panes next to it out evenly.
.It Xo Ic select-pane .It Xo Ic select-pane
.Op Fl DdeLlMmRU .Op Fl DdeLlMmRUZ
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Xc .Xc
@ -2368,6 +2375,8 @@ or
.Fl U .Fl U
is used, respectively the pane below, to the left, to the right, or above the is used, respectively the pane below, to the left, to the right, or above the
target pane is used. target pane is used.
.Fl Z
keeps the window zoomed if it was zoomed.
.Fl l .Fl l
is the same as using the is the same as using the
.Ic last-pane .Ic last-pane
@ -2473,7 +2482,7 @@ All other options have the same meaning as for the
.Ic new-window .Ic new-window
command. command.
.It Xo Ic swap-pane .It Xo Ic swap-pane
.Op Fl dDU .Op Fl dDUZ
.Op Fl s Ar src-pane .Op Fl s Ar src-pane
.Op Fl t Ar dst-pane .Op Fl t Ar dst-pane
.Xc .Xc
@ -2490,7 +2499,9 @@ swaps with the next pane (after it numerically).
.Fl d .Fl d
instructs instructs
.Nm .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 .Pp
If If
.Fl s .Fl s

3
tmux.h
View File

@ -922,6 +922,7 @@ struct window {
#define WINDOW_ACTIVITY 0x2 #define WINDOW_ACTIVITY 0x2
#define WINDOW_SILENCE 0x4 #define WINDOW_SILENCE 0x4
#define WINDOW_ZOOMED 0x8 #define WINDOW_ZOOMED 0x8
#define WINDOW_WASZOOMED 0x10
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
int alerts_queued; 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); void window_resize(struct window *, u_int, u_int);
int window_zoom(struct window_pane *); int window_zoom(struct window_pane *);
int window_unzoom(struct window *); 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_lost_pane(struct window *, struct window_pane *);
void window_remove_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); struct window_pane *window_pane_at_index(struct window *, u_int);

View File

@ -587,6 +587,28 @@ window_unzoom(struct window *w)
return (0); 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 * struct window_pane *
window_add_pane(struct window *w, struct window_pane *other, u_int hlimit, window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
int flags) int flags)