=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/layout.c,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** src/usr.bin/tmux/layout.c 2010/01/07 20:52:18 1.5 --- src/usr.bin/tmux/layout.c 2010/06/29 03:30:14 1.6 *************** *** 1,4 **** ! /* $OpenBSD: layout.c,v 1.5 2010/01/07 20:52:18 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: layout.c,v 1.6 2010/06/29 03:30:14 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott *************** *** 218,223 **** --- 218,244 ---- } } + /* 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,308 **** --- 323,379 ---- } } + /* 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) { struct layout_cell *lc; *************** *** 597,655 **** return (lcnew); } ! /* Destroy the layout associated with a pane and redistribute the space. */ 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); - } - /* Fix pane offsets and sizes. */ ! layout_fix_offsets(wp->window->layout_root); ! layout_fix_panes(wp->window, wp->window->sx, wp->window->sy); } - --- 668,683 ---- return (lcnew); } ! /* Destroy the cell associated with a pane. */ void layout_close_pane(struct window_pane *wp) { ! /* Remove the cell. */ ! layout_destroy_cell(wp->layout_cell, &wp->window->layout_root); /* Fix pane offsets and sizes. */ ! if (wp->window->layout_root != NULL) { ! layout_fix_offsets(wp->window->layout_root); ! layout_fix_panes(wp->window, wp->window->sx, wp->window->sy); ! } }