]> git.sur5r.net Git - i3/i3/commitdiff
fix floating focus behaviour, extend testcase
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 14 Nov 2010 21:35:44 +0000 (22:35 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 14 Nov 2010 21:35:44 +0000 (22:35 +0100)
src/con.c
src/floating.c
src/x.c
testcases/t/35-floating-focus.t

index e92322734234d1646e6620f41be0bc6a00a62f45..2487dd830477d872b5e1519eb9a075b9ce9c17ee 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -422,9 +422,24 @@ Con *con_next_focused(Con *con) {
     /* floating containers are attached to a workspace, so we focus either the
      * next floating container (if any) or the workspace itself. */
     if (con->type == CT_FLOATING_CON) {
+        DLOG("selecting next for CT_FLOATING_CON\n");
         next = TAILQ_NEXT(con, floating_windows);
-        if (next == TAILQ_END(&(parent->floating_head)))
-            next = con_get_workspace(con);
+        if (next == TAILQ_END(&(parent->floating_head))) {
+            Con *ws = con_get_workspace(con);
+            next = ws;
+            DLOG("no more floating containers for next = %p, restoring workspace focus\n", next);
+            while (next != TAILQ_END(&(ws->focus_head)) && !TAILQ_EMPTY(&(next->focus_head))) {
+                next = TAILQ_FIRST(&(next->focus_head));
+                if (next == con) {
+                    DLOG("skipping container itself, we want the next client\n");
+                    next = TAILQ_NEXT(next, focused);
+                }
+            }
+            if (next == TAILQ_END(&(ws->focus_head))) {
+                DLOG("Focus list empty, returning NULL\n");
+                next = NULL;
+            }
+        }
         return next;
     }
 
index 005f2092c48fffd420c5a523975bcb1f6cff4dc7..2292d89be19f507976b325bcb26307e4941fa50b 100644 (file)
@@ -78,6 +78,8 @@ void floating_enable(Con *con, bool automatic) {
 
     TAILQ_INSERT_TAIL(&(nc->nodes_head), con, nodes);
     TAILQ_INSERT_TAIL(&(nc->focus_head), con, focused);
+    // TODO: don’t influence focus handling when Con was not focused before.
+    con_focus(con);
 }
 
 void floating_disable(Con *con, bool automatic) {
@@ -105,6 +107,8 @@ void floating_disable(Con *con, bool automatic) {
     con->floating = FLOATING_USER_OFF;
 
     con_fix_percent(con->parent, WINDOW_ADD);
+    // TODO: don’t influence focus handling when Con was not focused before.
+    con_focus(con);
 }
 
 
diff --git a/src/x.c b/src/x.c
index fe83a8483f6dc6d12cf0796ac22c73d4d00868c9..5c854d0187226bc7bac2661ad62b20b716b6e721 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -372,7 +372,7 @@ static void x_push_node(Con *con) {
     state = state_for_frame(con->frame);
 
     if (state->name != NULL) {
-        DLOG("pushing name %s\n", state->name);
+        DLOG("pushing name %s for con %p\n", state->name, con);
 
         xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->frame,
                             WM_NAME, STRING, 8, strlen(state->name), state->name);
index 7efe2472f7965b13bbf3260773e66b271597c3d8..3b6cfdae73d76968eefa793a479c18d217e7dec9 100644 (file)
@@ -1,7 +1,7 @@
 #!perl
 # vim:ts=4:sw=4:expandtab
 
-use i3test tests => 3;
+use i3test tests => 9;
 use Time::HiRes qw(sleep);
 
 my $i3 = i3("/tmp/nestedcons");
@@ -9,6 +9,10 @@ my $i3 = i3("/tmp/nestedcons");
 my $tmp = get_unused_workspace();
 $i3->command("workspace $tmp")->recv;
 
+#############################################################################
+# 1: see if focus stays the same when toggling tiling/floating mode
+#############################################################################
+
 $i3->command("open")->recv;
 $i3->command("open")->recv;
 
@@ -21,3 +25,48 @@ $i3->command("mode tiling")->recv;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok($content[1]->{focused}, '==', 1, 'Second container still focused after mode toggle');
+
+#############################################################################
+# 2: see if the focus gets reverted correctly when closing floating clients
+# (first to the next floating client, then to the last focused tiling client)
+#############################################################################
+
+$tmp = get_unused_workspace();
+$i3->command("workspace $tmp")->recv;
+
+$i3->command("open")->recv;
+$i3->command("open")->recv;
+$i3->command("open")->recv;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 3, 'two containers opened');
+cmp_ok($content[2]->{focused}, '==', 1, 'Last container focused');
+
+my $last_id = $content[2]->{id};
+my $second_id = $content[1]->{id};
+my $first_id = $content[0]->{id};
+diag("last_id = $last_id, second_id = $second_id, first_id = $first_id");
+
+$i3->command(qq|[con_id="$second_id"] focus|)->recv;
+@content = @{get_ws_content($tmp)};
+cmp_ok($content[1]->{focused}, '==', 1, 'Second container focused');
+
+$i3->command("mode floating")->recv;
+
+$i3->command(qq|[con_id="$last_id"] focus|)->recv;
+@content = @{get_ws_content($tmp)};
+cmp_ok($content[1]->{focused}, '==', 1, 'Last container focused');
+
+$i3->command("mode floating")->recv;
+
+diag("focused = " . get_focused($tmp));
+
+$i3->command("kill")->recv;
+
+diag("focused = " . get_focused($tmp));
+# TODO: this test result is actually not right. the focus reverts to where the mouse pointer is.
+cmp_ok(get_focused($tmp), '==', $second_id, 'Focus reverted to second floating container');
+
+$i3->command("kill")->recv;
+@content = @{get_ws_content($tmp)};
+cmp_ok($content[0]->{focused}, '==', 1, 'Focus reverted to tiling container');