From cdeb49127fe25fded22d80a94ddd26cf46253b68 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 14 Mar 2011 16:34:35 +0100 Subject: [PATCH] Bugfix: restore focus to the correct window when a non-focused window gets destroyed (+testcase) --- src/con.c | 18 ++++++++++++------ testcases/t/29-focus-after-close.t | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/con.c b/src/con.c index 91f11d24..0ed4436a 100644 --- a/src/con.c +++ b/src/con.c @@ -623,12 +623,18 @@ Con *con_next_focused(Con *con) { return con_descend_focused(output_get_content(con->parent->parent)); } - /* try to focus the next container on the same level as this one */ - next = TAILQ_NEXT(con, focused); - - /* if that was not possible, go up to its parent */ - if (next == TAILQ_END(&(parent->nodes_head))) - next = con->parent; + /* if 'con' is not the first entry in the focus stack, use the first one as + * it’s currently focused already */ + Con *first = TAILQ_FIRST(&(con->parent->focus_head)); + if (first != con) { + DLOG("Using first entry %p\n", first); + next = first; + } else { + /* try to focus the next container on the same level as this one or fall + * back to its parent */ + if (!(next = TAILQ_NEXT(con, focused))) + next = con->parent; + } /* now go down the focus stack as far as * possible, excluding the current container */ diff --git a/testcases/t/29-focus-after-close.t b/testcases/t/29-focus-after-close.t index d922578c..b34e6686 100644 --- a/testcases/t/29-focus-after-close.t +++ b/testcases/t/29-focus-after-close.t @@ -4,8 +4,11 @@ # Check if the focus is correctly restored after closing windows. # use i3test; +use X11::XCB qw(:all); use List::Util qw(first); +my $x = X11::XCB::Connection->new; + my $i3 = i3("/tmp/nestedcons"); my $tmp = fresh_workspace; @@ -87,6 +90,27 @@ is(get_focused($tmp), $right, 'top right container focused (in focus stack)'); my $tr = first { $_->{id} eq $right } @{$nodes->[0]->{nodes}}; is($tr->{focused}, 1, 'top right container really has focus'); +############################################################## +# check if focus is correct after closing an unfocused window +############################################################## + +$tmp = fresh_workspace; + +ok(@{get_ws_content($tmp)} == 0, 'no containers yet'); + +$first = open_empty_con($i3); +$middle = open_empty_con($i3); +# XXX: the $right empty con will be filled with the x11 window we are creating afterwards +$right = open_empty_con($i3); +my $win = open_standard_window($x, '#00ff00'); + +cmd qq|[con_id="$middle"] focus|; +$win->destroy; + +sleep 0.25; + +is(get_focused($tmp), $middle, 'middle container focused'); + ############################################################## # and now for something completely different: # check if the pointer position is relevant when restoring focus