summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/layout.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2010-06-29 03:30:15 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2010-06-29 03:30:15 +0000
commit27d18160c9396db3e3b2cb67151fb869a9a704f3 (patch)
tree94dbad3c698eabf4a186a0ac507bc50b8a98e3b6 /usr.bin/tmux/layout.c
parent8e604a37f5b8e2b615a0262254283428820ec4c4 (diff)
Custom layouts. list-windows command displays the layout as a string (such as
"bb62,159x48,0,0{79x48,0,0,79x48,80,0}") and it can be applied to another window (with the same number of panes or fewer) using select-layout.
Diffstat (limited to 'usr.bin/tmux/layout.c')
-rw-r--r--usr.bin/tmux/layout.c130
1 files changed, 79 insertions, 51 deletions
diff --git a/usr.bin/tmux/layout.c b/usr.bin/tmux/layout.c
index 0c0c82aeaad..703d1ff97c7 100644
--- a/usr.bin/tmux/layout.c
+++ b/usr.bin/tmux/layout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: layout.c,v 1.5 2010/01/07 20:52:18 nicm Exp $ */
+/* $OpenBSD: layout.c,v 1.6 2010/06/29 03:30:14 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -218,6 +218,27 @@ layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
}
}
+/* Count the number of available cells in a layout. */
+u_int
+layout_count_cells(struct layout_cell *lc)
+{
+ struct layout_cell *lcchild;
+ u_int n;
+
+ switch (lc->type) {
+ case LAYOUT_WINDOWPANE:
+ return (1);
+ case LAYOUT_LEFTRIGHT:
+ case LAYOUT_TOPBOTTOM:
+ n = 0;
+ TAILQ_FOREACH(lcchild, &lc->cells, entry)
+ n += layout_count_cells(lcchild);
+ return (n);
+ default:
+ fatalx("bad layout type");
+ }
+}
+
/* Calculate how much size is available to be removed from a cell. */
u_int
layout_resize_check(struct layout_cell *lc, enum layout_type type)
@@ -302,6 +323,56 @@ layout_resize_adjust(struct layout_cell *lc, enum layout_type type, int change)
}
}
+/* Destroy a cell and redistribute the space. */
+void
+layout_destroy_cell(struct layout_cell *lc, struct layout_cell **lcroot)
+{
+ struct layout_cell *lcother, *lcparent;
+
+ /*
+ * If no parent, this is the last pane so window close is imminent and
+ * there is no need to resize anything.
+ */
+ lcparent = lc->parent;
+ if (lcparent == NULL) {
+ layout_free_cell(lc);
+ *lcroot = NULL;
+ return;
+ }
+
+ /* Merge the space into the previous or next cell. */
+ if (lc == TAILQ_FIRST(&lcparent->cells))
+ lcother = TAILQ_NEXT(lc, entry);
+ else
+ lcother = TAILQ_PREV(lc, layout_cells, entry);
+ if (lcparent->type == LAYOUT_LEFTRIGHT)
+ layout_resize_adjust(lcother, lcparent->type, lc->sx + 1);
+ else
+ layout_resize_adjust(lcother, lcparent->type, lc->sy + 1);
+
+ /* Remove this from the parent's list. */
+ TAILQ_REMOVE(&lcparent->cells, lc, entry);
+ layout_free_cell(lc);
+
+ /*
+ * If the parent now has one cell, remove the parent from the tree and
+ * replace it by that cell.
+ */
+ lc = TAILQ_FIRST(&lcparent->cells);
+ if (TAILQ_NEXT(lc, entry) == NULL) {
+ TAILQ_REMOVE(&lcparent->cells, lc, entry);
+
+ lc->parent = lcparent->parent;
+ if (lc->parent == NULL) {
+ lc->xoff = 0; lc->yoff = 0;
+ *lcroot = lc;
+ } else
+ TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
+
+ layout_free_cell(lcparent);
+ }
+}
+
void
layout_init(struct window *w)
{
@@ -597,59 +668,16 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size)
return (lcnew);
}
-/* Destroy the layout associated with a pane and redistribute the space. */
+/* Destroy the cell associated with a pane. */
void
layout_close_pane(struct window_pane *wp)
{
- struct layout_cell *lc, *lcother, *lcparent;
-
- lc = wp->layout_cell;
- lcparent = lc->parent;
-
- /*
- * If no parent, this is the last pane so window close is imminent and
- * there is no need to resize anything.
- */
- if (lcparent == NULL) {
- layout_free_cell(lc);
- wp->window->layout_root = NULL;
- return;
- }
-
- /* Merge the space into the previous or next cell. */
- if (lc == TAILQ_FIRST(&lcparent->cells))
- lcother = TAILQ_NEXT(lc, entry);
- else
- lcother = TAILQ_PREV(lc, layout_cells, entry);
- if (lcparent->type == LAYOUT_LEFTRIGHT)
- layout_resize_adjust(lcother, lcparent->type, lc->sx + 1);
- else
- layout_resize_adjust(lcother, lcparent->type, lc->sy + 1);
-
- /* Remove this from the parent's list. */
- TAILQ_REMOVE(&lcparent->cells, lc, entry);
- layout_free_cell(lc);
-
- /*
- * If the parent now has one cell, remove the parent from the tree and
- * replace it by that cell.
- */
- lc = TAILQ_FIRST(&lcparent->cells);
- if (TAILQ_NEXT(lc, entry) == NULL) {
- TAILQ_REMOVE(&lcparent->cells, lc, entry);
-
- lc->parent = lcparent->parent;
- if (lc->parent == NULL) {
- lc->xoff = 0; lc->yoff = 0;
- wp->window->layout_root = lc;
- } else
- TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
-
- layout_free_cell(lcparent);
- }
+ /* Remove the cell. */
+ layout_destroy_cell(wp->layout_cell, &wp->window->layout_root);
/* Fix pane offsets and sizes. */
- layout_fix_offsets(wp->window->layout_root);
- layout_fix_panes(wp->window, wp->window->sx, wp->window->sy);
+ if (wp->window->layout_root != NULL) {
+ layout_fix_offsets(wp->window->layout_root);
+ layout_fix_panes(wp->window, wp->window->sx, wp->window->sy);
+ }
}
-