From 57438d270de49a97f1bb55e6730da2ff8621c6ce Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 5 Aug 2015 22:40:58 +0200 Subject: [PATCH] append_layout: load floating containers correctly fixes #1739 fixes #1271 --- src/load_layout.c | 27 ++++++++ testcases/t/249-layout-restore-floating.t | 82 +++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 testcases/t/249-layout-restore-floating.t diff --git a/src/load_layout.c b/src/load_layout.c index fa0d2e5a..ae8eb5bc 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -116,6 +116,33 @@ static int json_end_map(void *ctx) { json_node->num = ws_name_to_number(json_node->name); } + // When appending JSON layout files that only contain the workspace + // _contents_, we might not have an upfront signal that the + // container we’re currently parsing is a floating container (like + // the “floating_nodes” key of the workspace container itself). + // That’s why we make sure the con is attached at the right place + // in the hierarchy in case it’s floating. + if (json_node->type == CT_FLOATING_CON) { + DLOG("fixing parent which currently is %p / %s\n", json_node->parent, json_node->parent->name); + json_node->parent = con_get_workspace(json_node->parent); + + // Also set a size if none was supplied, otherwise the placeholder + // window cannot be created as X11 requests with width=0 or + // height=0 are invalid. + const Rect zero = {0,0,0,0}; + if (memcmp(&(json_node->rect), &zero, sizeof(Rect)) == 0) { + DLOG("Geometry not set, combining children\n"); + Con *child; + TAILQ_FOREACH(child, &(json_node->nodes_head), nodes) { + DLOG("child geometry: %d x %d\n", child->geometry.width, child->geometry.height); + json_node->rect.width += child->geometry.width; + json_node->rect.height = max(json_node->rect.height, child->geometry.height); + } + } + + floating_check_size(json_node); + } + LOG("attaching\n"); con_attach(json_node, json_node->parent, true); LOG("Creating window\n"); diff --git a/testcases/t/249-layout-restore-floating.t b/testcases/t/249-layout-restore-floating.t new file mode 100644 index 00000000..805b071a --- /dev/null +++ b/testcases/t/249-layout-restore-floating.t @@ -0,0 +1,82 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies floating containers are restored in the correct place in the +# hierarchy and get a non-zero size. +# Ticket: #1739 +# Bug still in: 4.10.3-264-g419b73b +use i3test; +use File::Temp qw(tempfile); +use IO::Handle; + +my $ws = fresh_workspace; + +my @content = @{get_ws_content($ws)}; +is(@content, 0, 'no nodes on the new workspace yet'); + +my ($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // floating_con with 1 children + "border": "none", + "floating": "auto_off", + "layout": "splith", + "percent": null, + "type": "floating_con", + // NOTE that "rect" is missing here. + "nodes": [ + { + "border": "none", + "current_border_width": 0, + "floating": "user_on", + "geometry": { + "height": 384, + "width": 128, + "x": 448, + "y": 441 + }, + "name": "Splash", + "percent": 1, + "swallows": [ + { + "class": "^Steam$", + "instance": "^Steam$", + "title": "^Steam$" + // "transient_for": "^$" + } + ], + "type": "con" + } + ] +} +EOT +$fh->flush; +my $reply = cmd "append_layout $filename"; + +does_i3_live; + +ok($reply->[0]->{success}, 'Layout successfully loaded'); + +cmd 'kill'; + +ok(workspace_exists($ws), 'Workspace still exists'); + +does_i3_live; + +close($fh); + +done_testing;