From ab4e5e8574c3ccffeed275eeebc4845e3f33acab Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 18 May 2009 21:01:38 +0000 Subject: [PATCH] Clean up manual layout code: - change the one layout function into two _refresh and _resize - create layout-manual.c for manual layout code - move the fit panes/update panes code from window.c to the new file as it is only used by manual layout now - move the resize pane code into layout-manual.c as well - get rid of the direct calls to fit/update and make them go through layout - rename a couple of variables This is mainly as a first step before reworking the manual layout code to see if anything breaks. --- cmd-break-pane.c | 8 +- cmd-resize-pane.c | 61 ++-------------- layout-manual.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++ layout.c | 75 +++++++++---------- tmux.h | 9 ++- window.c | 105 +------------------------- 6 files changed, 233 insertions(+), 208 deletions(-) create mode 100644 layout-manual.c diff --git a/cmd-break-pane.c b/cmd-break-pane.c index e8e3f945..88271971 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-break-pane.c,v 1.2 2009-05-04 17:58:26 nicm Exp $ */ +/* $Id: cmd-break-pane.c,v 1.3 2009-05-18 21:01:38 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -74,18 +74,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) if (wl->window->active == NULL) wl->window->active = TAILQ_NEXT(wp, entry); } - window_fit_panes(wl->window); + layout_refresh(wl->window, 0); w = wp->window = window_create1(s->sx, s->sy); TAILQ_INSERT_HEAD(&w->panes, wp, entry); w->active = wp; - window_fit_panes(w); w->name = default_window_name(w); wl = session_attach(s, w, -1, &cause); /* can't fail */ - if (!(data->flags & CMD_DFLAG)) session_select(s, wl->idx); + layout_refresh(w, 0); + server_redraw_session(s); return (0); diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index f3b82888..63b18dcb 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-resize-pane.c,v 1.4 2009-05-18 20:18:08 nicm Exp $ */ +/* $Id: cmd-resize-pane.c,v 1.5 2009-05-18 21:01:38 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -67,15 +67,11 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_pane_data *data = self->data; struct winlink *wl; const char *errstr; - struct window_pane *wp, *wq; + struct window_pane *wp; u_int adjust; if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return (-1); - if (wl->window->layout != 0) { - ctx->error(ctx, "window not in manual layout"); - return (-1); - } if (data->pane == -1) wp = wl->window->active; else { @@ -96,55 +92,10 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) } } - if (data->flags & CMD_UPPERDFLAG) { - /* - * If this is not the last pane, keep trying to increase size - * and remove it from the next panes. If it is the last, do - * so on the previous pane. - */ - if (TAILQ_NEXT(wp, entry) == NULL) { - if (wp == TAILQ_FIRST(&wl->window->panes)) { - /* Only one pane. */ - return (0); - } - wp = TAILQ_PREV(wp, window_panes, entry); - } - while (adjust-- > 0) { - wq = wp; - while ((wq = TAILQ_NEXT(wq, entry)) != NULL) { - if (wq->sy <= PANE_MINIMUM) - continue; - window_pane_resize(wq, wq->sx, wq->sy - 1); - break; - } - if (wq == NULL) - break; - window_pane_resize(wp, wp->sx, wp->sy + 1); - } - } else { - /* - * If this is not the last pane, keep trying to reduce size - * and add to the following pane. If it is the last, do so on - * the previous pane. - */ - wq = TAILQ_NEXT(wp, entry); - if (wq == NULL) { - if (wp == TAILQ_FIRST(&wl->window->panes)) { - /* Only one pane. */ - return (0); - } - wq = wp; - wp = TAILQ_PREV(wq, window_panes, entry); - } - while (adjust-- > 0) { - if (wp->sy <= PANE_MINIMUM) - break; - window_pane_resize(wq, wq->sx, wq->sy + 1); - window_pane_resize(wp, wp->sx, wp->sy - 1); - } - } - window_update_panes(wl->window); - + if (data->flags & CMD_UPPERDFLAG) + layout_resize(wp, adjust); + else + layout_resize(wp, -adjust); server_redraw_window(wl->window); return (0); diff --git a/layout-manual.c b/layout-manual.c new file mode 100644 index 00000000..46a49320 --- /dev/null +++ b/layout-manual.c @@ -0,0 +1,183 @@ +/* $Id: layout-manual.c,v 1.1 2009-05-18 21:01:38 nicm Exp $ */ + +/* + * Copyright (c) 2009 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "tmux.h" + +void layout_manual_update_offsets(struct window *); + +void +layout_manual_refresh(struct window *w, unused int active_only) +{ + struct window_pane *wp; + u_int npanes, canfit, total; + int left; + + if (active_only) + return; + + if (TAILQ_EMPTY(&w->panes)) + return; + + /* Clear hidden flags. */ + TAILQ_FOREACH(wp, &w->panes, entry) + wp->flags &= ~PANE_HIDDEN; + + /* Check the new size. */ + npanes = window_count_panes(w); + if (w->sy <= PANE_MINIMUM * npanes) { + /* How many can we fit? */ + canfit = w->sy / PANE_MINIMUM; + if (canfit == 0) { + /* None. Just use this size for the first. */ + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp == TAILQ_FIRST(&w->panes)) + wp->sy = w->sy; + else + wp->flags |= PANE_HIDDEN; + } + } else { + /* >=1, set minimum for them all. */ + TAILQ_FOREACH(wp, &w->panes, entry) { + if (canfit-- > 0) + wp->sy = PANE_MINIMUM - 1; + else + wp->flags |= PANE_HIDDEN; + } + /* And increase the first by the rest. */ + TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM; + } + } else { + /* In theory they will all fit. Find the current total. */ + total = 0; + TAILQ_FOREACH(wp, &w->panes, entry) + total += wp->sy; + total += npanes - 1; + + /* Growing or shrinking? */ + left = w->sy - total; + if (left > 0) { + /* Growing. Expand evenly. */ + while (left > 0) { + TAILQ_FOREACH(wp, &w->panes, entry) { + wp->sy++; + if (--left == 0) + break; + } + } + } else { + /* Shrinking. Reduce evenly down to minimum. */ + while (left < 0) { + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp->sy <= PANE_MINIMUM - 1) + continue; + wp->sy--; + if (++left == 0) + break; + } + } + } + } + + /* Now do the resize. */ + TAILQ_FOREACH(wp, &w->panes, entry) { + wp->sy--; + window_pane_resize(wp, w->sx, wp->sy + 1); + } + + /* Fill in the offsets. */ + layout_manual_update_offsets(w); + + /* Switch the active window if necessary. */ + window_set_active_pane(w, w->active); +} + +void +layout_manual_resize(struct window_pane *wp, int adjust) +{ + struct window *w = wp->window; + struct window_pane *wq; + + if (adjust > 0) { + /* + * If this is not the last pane, keep trying to increase size + * and remove it from the next panes. If it is the last, do + * so on the previous pane. + */ + if (TAILQ_NEXT(wp, entry) == NULL) { + if (wp == TAILQ_FIRST(&w->panes)) { + /* Only one pane. */ + return; + } + wp = TAILQ_PREV(wp, window_panes, entry); + } + while (adjust-- > 0) { + wq = wp; + while ((wq = TAILQ_NEXT(wq, entry)) != NULL) { + if (wq->sy <= PANE_MINIMUM) + continue; + window_pane_resize(wq, wq->sx, wq->sy - 1); + break; + } + if (wq == NULL) + break; + window_pane_resize(wp, wp->sx, wp->sy + 1); + } + } else { + adjust = -adjust; + /* + * If this is not the last pane, keep trying to reduce size + * and add to the following pane. If it is the last, do so on + * the previous pane. + */ + wq = TAILQ_NEXT(wp, entry); + if (wq == NULL) { + if (wp == TAILQ_FIRST(&w->panes)) { + /* Only one pane. */ + return; + } + wq = wp; + wp = TAILQ_PREV(wq, window_panes, entry); + } + while (adjust-- > 0) { + if (wp->sy <= PANE_MINIMUM) + break; + window_pane_resize(wq, wq->sx, wq->sy + 1); + window_pane_resize(wp, wp->sx, wp->sy - 1); + } + } + + layout_manual_update_offsets(w); +} + +void +layout_manual_update_offsets(struct window *w) +{ + struct window_pane *wp; + u_int yoff; + + yoff = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp->flags & PANE_HIDDEN) + continue; + wp->xoff = 0; + wp->yoff = yoff; + yoff += wp->sy + 1; + } +} diff --git a/layout.c b/layout.c index a97cecf9..6ebe0712 100644 --- a/layout.c +++ b/layout.c @@ -1,4 +1,4 @@ -/* $Id: layout.c,v 1.7 2009-05-16 11:48:47 nicm Exp $ */ +/* $Id: layout.c,v 1.8 2009-05-18 21:01:38 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -23,25 +23,29 @@ #include "tmux.h" /* - * Layout functions: second argument (int) is 1 if definitely the /only/ change - * has been the active pane has changed. If 0 then panes, active pane or both - * may have changed. + * Each layout has two functions, _refresh to relayout the panes and _resize to + * resize a single pane. + * + * Second argument (int) to _refresh is 1 if the only change has been that the + * active pane has changed. If 0 then panes, active pane or both may have + * changed. */ -void layout_manual(struct window *, int); -void layout_active_only(struct window *, int); -void layout_even_horizontal(struct window *, int); -void layout_even_vertical(struct window *, int); -void layout_left_vertical(struct window *, int); + +void layout_active_only_refresh(struct window *, int); +void layout_even_horizontal_refresh(struct window *, int); +void layout_even_vertical_refresh(struct window *, int); +void layout_left_vertical_refresh(struct window *, int); const struct { - const char *name; - void (*fn)(struct window *, int); + const char *name; + void (*refresh)(struct window *, int); + void (*resize)(struct window_pane *, int); } layouts[] = { - { "manual", layout_manual }, - { "active-only", layout_active_only }, - { "even-horizontal", layout_even_horizontal }, - { "even-vertical", layout_even_vertical }, - { "left-vertical", layout_left_vertical }, + { "manual", layout_manual_refresh, layout_manual_resize }, + { "active-only", layout_active_only_refresh, NULL }, + { "even-horizontal", layout_even_horizontal_refresh, NULL }, + { "even-vertical", layout_even_vertical_refresh, NULL }, + { "left-vertical", layout_left_vertical_refresh, NULL }, }; const char * @@ -74,11 +78,6 @@ layout_select(struct window *w, u_int layout) return (-1); w->layout = layout; - if (w->layout == 0) { - /* XXX Special-case manual. */ - window_fit_panes(w); - window_update_panes(w); - } layout_refresh(w, 0); return (0); } @@ -87,12 +86,8 @@ void layout_next(struct window *w) { w->layout++; - if (w->layout > nitems(layouts) - 1) { + if (w->layout > nitems(layouts) - 1) w->layout = 0; - /* XXX Special-case manual. */ - window_fit_panes(w); - window_update_panes(w); - } layout_refresh(w, 0); } @@ -103,28 +98,24 @@ layout_previous(struct window *w) w->layout = nitems(layouts) - 1; else w->layout--; - if (w->layout == 0) { - /* XXX Special-case manual. */ - window_fit_panes(w); - window_update_panes(w); - } layout_refresh(w, 0); } void -layout_refresh(struct window *w, unused int active_changed) +layout_refresh(struct window *w, int active_only) { - layouts[w->layout].fn(w, active_changed); + layouts[w->layout].refresh(w, active_only); server_redraw_window(w); } void -layout_manual(unused struct window *w, unused int active_changed) +layout_resize(struct window_pane *wp, int adjust) { + layouts[wp->window->layout].resize(wp, adjust); } void -layout_active_only(struct window *w, unused int active_changed) +layout_active_only_refresh(struct window *w, unused int active_only) { struct window_pane *wp; @@ -139,12 +130,12 @@ layout_active_only(struct window *w, unused int active_changed) } void -layout_even_horizontal(struct window *w, int active_changed) +layout_even_horizontal_refresh(struct window *w, int active_only) { struct window_pane *wp; u_int i, n, width, xoff; - if (active_changed) + if (active_only) return; /* Get number of panes. */ @@ -187,12 +178,12 @@ layout_even_horizontal(struct window *w, int active_changed) } void -layout_even_vertical(struct window *w, int active_changed) +layout_even_vertical_refresh(struct window *w, int active_only) { struct window_pane *wp; u_int i, n, height, yoff; - if (active_changed) + if (active_only) return; /* Get number of panes. */ @@ -235,12 +226,12 @@ layout_even_vertical(struct window *w, int active_changed) } void -layout_left_vertical(struct window *w, int active_changed) +layout_left_vertical_refresh(struct window *w, int active_only) { struct window_pane *wp; u_int i, n, height, yoff; - if (active_changed) + if (active_only) return; /* Get number of panes. */ @@ -250,7 +241,7 @@ layout_left_vertical(struct window *w, int active_changed) /* Need >1 pane and minimum columns; if fewer, display active only. */ if (n == 1 || w->sx < 82 + PANE_MINIMUM) { - layout_active_only(w, active_changed); + layout_active_only_refresh(w, active_only); return; } n--; diff --git a/tmux.h b/tmux.h index e58ac097..6c2a2e85 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.318 2009-05-16 11:48:47 nicm Exp $ */ +/* $Id: tmux.h,v 1.319 2009-05-18 21:01:38 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1549,8 +1549,6 @@ struct window_pane *window_add_pane(struct window *, int, void window_remove_pane(struct window *, struct window_pane *); u_int window_index_of_pane(struct window *, struct window_pane *); struct window_pane *window_pane_at_index(struct window *, u_int); -void window_fit_panes(struct window *); -void window_update_panes(struct window *); u_int window_count_panes(struct window *); void window_destroy_panes(struct window *); struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int); @@ -1571,10 +1569,15 @@ void window_pane_mouse(struct window_pane *, const char * layout_name(struct window *); int layout_lookup(const char *); void layout_refresh(struct window *, int); +void layout_resize(struct window_pane *, int); int layout_select(struct window *, u_int); void layout_next(struct window *); void layout_previous(struct window *); +/* layout-manual.c */ +void layout_manual_refresh(struct window *, int); +void layout_manual_resize(struct window_pane *, int); + /* window-clock.c */ extern const struct window_mode window_clock_mode; diff --git a/window.c b/window.c index 787700a4..4836f0cb 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.76 2009-05-15 12:58:56 nicm Exp $ */ +/* $Id: window.c,v 1.77 2009-05-18 21:01:38 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -279,109 +279,9 @@ window_resize(struct window *w, u_int sx, u_int sy) w->sx = sx; w->sy = sy; - window_fit_panes(w); return (0); } -void -window_fit_panes(struct window *w) -{ - struct window_pane *wp; - u_int npanes, canfit, total; - int left; - - if (TAILQ_EMPTY(&w->panes)) - return; - - /* Clear hidden flags. */ - TAILQ_FOREACH(wp, &w->panes, entry) - wp->flags &= ~PANE_HIDDEN; - - /* Check the new size. */ - npanes = window_count_panes(w); - if (w->sy <= PANE_MINIMUM * npanes) { - /* How many can we fit? */ - canfit = w->sy / PANE_MINIMUM; - if (canfit == 0) { - /* None. Just use this size for the first. */ - TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp == TAILQ_FIRST(&w->panes)) - wp->sy = w->sy; - else - wp->flags |= PANE_HIDDEN; - } - } else { - /* >=1, set minimum for them all. */ - TAILQ_FOREACH(wp, &w->panes, entry) { - if (canfit-- > 0) - wp->sy = PANE_MINIMUM - 1; - else - wp->flags |= PANE_HIDDEN; - } - /* And increase the first by the rest. */ - TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM; - } - } else { - /* In theory they will all fit. Find the current total. */ - total = 0; - TAILQ_FOREACH(wp, &w->panes, entry) - total += wp->sy; - total += npanes - 1; - - /* Growing or shrinking? */ - left = w->sy - total; - if (left > 0) { - /* Growing. Expand evenly. */ - while (left > 0) { - TAILQ_FOREACH(wp, &w->panes, entry) { - wp->sy++; - if (--left == 0) - break; - } - } - } else { - /* Shrinking. Reduce evenly down to minimum. */ - while (left < 0) { - TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp->sy <= PANE_MINIMUM - 1) - continue; - wp->sy--; - if (++left == 0) - break; - } - } - } - } - - /* Now do the resize. */ - TAILQ_FOREACH(wp, &w->panes, entry) { - wp->sy--; - window_pane_resize(wp, w->sx, wp->sy + 1); - } - - /* Fill in the offsets. */ - window_update_panes(w); - - /* Switch the active window if necessary. */ - window_set_active_pane(w, w->active); -} - -void -window_update_panes(struct window *w) -{ - struct window_pane *wp; - u_int yoff; - - yoff = 0; - TAILQ_FOREACH(wp, &w->panes, entry) { - if (wp->flags & PANE_HIDDEN) - continue; - wp->xoff = 0; - wp->yoff = yoff; - yoff += wp->sy + 1; - } -} - void window_set_active_pane(struct window *w, struct window_pane *wp) { @@ -422,7 +322,6 @@ window_add_pane(struct window *w, int wanty, const char *cmd, TAILQ_INSERT_HEAD(&w->panes, wp, entry); else TAILQ_INSERT_AFTER(&w->panes, w->active, wp, entry); - window_update_panes(w); if (window_pane_spawn(wp, cmd, cwd, envp, cause) != 0) { window_remove_pane(w, wp); return (NULL); @@ -439,8 +338,6 @@ window_remove_pane(struct window *w, struct window_pane *wp) TAILQ_REMOVE(&w->panes, wp, entry); window_pane_destroy(wp); - - window_fit_panes(w); } u_int