You may want this too which stops us hammering ptys with TIOCSWINSZ on
resize which seems to confuse some programs

I've also attached the full latest zoom diff.


diff --git a/server-client.c b/server-client.c
index d9a647e..3c14ff8 100644
--- a/server-client.c
+++ b/server-client.c
@@ -28,6 +28,7 @@
 #include "tmux.h"
 
 void   server_client_check_focus(struct window_pane *);
+void   server_client_check_resize(struct window_pane *);
 void   server_client_check_mouse(struct client *, struct window_pane *);
 void   server_client_repeat_timer(int, short, void *);
 void   server_client_check_exit(struct client *);
@@ -495,7 +496,7 @@ server_client_loop(void)
 
        /*
         * Any windows will have been redrawn as part of clients, so clear
-        * their flags now. Also check and update pane focus.
+        * their flags now. Also check pane focus and resize.
         */
        for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
                w = ARRAY_ITEM(&windows, i);
@@ -505,11 +506,41 @@ server_client_loop(void)
                w->flags &= ~WINDOW_REDRAW;
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        server_client_check_focus(wp);
+                       server_client_check_resize(wp);
                        wp->flags &= ~PANE_REDRAW;
                }
        }
 }
 
+/* Check if pane should be resized. */
+void
+server_client_check_resize(struct window_pane *wp)
+{
+       struct winsize  ws;
+
+       if (wp->fd == -1 || !(wp->flags & PANE_RESIZE))
+               return;
+
+       memset(&ws, 0, sizeof ws);
+       ws.ws_col = wp->sx;
+       ws.ws_row = wp->sy;
+
+       if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) {
+#ifdef __sun
+               /*
+                * Some versions of Solaris apparently can return an error when
+                * resizing; don't know why this happens, can't reproduce on
+                * other platforms and ignoring it doesn't seem to cause any
+                * issues.
+                */
+               if (errno != EINVAL)
+#endif
+               fatal("ioctl failed");
+       }
+
+       wp->flags &= ~PANE_RESIZE;
+}
+
 /* Check whether pane should be focused. */
 void
 server_client_check_focus(struct window_pane *wp)
