aboutsummaryrefslogtreecommitdiff
path: root/layout-custom.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2019-10-14 12:01:26 +0100
committerThomas Adam <thomas@xteddy.org>2019-10-14 12:01:26 +0100
commiteb57cbcc296b10d8d9ea41930ab402717c800f9c (patch)
tree6f6ad7c4bfb1abcba860ee51e9bc77ffef1bfc5a /layout-custom.c
parent7323ffeef22074911038444c0bfc675f56cd9726 (diff)
parentb598bbcc2e8b26855e4d34dfff9c222c28080cd7 (diff)
downloadrtmux-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.c69
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);