From 09b5b17830588c4f9c97e485f02b3e6a05ce3b54 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 21 Nov 2010 16:49:59 +0100 Subject: [PATCH] =?UTF-8?q?Bugfix:=20Don=E2=80=99t=20attach=20tiling=20con?= =?UTF-8?q?tainers=20to=20floating=20containers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bug happened when there were only floating containers on a workspace and a new tiling window was to be opened. --- src/con.c | 22 ++++++++--- src/tree.c | 4 ++ testcases/t/38-floating-attach.t | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 testcases/t/38-floating-attach.t diff --git a/src/con.c b/src/con.c index 1686d84f..fb6866d8 100644 --- a/src/con.c +++ b/src/con.c @@ -70,14 +70,24 @@ Con *con_new(Con *parent) { */ void con_attach(Con *con, Con *parent) { con->parent = parent; - Con *current = TAILQ_FIRST(&(parent->focus_head)); + Con *loop; + Con *current = NULL; - if (current == TAILQ_END(&(parent->focus_head))) - TAILQ_INSERT_TAIL(&(parent->nodes_head), con, nodes); - else { - DLOG("inserting after\n"); - TAILQ_INSERT_AFTER(&(parent->nodes_head), current, con, nodes); + /* Get the first tiling container in focus stack */ + TAILQ_FOREACH(loop, &(parent->focus_head), focused) { + if (loop->type == CT_FLOATING_CON) + continue; + current = loop; + break; } + + /* Insert the container after the tiling container, if found */ + if (current) { + DLOG("Inserting con = %p after last focused tiling con %p\n", + con, current); + TAILQ_INSERT_AFTER(&(parent->nodes_head), current, con, nodes); + } else TAILQ_INSERT_TAIL(&(parent->nodes_head), con, nodes); + /* We insert to the TAIL because con_focus() will correct this. * This way, we have the option to insert Cons without having * to focus them. */ diff --git a/src/tree.c b/src/tree.c index dac949ba..e0b1ab7d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -104,6 +104,10 @@ Con *tree_open_con(Con *con) { * the new container needs to be opened as a leaf of the workspace. */ if (con->type == CT_OUTPUT) con = focused; + /* If the currently focused container is a floating container, we + * attach the new container to the workspace */ + if (con->type == CT_FLOATING_CON) + con = con->parent; } assert(con != NULL); diff --git a/testcases/t/38-floating-attach.t b/testcases/t/38-floating-attach.t new file mode 100644 index 00000000..0a85ff6d --- /dev/null +++ b/testcases/t/38-floating-attach.t @@ -0,0 +1,63 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# Regression test: New windows were attached to the container of a floating window +# if only a floating window is present on the workspace. + +use i3test tests => 7; +use X11::XCB qw(:all); +use Time::HiRes qw(sleep); + +BEGIN { + use_ok('X11::XCB::Window'); +} + +my $i3 = i3("/tmp/nestedcons"); + +my $tmp = get_unused_workspace(); +$i3->command("workspace $tmp")->recv; + +############################################################################# +# 1: open a floating window, get it mapped +############################################################################# + +my $x = X11::XCB::Connection->new; + +# Create a floating window +my $window = $x->root->create_child( + class => WINDOW_CLASS_INPUT_OUTPUT, + rect => [ 0, 0, 30, 30], + background_color => '#C0C0C0', + # replace the type with 'utility' as soon as the coercion works again in X11::XCB + window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'), +); + +isa_ok($window, 'X11::XCB::Window'); + +$window->map; + +sleep 0.25; + +ok($window->mapped, 'Window is mapped'); + +my $ws = get_ws($tmp); +my ($nodes, $focus) = get_ws_content($tmp); + +is(@{$ws->{floating_nodes}}, 1, 'one floating node'); +is(@{$nodes}, 0, 'no tiling nodes'); + +# Create a tiling window +my $twindow = $x->root->create_child( + class => WINDOW_CLASS_INPUT_OUTPUT, + rect => [ 0, 0, 30, 30], + background_color => '#C0C0C0', +); + +isa_ok($twindow, 'X11::XCB::Window'); + +$twindow->map; + +sleep 0.25; + +($nodes, $focus) = get_ws_content($tmp); + +is(@{$nodes}, 1, 'one tiling node');