diff --git a/tmux.h b/tmux.h
index 4d01a72..144433c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -929,6 +929,7 @@ struct window_pane {
 #define PANE_DROP 0x2
 #define PANE_FOCUSED 0x4
 #define PANE_HIDDEN 0x8
+#define PANE_RESIZE 0x10
 
        char            *cmd;
        char            *shell;
diff --git a/window.c b/window.c
index 2170b07..00eb3e6 100644
--- a/window.c
+++ b/window.c
@@ -915,32 +915,16 @@ window_pane_error_callback(
 void
 window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
 {
-       struct winsize  ws;
-
        if (sx == wp->sx && sy == wp->sy)
                return;
        wp->sx = sx;
        wp->sy = sy;
 
-       memset(&ws, 0, sizeof ws);
-       ws.ws_col = sx;
-       ws.ws_row = sy;
-
        screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
        if (wp->mode != NULL)
                wp->mode->resize(wp, sx, sy);
 
-       if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
-#ifdef __sun
-               /*
-                * Some versions of Solaris apparently can return an error when
-                * resizing; don't know why this happens, can't reproduce on
-                * other platforms and ignoring it doesn't seem to cause any
-                * issues.
-                */
-               if (errno != EINVAL)
-#endif
-               fatal("ioctl failed");
+       wp->flags |= PANE_RESIZE;
 }
 
 /*


On Fri, Feb 22, 2013 at 06:02:47PM +0000, Nicholas Marriott wrote:
> I don't know, send me what is in your prompt please (eg echo $PS1|cat -v).
> 
> Also you will want to apply this on top of the zoom patch to fix zoom
> with window resizing:
> 
> diff --git a/resize.c b/resize.c
> index a560958..90212b2 100644
> --- a/resize.c
> +++ b/resize.c
> @@ -50,7 +50,7 @@ recalculate_sizes(void)
>       struct window           *w;
>       struct window_pane      *wp;
>       u_int                    i, j, ssx, ssy, has, limit;
> -     int                      flag, has_status;
> +     int                      flag, has_status, is_zoomed;
>  
>       RB_FOREACH(s, sessions, &sessions) {
>               has_status = options_get_number(&s->options, "status");
> @@ -123,12 +123,16 @@ recalculate_sizes(void)
>  
>               if (w->sx == ssx && w->sy == ssy)
>                       continue;
> -
>               log_debug("window size %u,%u (was %u,%u)", ssx, ssy, w->sx,
>                   w->sy);
>  
> +             is_zoomed = !TAILQ_EMPTY(&w->saved_panes);
> +             if (is_zoomed)
> +                     window_unzoom(w);
>               layout_resize(w, ssx, ssy);
>               window_resize(w, ssx, ssy);
> +             if (is_zoomed && window_pane_visible(w->active))
> +                     window_zoom(w->active);
>  
>               /*
>                * If the current pane is now not visible, move to the next
> 
> 
> 
> 
> On Fri, Feb 22, 2013 at 09:49:52AM -0800, Aaron Jensen wrote:
> >    seems I can yeah. What's causing it?
> > 
> >    On Fri, Feb 22, 2013 at 9:48 AM, Nicholas Marriott
> >    <[1]nicholas.marri...@gmail.com> wrote:
> > 
> >      This may be unrelated, can you reproduce this by having a small 
> > terminal
> >      in tmux with 1 pane and then resizing the terminal instead of zooming?
> > 
> >      On Fri, Feb 22, 2013 at 09:45:48AM -0800, Aaron Jensen wrote:
> >      > * *I'm not getting the bleed through, but the resize causes some
> >      problems
> >      > * *with rendering the prompt, it plops part of my fairly long prompt
> >      on top
> >      > * *of where i should be typing when i zoom
> >      >
> >      > *
> >      *[1][2]http://dl.dropbox.com/u/113468811/Screenshots/nafczt3h0xb_.png
> >      >
> >      > * *On Fri, Feb 22, 2013 at 9:29 AM, Nicholas Marriott
> >      > * *<[2][3]nicholas.marri...@gmail.com> wrote:
> >      >
> >      > * * *Try this instead please which should fix that:
> >      > * * *diff --git a/cmd-break-pane.c b/cmd-break-pane.c
> >      > * * *index a4350fe..4f329e5 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;
> >      > * * *+ * * * server_unzoom_window(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..41b532c 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;
> >      > * * *+ * * * server_unzoom_window(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;
> >      > * * *+ * * * server_unzoom_window(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..f0a17ad 100644
> >      > * * *--- a/cmd-kill-pane.c
> >      > * * *+++ b/cmd-kill-pane.c
> >      > * * *@@ -47,6 +47,7 @@ cmd_kill_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);
> >      > * * *+ * * * server_unzoom_window(wl->window);
> >      >
> >      > * * ** * * * if (window_count_panes(wl->window) == 1) {
> >      > * * ** * * * * * * * /* Only one pane, kill the window. */
> >      > * * *diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c
> >      > * * *index 328e1b4..b056b8f 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,18 @@ 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);
> >      > * * *+ * * * * * * * server_redraw_window(w);
> >      > * * *+ * * * * * * * server_status_window(w);
> >      > * * *+ * * * * * * * return (CMD_RETURN_NORMAL);
> >      > * * *+ * * * }
> >      > * * *+ * * * server_unzoom_window(w);
> >      >
> >      > * * ** * * * if (args->argc == 0)
> >      > * * ** * * * * * * * adjust = 1;
> >      > * * *diff --git a/cmd-select-layout.c b/cmd-select-layout.c
> >      > * * *index b2423e9..7e7e35e 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);
> >      > * * *+ * * * server_unzoom_window(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..71882e4 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);
> >      > * * ** * * * }
> >      > * * *+ * * * server_unzoom_window(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..a21ff77 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;
> >      > * * *+ * * * server_unzoom_window(w);
> >      >
> >      > * * ** * * * environ_init(&env);
> >      > * * ** * * * environ_copy(&global_environ, &env);
> >      > * * *diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
> >      > * * *index 42fe2fc..cc9e7df 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;
> >      > * * *+ * * * server_unzoom_window(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;
> >      > * * ** * * * }
> >      > * * *+ * * * server_unzoom_window(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/server-fn.c b/server-fn.c
> >      > * * *index 26f93d9..f17c3b1 100644
> >      > * * *--- a/server-fn.c
> >      > * * *+++ b/server-fn.c
> >      > * * *@@ -377,6 +377,7 @@ server_destroy_pane(struct window_pane *wp)
> >      > * * ** * * * * * * * return;
> >      > * * ** * * * }
> >      >
> >      > * * *+ * * * server_unzoom_window(w);
> >      > * * ** * * * layout_close_pane(wp);
> >      > * * ** * * * window_remove_pane(w, wp);
> >      >
> >      > * * *@@ -588,3 +589,11 @@ server_set_stdin_callback(struct client *c,
> >      void
> >      > * * *(*cb)(struct client *, int,
> >      >
> >      > * * ** * * * return (0);
> >      > * * **}
> >      > * * *+
> >      > * * *+void
> >      > * * *+server_unzoom_window(struct window *w)
> >      > * * *+{
> >      > * * *+ * * * window_unzoom(w);
> >      > * * *+ * * * server_redraw_window(w);
> >      > * * *+ * * * server_status_window(w);
> >      > * * *+}
> >      > * * *diff --git a/tmux.1 b/tmux.1
> >      > * * *index 8731efb..2f85a35 100644
> >      > * * *--- a/tmux.1
> >      > * * *+++ b/tmux.1
> >      > * * *@@ -1572,7 +1572,7 @@ Rename the current window, or the window 
> > at
> >      > * * **if specified, to
> >      > * * **.Ar new-name .
> >      > * * **.It Xo Ic resize-pane
> >      > * * *-.Op Fl DLRU
> >      > * * *+.Op Fl DLRUZ
> >      > * * **.Op Fl t Ar target-pane
> >      > * * **.Op Fl x Ar width
> >      > * * **.Op Fl y Ar height
> >      > * * *@@ -1596,6 +1596,11 @@ or
> >      > * * **The
> >      > * * **.Ar adjustment
> >      > * * **is given in lines or cells (the default is 1).
> >      > * * *+.Pp
> >      > * * *+With
> >      > * * *+.Fl Z ,
> >      > * * *+the active pane is toggled between occupying the whole of the
> >      window
> >      > * * *and it's
> >      > * * *+normal position in the layout.
> >      > * * **.It Xo Ic respawn-pane
> >      > * * **.Op Fl k
> >      > * * **.Op Fl t Ar target-pane
> >      > * * *diff --git a/tmux.h b/tmux.h
> >      > * * *index 8c06197..4d01a72 100644
> >      > * * *--- a/tmux.h
> >      > * * *+++ b/tmux.h
> >      > * * *@@ -928,6 +928,7 @@ struct window_pane {
> >      > * * **#define PANE_REDRAW 0x1
> >      > * * **#define PANE_DROP 0x2
> >      > * * **#define PANE_FOCUSED 0x4
> >      > * * *+#define PANE_HIDDEN 0x8
> >      >
> >      > * * ** * * * char * * * * * **cmd;
> >      > * * ** * * * char * * * * * **shell;
> >      > * * *@@ -978,6 +979,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;
> >      >
> >      > * * *@@ -1910,6 +1917,7 @@ void * * * server_push_stdout(struct 
> > client
> >      *);
> >      > * * **void * *server_push_stderr(struct client *);
> >      > * * **int * * server_set_stdin_callback(struct client *, void
> >      (*)(struct
> >      > * * *client *,
> >      > * * ** * * * * * *int, void *), void *, char **);
> >      > * * *+void * *server_unzoom_window(struct window *);
> >      >
> >      > * * **/* status.c */
> >      > * * **int * * status_out_cmp(struct status_out *, struct status_out
> >      *);
> >      > * * *@@ -2113,6 +2121,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..2170b07 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;
> >      >
> >      > * * *@@ -333,6 +334,8 @@ window_destroy(struct window *w)
> >      > * * **{
> >      > * * ** * * * u_int * i;
> >      >
> >      > * * *+ * * * window_unzoom(w);
> >      > * * *+
> >      > * * ** * * * if (window_index(w, &i) != 0)
> >      > * * ** * * * * * * * fatalx("index not found");
> >      > * * ** * * * ARRAY_SET(&windows, i, NULL);
> >      > * * *@@ -455,6 +458,75 @@ 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) {
> >      > * * *+ * * * * * * * wp1->flags |= PANE_HIDDEN;
> >      > * * *+ * * * * * * * RB_REMOVE(window_pane_tree, &all_window_panes,
> >      wp1);
> >      > * * *+ * * * }
> >      > * * *+
> >      > * * *+ * * * w->saved_cell = wp->layout_cell;
> >      > * * *+ * * * w->saved_layout = w->layout_root;
> >      > * * *+ * * * layout_init(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) {
> >      > * * *+ * * * * * * * wp1->flags &= ~PANE_HIDDEN;
> >      > * * *+ * * * * * * * 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);
> >      > * * *+
> >      > * * *+ * * * return (0);
> >      > * * *+}
> >      > * * *+
> >      > * * **struct window_pane *
> >      > * * **window_add_pane(struct window *w, u_int hlimit)
> >      > * * **{
> >      > * * *@@ -585,6 +657,8 @@ window_printable_flags(struct session *s,
> >      struct
> >      > * * *winlink *wl)
> >      > * * ** * * * * * * * flags[pos++] = '*';
> >      > * * ** * * * if (wl == TAILQ_FIRST(&s->lastw))
> >      > * * ** * * * * * * * flags[pos++] = '-';
> >      > * * *+ * * * if (!TAILQ_EMPTY(&wl->window->saved_panes))
> >      > * * *+ * * * * * * * flags[pos++] = 'Z';
> >      > * * ** * * * if (pos == 0)
> >      > * * ** * * * * * * * flags[pos++] = ' ';
> >      > * * ** * * * flags[pos] = '\0';
> >      > * * *@@ -1032,6 +1106,8 @@ window_pane_visible(struct window_pane 
> > *wp)
> >      > * * **{
> >      > * * ** * * * struct window * *w = wp->window;
> >      >
> >      > * * *+ * * * if (wp->flags & PANE_HIDDEN)
> >      > * * *+ * * * * * * * return (0);
> >      > * * ** * * * if (wp->xoff >= w->sx || wp->yoff >= w->sy)
> >      > * * ** * * * * * * * return (0);
> >      > * * ** * * * if (wp->xoff + wp->sx > w->sx || wp->yoff + wp->sy >
> >      w->sy)
> >      >
> >      > * * *On Fri, Feb 22, 2013 at 09:16:36AM -0800, Aaron Jensen wrote:
> >      > * * *> * *I may have misunderstood what this is intending to do, but
> >      I'm
> >      > * * *seeing pane
> >      > * * *> * *updates even though the panes are "hidden". In other words,
> >      my
> >      > * * *zoom'd pane
> >      > * * *> * *is getting overwritten when the other panes change. Is that
> >      > * * *intended?
> >      > * * *>
> >      > * * *> * *On Fri, Feb 22, 2013 at 9:10 AM, Aaron Jensen
> >      > * * *<[1][3][4]aaronjen...@gmail.com>
> >      > * * *> * *wrote:
> >      > * * *>
> >      > * * *> * * *I'm trying it today too. So far so good. Also, I was able
> >      to
> >      > * * *apply your
> >      > * * *> * * *patch :)
> >      > * * *>
> >      > * * *> * * *On Fri, Feb 22, 2013 at 8:21 AM, Nicholas Marriott
> >      > * * *> * * *<[2][4][5]nicholas.marri...@gmail.com> wrote:
> >      > * * *>
> >      > * * *> * * * *not convinced about the way it works, need to think
> >      about it.
> >      > * * *also it
> >      > * * *> * * * *needs testing
> >      > * * *>
> >      > * * *> * * * *On Fri, Feb 22, 2013 at 01:10:09PM -0300, Thiago 
> > Padilha
> >      wrote:
> >      > * * *> * * * *> On Fri, Feb 22, 2013 at 12:57 PM, Nicholas Marriott
> >      > * * *> * * * *> <[3][5][6]nicholas.marri...@gmail.com> wrote:
> >      > * * *> * * * *> > Here is the latest in case anyone wants to run with
> >      it for
> >      > * * *a while
> >      > * * *> * * * *> > before I decide whether or not to commit it :-).
> >      > * * *> * * * *> >
> >      > * * *> * * * *>
> >      > * * *> * * * *> What's wrong with it?
> >      > * * *>
> >      > * * *> * * *
> >      > * *
> >      
> > **------------------------------------------------------------------------------
> >      > * * *> * * * *Everyone hates slow websites. So do we.
> >      > * * *> * * * *Make your web apps faster with AppDynamics
> >      > * * *> * * * *Download AppDynamics Lite for free today:
> >      > * * *> * * * *[4][6][7]http://p.sf.net/sfu/appdyn_d2d_feb
> >      > * * *> * * * *_______________________________________________
> >      > * * *> * * * *tmux-users mailing list
> >      > * * *> * * * *[5][7][8]tmux-users@lists.sourceforge.net
> >      > * * *> * * *
> >      *[6][8][9]https://lists.sourceforge.net/lists/listinfo/tmux-users
> >      > * * *>
> >      > * * *> References
> >      > * * *>
> >      > * * *> * *Visible links
> >      > * * *> * *1. mailto:[9][10]aaronjen...@gmail.com
> >      > * * *> * *2. mailto:[10][11]nicholas.marri...@gmail.com
> >      > * * *> * *3. mailto:[11][12]nicholas.marri...@gmail.com
> >      > * * *> * *4. [12][13]http://p.sf.net/sfu/appdyn_d2d_feb
> >      > * * *> * *5. mailto:[13][14]tmux-users@lists.sourceforge.net
> >      > * * *> * *6.
> >      [14][15]https://lists.sourceforge.net/lists/listinfo/tmux-users
> >      >
> >      > References
> >      >
> >      > * *Visible links
> >      > * *1.
> >      [16]http://dl.dropbox.com/u/113468811/Screenshots/nafczt3h0xb_.png
> >      > * *2. mailto:[17]nicholas.marri...@gmail.com
> >      > * *3. mailto:[18]aaronjen...@gmail.com
> >      > * *4. mailto:[19]nicholas.marri...@gmail.com
> >      > * *5. mailto:[20]nicholas.marri...@gmail.com
> >      > * *6. [21]http://p.sf.net/sfu/appdyn_d2d_feb
> >      > * *7. mailto:[22]tmux-users@lists.sourceforge.net
> >      > * *8. [23]https://lists.sourceforge.net/lists/listinfo/tmux-users
> >      > * *9. mailto:[24]aaronjen...@gmail.com
> >      > * 10. mailto:[25]nicholas.marri...@gmail.com
> >      > * 11. mailto:[26]nicholas.marri...@gmail.com
> >      > * 12. [27]http://p.sf.net/sfu/appdyn_d2d_feb
> >      > * 13. mailto:[28]tmux-users@lists.sourceforge.net
> >      > * 14. [29]https://lists.sourceforge.net/lists/listinfo/tmux-users
> > 
> > References
> > 
> >    Visible links
> >    1. mailto:nicholas.marri...@gmail.com
> >    2. http://dl.dropbox.com/u/113468811/Screenshots/nafczt3h0xb_.png
> >    3. mailto:nicholas.marri...@gmail.com
> >    4. mailto:aaronjen...@gmail.com
> >    5. mailto:nicholas.marri...@gmail.com
> >    6. mailto:nicholas.marri...@gmail.com
> >    7. http://p.sf.net/sfu/appdyn_d2d_feb
> >    8. mailto:tmux-users@lists.sourceforge.net
> >    9. https://lists.sourceforge.net/lists/listinfo/tmux-users
> >   10. mailto:aaronjen...@gmail.com
> >   11. mailto:nicholas.marri...@gmail.com
> >   12. mailto:nicholas.marri...@gmail.com
> >   13. http://p.sf.net/sfu/appdyn_d2d_feb
> >   14. mailto:tmux-users@lists.sourceforge.net
> >   15. https://lists.sourceforge.net/lists/listinfo/tmux-users
> >   16. http://dl.dropbox.com/u/113468811/Screenshots/nafczt3h0xb_.png
> >   17. mailto:nicholas.marri...@gmail.com
> >   18. mailto:aaronjen...@gmail.com
> >   19. mailto:nicholas.marri...@gmail.com
> >   20. mailto:nicholas.marri...@gmail.com
> >   21. http://p.sf.net/sfu/appdyn_d2d_feb
> >   22. mailto:tmux-users@lists.sourceforge.net
> >   23. https://lists.sourceforge.net/lists/listinfo/tmux-users
> >   24. mailto:aaronjen...@gmail.com
> >   25. mailto:nicholas.marri...@gmail.com
> >   26. mailto:nicholas.marri...@gmail.com
> >   27. http://p.sf.net/sfu/appdyn_d2d_feb
> >   28. mailto:tmux-users@lists.sourceforge.net
> >   29. https://lists.sourceforge.net/lists/listinfo/tmux-users
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index a4350fe..4f329e5 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;
+       server_unzoom_window(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..41b532c 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;
+       server_unzoom_window(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;
+       server_unzoom_window(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..f0a17ad 100644
--- a/cmd-kill-pane.c
+++ b/cmd-kill-pane.c
@@ -47,6 +47,7 @@ cmd_kill_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);
+       server_unzoom_window(wl->window);
 
        if (window_count_panes(wl->window) == 1) {
                /* Only one pane, kill the window. */
diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c
index 328e1b4..b056b8f 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,18 @@ 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);
+               server_redraw_window(w);
+               server_status_window(w);
+               return (CMD_RETURN_NORMAL);
+       }
+       server_unzoom_window(w);
 
        if (args->argc == 0)
                adjust = 1;
diff --git a/cmd-select-layout.c b/cmd-select-layout.c
index b2423e9..7e7e35e 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);
+       server_unzoom_window(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..71882e4 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);
        }
+       server_unzoom_window(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..a21ff77 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;
+       server_unzoom_window(w);
 
        environ_init(&env);
        environ_copy(&global_environ, &env);
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 42fe2fc..cc9e7df 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;
+       server_unzoom_window(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;
        }
+       server_unzoom_window(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/resize.c b/resize.c
index a560958..90212b2 100644
--- a/resize.c
+++ b/resize.c
@@ -50,7 +50,7 @@ recalculate_sizes(void)
        struct window           *w;
        struct window_pane      *wp;
        u_int                    i, j, ssx, ssy, has, limit;
-       int                      flag, has_status;
+       int                      flag, has_status, is_zoomed;
 
        RB_FOREACH(s, sessions, &sessions) {
                has_status = options_get_number(&s->options, "status");
@@ -123,12 +123,16 @@ recalculate_sizes(void)
 
                if (w->sx == ssx && w->sy == ssy)
                        continue;
-
                log_debug("window size %u,%u (was %u,%u)", ssx, ssy, w->sx,
                    w->sy);
 
+               is_zoomed = !TAILQ_EMPTY(&w->saved_panes);
+               if (is_zoomed)
+                       window_unzoom(w);
                layout_resize(w, ssx, ssy);
                window_resize(w, ssx, ssy);
+               if (is_zoomed && window_pane_visible(w->active))
+                       window_zoom(w->active);
 
                /*
                 * If the current pane is now not visible, move to the next
diff --git a/server-client.c b/server-client.c
index d9a647e..3c14ff8 100644
--- a/server-client.c
+++ b/server-client.c
@@ -28,6 +28,7 @@
 #include "tmux.h"
 
 void   server_client_check_focus(struct window_pane *);
+void   server_client_check_resize(struct window_pane *);
 void   server_client_check_mouse(struct client *, struct window_pane *);
 void   server_client_repeat_timer(int, short, void *);
 void   server_client_check_exit(struct client *);
@@ -495,7 +496,7 @@ server_client_loop(void)
 
        /*
         * Any windows will have been redrawn as part of clients, so clear
-        * their flags now. Also check and update pane focus.
+        * their flags now. Also check pane focus and resize.
         */
        for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
                w = ARRAY_ITEM(&windows, i);
@@ -505,11 +506,41 @@ server_client_loop(void)
                w->flags &= ~WINDOW_REDRAW;
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        server_client_check_focus(wp);
+                       server_client_check_resize(wp);
                        wp->flags &= ~PANE_REDRAW;
                }
        }
 }
 
+/* Check if pane should be resized. */
+void
+server_client_check_resize(struct window_pane *wp)
+{
+       struct winsize  ws;
+
+       if (wp->fd == -1 || !(wp->flags & PANE_RESIZE))
+               return;
+
+       memset(&ws, 0, sizeof ws);
+       ws.ws_col = wp->sx;
+       ws.ws_row = wp->sy;
+
+       if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) {
+#ifdef __sun
+               /*
+                * Some versions of Solaris apparently can return an error when
+                * resizing; don't know why this happens, can't reproduce on
+                * other platforms and ignoring it doesn't seem to cause any
+                * issues.
+                */
+               if (errno != EINVAL)
+#endif
+               fatal("ioctl failed");
+       }
+
+       wp->flags &= ~PANE_RESIZE;
+}
+
 /* Check whether pane should be focused. */
 void
 server_client_check_focus(struct window_pane *wp)
