From 524f20b8a02b2b243f92e01c17c1680f12c851c3 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 18 Apr 2014 20:30:27 +0200 Subject: [PATCH] layout restoring: append at the nearest split container (or workspace) (Thanks chris) Before this commit, leaf containers (such as terminal emulators) would get children appended, which is not intended. fixes #1223 --- include/load_layout.h | 2 +- src/commands.c | 10 +++++++++- src/load_layout.c | 6 +++--- src/tree.c | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/load_layout.h b/include/load_layout.h index 0a5328fa..a598c8c6 100644 --- a/include/load_layout.h +++ b/include/load_layout.h @@ -10,4 +10,4 @@ */ #pragma once -void tree_append_json(const char *filename, char **errormsg); +void tree_append_json(Con *con, const char *filename, char **errormsg); diff --git a/src/commands.c b/src/commands.c index 0f4315c1..11d0b244 100644 --- a/src/commands.c +++ b/src/commands.c @@ -877,8 +877,16 @@ void cmd_nop(I3_CMD, char *comment) { void cmd_append_layout(I3_CMD, char *path) { LOG("Appending layout \"%s\"\n", path); Con *parent = focused; + /* We need to append the layout to a split container, since a leaf + * container must not have any children (by definition). + * Note that we explicitly check for workspaces, since they are okay for + * this purpose, but con_accepts_window() returns false for workspaces. */ + while (parent->type != CT_WORKSPACE && !con_accepts_window(parent)) + parent = parent->parent; + DLOG("Appending to parent=%p instead of focused=%p\n", + parent, focused); char *errormsg = NULL; - tree_append_json(path, &errormsg); + tree_append_json(parent, path, &errormsg); if (errormsg != NULL) { yerror(errormsg); free(errormsg); diff --git a/src/load_layout.c b/src/load_layout.c index 627c1f6e..cebb1930 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -395,7 +395,7 @@ static int json_double(void *ctx, double val) { return 1; } -void tree_append_json(const char *filename, char **errormsg) { +void tree_append_json(Con *con, const char *filename, char **errormsg) { FILE *f; if ((f = fopen(filename, "r")) == NULL) { LOG("Cannot open file \"%s\"\n", filename); @@ -439,7 +439,7 @@ void tree_append_json(const char *filename, char **errormsg) { /* Allow multiple values, i.e. multiple nodes to attach */ yajl_config(hand, yajl_allow_multiple_values, true); yajl_status stat; - json_node = focused; + json_node = con; to_focus = NULL; parsing_swallows = false; parsing_rect = false; @@ -460,7 +460,7 @@ void tree_append_json(const char *filename, char **errormsg) { /* In case not all containers were restored, we need to fix the * percentages, otherwise i3 will crash immediately when rendering the * next time. */ - con_fix_percent(focused); + con_fix_percent(con); setlocale(LC_NUMERIC, ""); #if YAJL_MAJOR >= 2 diff --git a/src/tree.c b/src/tree.c index 80af5223..d4936299 100644 --- a/src/tree.c +++ b/src/tree.c @@ -84,7 +84,7 @@ bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry) { }; focused = croot; - tree_append_json(globbed, NULL); + tree_append_json(focused, globbed, NULL); printf("appended tree, using new root\n"); croot = TAILQ_FIRST(&(croot->nodes_head));