Like this, but I am unsure if this is just an awful hack and we might be better to properly support 'detached' panes which don't have a cell. Then we could have layouts where some panes aren't present at all but they would still appear in lsp etc.
diff --git a/cmd-break-pane.c b/cmd-break-pane.c index a4350fe..069eb3e 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -63,6 +63,8 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) } w = wl->window; + window_unzoom(w); + TAILQ_REMOVE(&w->panes, wp, entry); if (wp == w->active) { w->active = w->last; diff --git a/cmd-join-pane.c b/cmd-join-pane.c index a2e7a2d..9a3a9fd 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -91,11 +91,13 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window) return (CMD_RETURN_ERROR); dst_w = dst_wl->window; dst_idx = dst_wl->idx; + window_unzoom(dst_w); src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp); if (src_wl == NULL) return (CMD_RETURN_ERROR); src_w = src_wl->window; + window_unzoom(src_w); if (not_same_window && src_w == dst_w) { ctx->error(ctx, "can't join a pane to its own window"); diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c index 4f7af2e..750faf0 100644 --- a/cmd-kill-pane.c +++ b/cmd-kill-pane.c @@ -54,6 +54,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) recalculate_sizes(); return (CMD_RETURN_NORMAL); } + window_unzoom(wl->window); if (args_has(self->args, 'a')) { TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 328e1b4..dc75494 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -31,8 +31,8 @@ enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_resize_pane_entry = { "resize-pane", "resizep", - "DLRt:Ux:y:", 0, 1, - "[-DLRU] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]", + "DLRt:Ux:y:Z", 0, 1, + "[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]", 0, cmd_resize_pane_key_binding, NULL, @@ -75,6 +75,10 @@ cmd_resize_pane_key_binding(struct cmd *self, int key) self->args = args_create(1, "5"); args_set(self->args, 'R', NULL); break; + case 'z': + self->args = args_create(0); + args_set(self->args, 'z', NULL); + break; default: self->args = args_create(0); break; @@ -86,6 +90,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct winlink *wl; + struct window *w; const char *errstr; char *cause; struct window_pane *wp; @@ -94,6 +99,16 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL) return (CMD_RETURN_ERROR); + w = wl->window; + + if (args_has(args, 'z')) { + if (TAILQ_EMPTY(&w->saved_panes)) + window_zoom(wp); + else + window_unzoom(w); + return (CMD_RETURN_NORMAL); + } + window_unzoom(w); if (args->argc == 0) adjust = 1; diff --git a/cmd-select-layout.c b/cmd-select-layout.c index b2423e9..558661b 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -92,6 +92,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); + window_unzoom(wl->window); next = self->entry == &cmd_next_layout_entry; if (args_has(self->args, 'n')) diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 8ebae5f..2428b26 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -94,6 +94,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx) ctx->error(ctx, "pane not visible"); return (CMD_RETURN_ERROR); } + window_unzoom(wp->window); if (args_has(self->args, 'L')) wp = window_pane_find_left(wp); diff --git a/cmd-split-window.c b/cmd-split-window.c index cac8095..242db41 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -72,6 +72,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); w = wl->window; + window_unzoom(w); environ_init(&env); environ_copy(&global_environ, &env); diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index 42fe2fc..4d9044b 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -63,6 +63,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if (dst_wl == NULL) return (CMD_RETURN_ERROR); dst_w = dst_wl->window; + window_unzoom(dst_w); if (!args_has(args, 's')) { src_w = dst_w; @@ -82,6 +83,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) return (CMD_RETURN_ERROR); src_w = src_wl->window; } + window_unzoom(src_w); if (src_wp == dst_wp) return (CMD_RETURN_NORMAL); diff --git a/key-bindings.c b/key-bindings.c index 9e5a729..bf9ff31 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -150,6 +150,7 @@ key_bindings_init(void) { 't', 0, &cmd_clock_mode_entry }, { 'w', 0, &cmd_choose_window_entry }, { 'x', 0, &cmd_confirm_before_entry }, + { 'z', 0, &cmd_resize_pane_entry }, { '{', 0, &cmd_swap_pane_entry }, { '}', 0, &cmd_swap_pane_entry }, { '~', 0, &cmd_show_messages_entry }, diff --git a/tmux.h b/tmux.h index 8c06197..fa226a1 100644 --- a/tmux.h +++ b/tmux.h @@ -978,6 +978,12 @@ struct window { struct window_pane *last; struct window_panes panes; + struct window_pane *saved_before; + struct window_pane *saved_last; + struct window_panes saved_panes; + struct layout_cell *saved_layout; + struct layout_cell *saved_cell; + int lastlayout; struct layout_cell *layout_root; @@ -2113,6 +2119,8 @@ struct window_pane *window_find_string(struct window *, const char *); void window_set_active_pane(struct window *, struct window_pane *); struct window_pane *window_add_pane(struct window *, u_int); void window_resize(struct window *, u_int, u_int); +int window_zoom(struct window_pane *); +int window_unzoom(struct window *); 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_next_by_number(struct window *, diff --git a/window.c b/window.c index 77f06f8..f9a2888 100644 --- a/window.c +++ b/window.c @@ -278,6 +278,7 @@ window_create1(u_int sx, u_int sy) w->name = NULL; w->flags = 0; + TAILQ_INIT(&w->saved_panes); TAILQ_INIT(&w->panes); w->active = NULL; @@ -455,6 +456,73 @@ window_find_string(struct window *w, const char *s) return (window_get_active_at(w, x, y)); } +int +window_zoom(struct window_pane *wp) +{ + struct window *w = wp->window; + struct window_pane *wp1; + + if (!TAILQ_EMPTY(&w->saved_panes)) + return (-1); + + if (!window_pane_visible(wp)) + return (-1); + if (w->active != wp) + window_set_active_pane(w, wp); + + w->saved_before = TAILQ_NEXT(wp, entry); + TAILQ_REMOVE(&w->panes, wp, entry); + + w->saved_last = w->last; + w->last = NULL; + + memcpy(&w->saved_panes, &w->panes, sizeof w->saved_panes); + TAILQ_INIT(&w->panes); + TAILQ_INSERT_HEAD(&w->panes, wp, entry); + + TAILQ_FOREACH(wp1, &w->saved_panes, entry) + RB_REMOVE(window_pane_tree, &all_window_panes, wp1); + + w->saved_cell = wp->layout_cell; + w->saved_layout = w->layout_root; + layout_init(w); + + server_redraw_window(w); + return (0); +} + +int +window_unzoom(struct window *w) +{ + struct window_pane *wp, *wp1; + + if (TAILQ_EMPTY(&w->saved_panes)) + return (-1); + wp = w->active; + + TAILQ_FOREACH(wp1, &w->saved_panes, entry) + RB_INSERT(window_pane_tree, &all_window_panes, wp1); + + TAILQ_REMOVE(&w->panes, wp, entry); + memcpy(&w->panes, &w->saved_panes, sizeof w->panes); + TAILQ_INIT(&w->saved_panes); + + if (w->saved_before == NULL) + TAILQ_INSERT_TAIL(&w->panes, wp, entry); + else + TAILQ_INSERT_BEFORE(w->saved_before, wp, entry); + + w->last = w->saved_last; + + layout_free(w); + wp->layout_cell = w->saved_cell; + w->layout_root = w->saved_layout; + layout_fix_panes(w, w->sx, w->sy); + + server_redraw_window(w); + return (0); +} + struct window_pane * window_add_pane(struct window *w, u_int hlimit) { On Fri, Feb 22, 2013 at 07:58:16AM +0000, Thomas Adam wrote: > Hi, > > On 22 February 2013 07:52, Nicholas Marriott > <nicholas.marri...@gmail.com> wrote: > > Hmm. Not sure I like scrambling all the other panes sizes but I don't > > see offhand why it freezes. I take it you didn't do restore? > > I think I restored it by reapplying a different layout. The freeze > most likely was due to closing a pane in a maximised state because the > other pane(s) would then be marked as not visible and hence couldn't > select anything thereafter... or something like that. > > > Thinking more a mode wouldn't do it because of course they are inside > > the pane :-). > > > > I think rather than removing the old layout we should just save it off > > and make a new temporary one, then restoring it is simple. The problem > > is of course all the panes are still reachable via the window so might > > need checks all over the place... maybe just a check in > > window_pane_visible might get some of them. And a bunch of calls in > > various places to restore the layout before doing things like kill > > pane/select layout/etc etc etc. > > Hmm. That might work. I did originally think of just adding this > ability to resize-pane instead since it's not strictly a layout; of > course, this would be disruptive to other panes, so... maybe not. > > -- Thomas Adam ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_feb _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users