diff --git a/server-fn.c b/server-fn.c
index 26f93d9..f17c3b1 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -377,6 +377,7 @@ server_destroy_pane(struct window_pane *wp)
                return;
        }
 
+       server_unzoom_window(w);
        layout_close_pane(wp);
        window_remove_pane(w, wp);
 
@@ -588,3 +589,11 @@ server_set_stdin_callback(struct client *c, void 
(*cb)(struct client *, int,
 
        return (0);
 }
+
+void
+server_unzoom_window(struct window *w)
+{
+       window_unzoom(w);
+       server_redraw_window(w);
+       server_status_window(w);
+}
diff --git a/tmux.1 b/tmux.1
index 8731efb..2f85a35 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1572,7 +1572,7 @@ Rename the current window, or the window at
 if specified, to
 .Ar new-name .
 .It Xo Ic resize-pane
-.Op Fl DLRU
+.Op Fl DLRUZ
 .Op Fl t Ar target-pane
 .Op Fl x Ar width
 .Op Fl y Ar height
@@ -1596,6 +1596,11 @@ or
 The
 .Ar adjustment
 is given in lines or cells (the default is 1).
+.Pp
+With
+.Fl Z ,
+the active pane is toggled between occupying the whole of the window and it's
+normal position in the layout.
 .It Xo Ic respawn-pane
 .Op Fl k
 .Op Fl t Ar target-pane
diff --git a/tmux.h b/tmux.h
index 8c06197..144433c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -928,6 +928,8 @@ struct window_pane {
 #define PANE_REDRAW 0x1
 #define PANE_DROP 0x2
 #define PANE_FOCUSED 0x4
+#define PANE_HIDDEN 0x8
+#define PANE_RESIZE 0x10
 
        char            *cmd;
        char            *shell;
@@ -978,6 +980,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;
 
@@ -1910,6 +1918,7 @@ void       server_push_stdout(struct client *);
 void    server_push_stderr(struct client *);
 int     server_set_stdin_callback(struct client *, void (*)(struct client *,
             int, void *), void *, char **);
+void    server_unzoom_window(struct window *);
 
 /* status.c */
 int     status_out_cmp(struct status_out *, struct status_out *);
@@ -2113,6 +2122,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..00eb3e6 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;
 
@@ -333,6 +334,8 @@ window_destroy(struct window *w)
 {
        u_int   i;
 
+       window_unzoom(w);
+
        if (window_index(w, &i) != 0)
                fatalx("index not found");
        ARRAY_SET(&windows, i, NULL);
@@ -455,6 +458,75 @@ 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) {
+               wp1->flags |= PANE_HIDDEN;
+               RB_REMOVE(window_pane_tree, &all_window_panes, wp1);
+       }
+
+       w->saved_cell = wp->layout_cell;
+       w->saved_layout = w->layout_root;
+       layout_init(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) {
+               wp1->flags &= ~PANE_HIDDEN;
+               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);
+
+       return (0);
+}
+
 struct window_pane *
 window_add_pane(struct window *w, u_int hlimit)
 {
@@ -585,6 +657,8 @@ window_printable_flags(struct session *s, struct winlink 
*wl)
                flags[pos++] = '*';
        if (wl == TAILQ_FIRST(&s->lastw))
                flags[pos++] = '-';
+       if (!TAILQ_EMPTY(&wl->window->saved_panes))
+               flags[pos++] = 'Z';
        if (pos == 0)
                flags[pos++] = ' ';
        flags[pos] = '\0';
@@ -841,32 +915,16 @@ window_pane_error_callback(
 void
 window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
 {
-       struct winsize  ws;
-
        if (sx == wp->sx && sy == wp->sy)
                return;
        wp->sx = sx;
        wp->sy = sy;
 
-       memset(&ws, 0, sizeof ws);
-       ws.ws_col = sx;
-       ws.ws_row = sy;
-
        screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
        if (wp->mode != NULL)
                wp->mode->resize(wp, sx, sy);
 
-       if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
-#ifdef __sun
-               /*
-                * Some versions of Solaris apparently can return an error when
-                * resizing; don't know why this happens, can't reproduce on
-                * other platforms and ignoring it doesn't seem to cause any
-                * issues.
-                */
-               if (errno != EINVAL)
-#endif
-               fatal("ioctl failed");
+       wp->flags |= PANE_RESIZE;
 }
 
 /*
@@ -1032,6 +1090,8 @@ window_pane_visible(struct window_pane *wp)
 {
        struct window   *w = wp->window;
 
+       if (wp->flags & PANE_HIDDEN)
+               return (0);
        if (wp->xoff >= w->sx || wp->yoff >= w->sy)
                return (0);
        if (wp->xoff + wp->sx > w->sx || wp->yoff + wp->sy > w->sy)
------------------------------------------------------------------------------
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

Reply via email to