From dc10c670603e3b2bc3a1e98ecf60336ac90399a6 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 13 Nov 2010 14:55:11 +0100 Subject: [PATCH] Bugfix: Close containers which are empty due to a move (Thanks fernando) --- include/con.h | 6 ++++++ src/con.c | 20 +++++++++++++++++--- src/render.c | 6 ++---- src/tree.c | 6 ++++++ testcases/t/24-move.t | 18 +++++++++++++++++- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/include/con.h b/include/con.h index c4c4a270..65e64212 100644 --- a/include/con.h +++ b/include/con.h @@ -75,6 +75,12 @@ Con *con_by_frame_id(xcb_window_t frame); */ Con *con_for_window(i3Window *window, Match **store_match); +/** + * Returns the number of children of this container. + * + */ +int con_num_children(Con *con); + /** * Attaches the given container to the given parent. This happens when moving * a container or when inserting a new container at a specific place in the diff --git a/src/con.c b/src/con.c index 02d46db5..beaf82ce 100644 --- a/src/con.c +++ b/src/con.c @@ -286,6 +286,20 @@ Con *con_for_window(i3Window *window, Match **store_match) { return NULL; } +/* + * Returns the number of children of this container. + * + */ +int con_num_children(Con *con) { + Con *child; + int children = 0; + + TAILQ_FOREACH(child, &(con->nodes_head), nodes) + children++; + + return children; +} + /* * Updates the percent attribute of the children of the given container. This * function needs to be called when a window is added or removed from a @@ -294,9 +308,7 @@ Con *con_for_window(i3Window *window, Match **store_match) { */ void con_fix_percent(Con *con, int action) { Con *child; - int children = 0; - TAILQ_FOREACH(child, &(con->nodes_head), nodes) - children++; + int children = con_num_children(con); /* TODO: better document why this math works */ double fix; if (action == WINDOW_ADD) @@ -446,4 +458,6 @@ Rect con_border_style_rect(Con *con) { if (con->border_style == BS_NONE) return (Rect){0, 0, 0, 0}; + + assert(false); } diff --git a/src/render.c b/src/render.c index 523b9188..dcd5f58e 100644 --- a/src/render.c +++ b/src/render.c @@ -19,10 +19,7 @@ static bool show_debug_borders = false; void render_con(Con *con) { printf("currently rendering node %p / %s / layout %d\n", con, con->name, con->layout); - int children = 0; - Con *child; - TAILQ_FOREACH(child, &(con->nodes_head), nodes) - children++; + int children = con_num_children(con); printf("children: %d, orientation = %d\n", children, con->orientation); /* Copy container rect, subtract container border */ @@ -103,6 +100,7 @@ void render_con(Con *con) { return; } + Con *child; TAILQ_FOREACH(child, &(con->nodes_head), nodes) { /* default layout */ diff --git a/src/tree.c b/src/tree.c index f170386e..244b5ba9 100644 --- a/src/tree.c +++ b/src/tree.c @@ -364,6 +364,7 @@ void tree_next(char way, orientation_t orientation) { void tree_move(char way, orientation_t orientation) { /* 1: get the first parent with the same orientation */ Con *parent = focused->parent; + Con *old_parent = parent; if (focused->type == CT_WORKSPACE) return; bool level_changed = false; @@ -431,4 +432,9 @@ void tree_move(char way, orientation_t orientation) { TAILQ_INSERT_HEAD(&(next->parent->focus_head), focused, focused); /* TODO: don’t influence focus handling? */ } + + if (con_num_children(old_parent) == 0) { + DLOG("Old container empty after moving. Let's close it\n"); + tree_close(old_parent, false); + } } diff --git a/testcases/t/24-move.t b/testcases/t/24-move.t index a98622f2..e316db13 100644 --- a/testcases/t/24-move.t +++ b/testcases/t/24-move.t @@ -7,7 +7,7 @@ # 3) move a container inside another container # 4) move a container in a different direction so that we need to go up in tree # -use i3test tests => 16; +use i3test tests => 17; use X11::XCB qw(:all); my $i3 = i3("/tmp/nestedcons"); @@ -109,4 +109,20 @@ $i3->command('move after h')->recv; $content = get_ws_content($tmp); is(@{$content}, 2, 'two nodes on this workspace'); +###################################################################### +# 4) Move a container horizontally when inside a vertical split container. +# The container will be moved to the workspace level and the old vsplit +# container needs to be closed. Verify that it will be closed. +###################################################################### + +my $otmp = get_unused_workspace(); +$i3->command("workspace $otmp")->recv; + +$i3->command("open")->recv; +$i3->command("split v")->recv; +$i3->command("move after h")->recv; + +$content = get_ws_content($otmp); +is(@{$content}, 1, 'only one nodes on this workspace'); + diag( "Testing i3, Perl $], $^X" ); -- 2.39.5