diff options
author | Thomas Adam <thomas@xteddy.org> | 2019-10-14 12:01:26 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2019-10-14 12:01:26 +0100 |
commit | eb57cbcc296b10d8d9ea41930ab402717c800f9c (patch) | |
tree | 6f6ad7c4bfb1abcba860ee51e9bc77ffef1bfc5a /layout-custom.c | |
parent | 7323ffeef22074911038444c0bfc675f56cd9726 (diff) | |
parent | b598bbcc2e8b26855e4d34dfff9c222c28080cd7 (diff) | |
download | rtmux-eb57cbcc296b10d8d9ea41930ab402717c800f9c.tar.gz rtmux-eb57cbcc296b10d8d9ea41930ab402717c800f9c.tar.bz2 rtmux-eb57cbcc296b10d8d9ea41930ab402717c800f9c.zip |
Merge branch 'obsd-master'
Diffstat (limited to 'layout-custom.c')
-rw-r--r-- | layout-custom.c | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/layout-custom.c b/layout-custom.c index 4ac90a37..b049f482 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -116,13 +116,49 @@ layout_append(struct layout_cell *lc, char *buf, size_t len) return (0); } +/* Check layout sizes fit. */ +static int +layout_check(struct layout_cell *lc) +{ + struct layout_cell *lcchild; + u_int n = 0; + + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sy != lc->sy) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sx + 1; + } + if (n - 1 != lc->sx) + return (0); + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sx != lc->sx) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sy + 1; + } + if (n - 1 != lc->sy) + return (0); + break; + } + return (1); +} + /* Parse a layout string and arrange window as layout. */ int layout_parse(struct window *w, const char *layout) { struct layout_cell *lc, *lcchild; struct window_pane *wp; - u_int npanes, ncells; + u_int npanes, ncells, sx = 0, sy = 0; u_short csum; /* Check validity. */ @@ -153,6 +189,37 @@ layout_parse(struct window *w, const char *layout) layout_destroy_cell(w, lcchild, &lc); } + /* + * It appears older versions of tmux were able to generate layouts with + * an incorrect top cell size - if it is larger than the top child then + * correct that (if this is still wrong the check code will catch it). + */ + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sy = lcchild->sy + 1; + sx += lcchild->sx + 1; + } + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sx = lcchild->sx + 1; + sy += lcchild->sy + 1; + } + break; + } + if (lc->sx != sx || lc->sy != sy) { + log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy); + layout_print_cell(lc, __func__, 0); + lc->sx = sx - 1; lc->sy = sy - 1; + } + + /* Check the new layout. */ + if (!layout_check(lc)) + return (-1); + /* Resize to the layout size. */ window_resize(w, lc->sx, lc->sy); |