From 07b9118757e9e056d487d8ec6350b1321082e175 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 3 Aug 2016 09:07:02 +0000 Subject: [PATCH] Fix minimum size when pane status line is enabled, reported by Y Petremann. --- usr.bin/tmux/layout-custom.c | 4 +- usr.bin/tmux/layout-set.c | 26 +++++---- usr.bin/tmux/layout.c | 100 ++++++++++++++++++++--------------- usr.bin/tmux/tmux.h | 9 ++-- 4 files changed, 79 insertions(+), 60 deletions(-) diff --git a/usr.bin/tmux/layout-custom.c b/usr.bin/tmux/layout-custom.c index ced239ba7d0..dd386a11e90 100644 --- a/usr.bin/tmux/layout-custom.c +++ b/usr.bin/tmux/layout-custom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout-custom.c,v 1.9 2016/07/15 09:27:35 nicm Exp $ */ +/* $OpenBSD: layout-custom.c,v 1.10 2016/08/03 09:07:02 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott @@ -150,7 +150,7 @@ layout_parse(struct window *w, const char *layout) /* Fewer panes than cells - close the bottom right. */ lcchild = layout_find_bottomright(lc); - layout_destroy_cell(lcchild, &lc); + layout_destroy_cell(w, lcchild, &lc); } /* Save the old window size and resize to the layout size. */ diff --git a/usr.bin/tmux/layout-set.c b/usr.bin/tmux/layout-set.c index 59351a561f3..dfea56a01ed 100644 --- a/usr.bin/tmux/layout-set.c +++ b/usr.bin/tmux/layout-set.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout-set.c,v 1.14 2016/01/19 15:59:12 nicm Exp $ */ +/* $OpenBSD: layout-set.c,v 1.15 2016/08/03 09:07:02 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -155,7 +155,8 @@ layout_set_even_h(struct window *w) /* Allocate any remaining space. */ if (w->sx > xoff - 1) { lc = TAILQ_LAST(&lc->cells, layout_cells); - layout_resize_adjust(lc, LAYOUT_LEFTRIGHT, w->sx - (xoff - 1)); + layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, + w->sx - (xoff - 1)); } /* Fix cell offsets. */ @@ -208,7 +209,8 @@ layout_set_even_v(struct window *w) /* Allocate any remaining space. */ if (w->sy > yoff - 1) { lc = TAILQ_LAST(&lc->cells, layout_cells); - layout_resize_adjust(lc, LAYOUT_TOPBOTTOM, w->sy - (yoff - 1)); + layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, + w->sy - (yoff - 1)); } /* Fix cell offsets. */ @@ -322,14 +324,16 @@ layout_set_main_h(struct window *w) if (w->sx <= used) continue; lcchild = TAILQ_LAST(&lcrow->cells, layout_cells); - layout_resize_adjust(lcchild, LAYOUT_LEFTRIGHT, w->sx - used); + layout_resize_adjust(w, lcchild, LAYOUT_LEFTRIGHT, + w->sx - used); } /* Adjust the last row height to fit if necessary. */ used = mainheight + (rows * height) + rows - 1; if (w->sy > used) { lcrow = TAILQ_LAST(&lc->cells, layout_cells); - layout_resize_adjust(lcrow, LAYOUT_TOPBOTTOM, w->sy - used); + layout_resize_adjust(w, lcrow, LAYOUT_TOPBOTTOM, + w->sy - used); } /* Fix cell offsets. */ @@ -443,14 +447,16 @@ layout_set_main_v(struct window *w) if (w->sy <= used) continue; lcchild = TAILQ_LAST(&lccolumn->cells, layout_cells); - layout_resize_adjust(lcchild, LAYOUT_TOPBOTTOM, w->sy - used); + layout_resize_adjust(w, lcchild, LAYOUT_TOPBOTTOM, + w->sy - used); } /* Adjust the last column width to fit if necessary. */ used = mainwidth + (columns * width) + columns - 1; if (w->sx > used) { lccolumn = TAILQ_LAST(&lc->cells, layout_cells); - layout_resize_adjust(lccolumn, LAYOUT_LEFTRIGHT, w->sx - used); + layout_resize_adjust(w, lccolumn, LAYOUT_LEFTRIGHT, + w->sx - used); } /* Fix cell offsets. */ @@ -543,14 +549,16 @@ layout_set_tiled(struct window *w) if (w->sx <= used) continue; lcchild = TAILQ_LAST(&lcrow->cells, layout_cells); - layout_resize_adjust(lcchild, LAYOUT_LEFTRIGHT, w->sx - used); + layout_resize_adjust(w, lcchild, LAYOUT_LEFTRIGHT, + w->sx - used); } /* Adjust the last row height to fit if necessary. */ used = (rows * height) + rows - 1; if (w->sy > used) { lcrow = TAILQ_LAST(&lc->cells, layout_cells); - layout_resize_adjust(lcrow, LAYOUT_TOPBOTTOM, w->sy - used); + layout_resize_adjust(w, lcrow, LAYOUT_TOPBOTTOM, + w->sy - used); } /* Fix cell offsets. */ diff --git a/usr.bin/tmux/layout.c b/usr.bin/tmux/layout.c index 5b160ed878a..0d23540ad3c 100644 --- a/usr.bin/tmux/layout.c +++ b/usr.bin/tmux/layout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout.c,v 1.27 2016/04/29 15:00:48 nicm Exp $ */ +/* $OpenBSD: layout.c,v 1.28 2016/08/03 09:07:02 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -32,9 +32,11 @@ * cell a pointer to its parent cell. */ -static int layout_resize_pane_grow(struct layout_cell *, enum layout_type, - int); -static int layout_resize_pane_shrink(struct layout_cell *, +static u_int layout_resize_check(struct window *, struct layout_cell *, + enum layout_type); +static int layout_resize_pane_grow(struct window *, struct layout_cell *, + enum layout_type, int); +static int layout_resize_pane_shrink(struct window *, struct layout_cell *, enum layout_type, int); static int layout_need_status(struct layout_cell *, int); @@ -282,33 +284,38 @@ layout_count_cells(struct layout_cell *lc) } /* 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) +static u_int +layout_resize_check(struct window *w, struct layout_cell *lc, + enum layout_type type) { struct layout_cell *lcchild; u_int available, minimum; if (lc->type == LAYOUT_WINDOWPANE) { /* Space available in this cell only. */ + minimum = PANE_MINIMUM; if (type == LAYOUT_LEFTRIGHT) available = lc->sx; - else + else { available = lc->sy; - - if (available > PANE_MINIMUM) - available -= PANE_MINIMUM; + minimum += layout_need_status(lc, + options_get_number(w->options, + "pane-border-status") == 1); + } + if (available > minimum) + available -= minimum; else available = 0; } else if (lc->type == type) { /* Same type: total of available space in all child cells. */ available = 0; TAILQ_FOREACH(lcchild, &lc->cells, entry) - available += layout_resize_check(lcchild, type); + available += layout_resize_check(w, lcchild, type); } else { /* Different type: minimum of available space in child cells. */ minimum = UINT_MAX; TAILQ_FOREACH(lcchild, &lc->cells, entry) { - available = layout_resize_check(lcchild, type); + available = layout_resize_check(w, lcchild, type); if (available < minimum) minimum = available; } @@ -323,7 +330,8 @@ layout_resize_check(struct layout_cell *lc, enum layout_type type) * expects the change to have already been bounded to the space available. */ void -layout_resize_adjust(struct layout_cell *lc, enum layout_type type, int change) +layout_resize_adjust(struct window *w, struct layout_cell *lc, + enum layout_type type, int change) { struct layout_cell *lcchild; @@ -340,7 +348,7 @@ layout_resize_adjust(struct layout_cell *lc, enum layout_type type, int change) /* Child cell runs in a different direction. */ if (lc->type != type) { TAILQ_FOREACH(lcchild, &lc->cells, entry) - layout_resize_adjust(lcchild, type, change); + layout_resize_adjust(w, lcchild, type, change); return; } @@ -353,12 +361,12 @@ layout_resize_adjust(struct layout_cell *lc, enum layout_type type, int change) if (change == 0) break; if (change > 0) { - layout_resize_adjust(lcchild, type, 1); + layout_resize_adjust(w, lcchild, type, 1); change--; continue; } - if (layout_resize_check(lcchild, type) > 0) { - layout_resize_adjust(lcchild, type, -1); + if (layout_resize_check(w, lcchild, type) > 0) { + layout_resize_adjust(w, lcchild, type, -1); change++; } } @@ -367,7 +375,8 @@ 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) +layout_destroy_cell(struct window *w, struct layout_cell *lc, + struct layout_cell **lcroot) { struct layout_cell *lcother, *lcparent; @@ -388,9 +397,9 @@ layout_destroy_cell(struct layout_cell *lc, struct layout_cell **lcroot) else lcother = TAILQ_PREV(lc, layout_cells, entry); if (lcparent->type == LAYOUT_LEFTRIGHT) - layout_resize_adjust(lcother, lcparent->type, lc->sx + 1); + layout_resize_adjust(w, lcother, lcparent->type, lc->sx + 1); else - layout_resize_adjust(lcother, lcparent->type, lc->sy + 1); + layout_resize_adjust(w, lcother, lcparent->type, lc->sy + 1); /* Remove this from the parent's list. */ TAILQ_REMOVE(&lcparent->cells, lc, entry); @@ -454,7 +463,7 @@ layout_resize(struct window *w, u_int sx, u_int sy) * window size. */ xchange = sx - w->sx; - xlimit = layout_resize_check(lc, LAYOUT_LEFTRIGHT); + xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT); if (xchange < 0 && xchange < -xlimit) xchange = -xlimit; if (xlimit == 0) { @@ -464,11 +473,11 @@ layout_resize(struct window *w, u_int sx, u_int sy) xchange = sx - lc->sx; } if (xchange != 0) - layout_resize_adjust(lc, LAYOUT_LEFTRIGHT, xchange); + layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, xchange); /* Adjust vertically in a similar fashion. */ ychange = sy - w->sy; - ylimit = layout_resize_check(lc, LAYOUT_TOPBOTTOM); + ylimit = layout_resize_check(w, lc, LAYOUT_TOPBOTTOM); if (ychange < 0 && ychange < -ylimit) ychange = -ylimit; if (ylimit == 0) { @@ -478,7 +487,7 @@ layout_resize(struct window *w, u_int sx, u_int sy) ychange = sy - lc->sy; } if (ychange != 0) - layout_resize_adjust(lc, LAYOUT_TOPBOTTOM, ychange); + layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, ychange); /* Fix cell offsets. */ layout_fix_offsets(lc); @@ -522,8 +531,9 @@ layout_resize_pane_to(struct window_pane *wp, enum layout_type type, void layout_resize_pane(struct window_pane *wp, enum layout_type type, int change) { - struct layout_cell *lc, *lcparent; - int needed, size; + struct window *w = wp->window; + struct layout_cell *lc, *lcparent; + int needed, size; lc = wp->layout_cell; @@ -544,10 +554,10 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change) needed = change; while (needed != 0) { if (change > 0) { - size = layout_resize_pane_grow(lc, type, needed); + size = layout_resize_pane_grow(w, lc, type, needed); needed -= size; } else { - size = layout_resize_pane_shrink(lc, type, needed); + size = layout_resize_pane_shrink(w, lc, type, needed); needed += size; } @@ -563,8 +573,8 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change) /* Helper function to grow pane. */ static int -layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type, - int needed) +layout_resize_pane_grow(struct window *w, struct layout_cell *lc, + enum layout_type type, int needed) { struct layout_cell *lcadd, *lcremove; u_int size; @@ -575,7 +585,7 @@ layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type, /* Look towards the tail for a suitable cell for reduction. */ lcremove = TAILQ_NEXT(lc, entry); while (lcremove != NULL) { - size = layout_resize_check(lcremove, type); + size = layout_resize_check(w, lcremove, type); if (size > 0) break; lcremove = TAILQ_NEXT(lcremove, entry); @@ -585,7 +595,7 @@ layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type, if (lcremove == NULL) { lcremove = TAILQ_PREV(lc, layout_cells, entry); while (lcremove != NULL) { - size = layout_resize_check(lcremove, type); + size = layout_resize_check(w, lcremove, type); if (size > 0) break; lcremove = TAILQ_PREV(lcremove, layout_cells, entry); @@ -597,15 +607,15 @@ layout_resize_pane_grow(struct layout_cell *lc, enum layout_type type, /* Change the cells. */ if (size > (u_int) needed) size = needed; - layout_resize_adjust(lcadd, type, size); - layout_resize_adjust(lcremove, type, -size); + layout_resize_adjust(w, lcadd, type, size); + layout_resize_adjust(w, lcremove, type, -size); return (size); } /* Helper function to shrink pane. */ static int -layout_resize_pane_shrink(struct layout_cell *lc, enum layout_type type, - int needed) +layout_resize_pane_shrink(struct window *w, struct layout_cell *lc, + enum layout_type type, int needed) { struct layout_cell *lcadd, *lcremove; u_int size; @@ -613,7 +623,7 @@ layout_resize_pane_shrink(struct layout_cell *lc, enum layout_type type, /* Shrinking. Find cell to remove from by walking towards head. */ lcremove = lc; do { - size = layout_resize_check(lcremove, type); + size = layout_resize_check(w, lcremove, type); if (size != 0) break; lcremove = TAILQ_PREV(lcremove, layout_cells, entry); @@ -629,8 +639,8 @@ layout_resize_pane_shrink(struct layout_cell *lc, enum layout_type type, /* Change the cells. */ if (size > (u_int) -needed) size = -needed; - layout_resize_adjust(lcadd, type, size); - layout_resize_adjust(lcremove, type, -size); + layout_resize_adjust(w, lcadd, type, size); + layout_resize_adjust(w, lcremove, type, -size); return (size); } @@ -769,13 +779,15 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size, void layout_close_pane(struct window_pane *wp) { + struct window *w = wp->window; + /* Remove the cell. */ - layout_destroy_cell(wp->layout_cell, &wp->window->layout_root); + layout_destroy_cell(w, wp->layout_cell, &w->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); + if (w->layout_root != NULL) { + layout_fix_offsets(w->layout_root); + layout_fix_panes(w, w->sx, w->sy); } - notify_window_layout_changed(wp->window); + notify_window_layout_changed(w); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index c80771b36d1..335fb7d4dfa 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.640 2016/07/15 09:52:34 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.641 2016/08/03 09:07:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2185,7 +2185,7 @@ u_int layout_count_cells(struct layout_cell *); struct layout_cell *layout_create_cell(struct layout_cell *); void layout_free_cell(struct layout_cell *); void layout_print_cell(struct layout_cell *, const char *, u_int); -void layout_destroy_cell(struct layout_cell *, +void layout_destroy_cell(struct window *, struct layout_cell *, struct layout_cell **); void layout_set_size(struct layout_cell *, u_int, u_int, u_int, u_int); @@ -2193,9 +2193,8 @@ void layout_make_leaf(struct layout_cell *, struct window_pane *); void layout_make_node(struct layout_cell *, enum layout_type); void layout_fix_offsets(struct layout_cell *); void layout_fix_panes(struct window *, u_int, u_int); -u_int layout_resize_check(struct layout_cell *, enum layout_type); -void layout_resize_adjust(struct layout_cell *, enum layout_type, - int); +void layout_resize_adjust(struct window *, struct layout_cell *, + enum layout_type, int); void layout_init(struct window *, struct window_pane *); void layout_free(struct window *); void layout_resize(struct window *, u_int, u_int); -- 2.20.1