]> git.sur5r.net Git - i3/i3/commitdiff
Raise floating window to top when it gets focus
authorOrestis Floros <orestisf1993@gmail.com>
Fri, 22 Sep 2017 19:00:06 +0000 (22:00 +0300)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 24 Sep 2017 15:07:07 +0000 (17:07 +0200)
Applied for:
1. '[...] focus' for a floating container raises it to the top.
2. Focusing a window through a focus event raises it to the top.

Fixes #2572

src/click.c
src/con.c
src/handlers.c
testcases/t/135-floating-focus.t

index e5cdc8b2f39e82dbe880fb184337f3f8363380f2..78af8a0350cd067179f5aaedcf263ad631e11b84 100644 (file)
@@ -262,8 +262,6 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
      * We will skip handling events on floating cons in fullscreen mode */
     Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL);
     if (floatingcon != NULL && fs != con) {
-        floating_raise_con(floatingcon);
-
         /* 4: floating_modifier plus left mouse button drags */
         if (mod_pressed && event->detail == XCB_BUTTON_CLICK_LEFT) {
             floating_drag_window(floatingcon, event);
index df115230732d8c7f4d9afbd41efffaf0494124f1..2e22619f3d838968de6840a29d130ed61bbbcfc4 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -243,6 +243,13 @@ void con_focus(Con *con) {
         workspace_update_urgent_flag(con_get_workspace(con));
         ipc_send_window_event("urgent", con);
     }
+
+    /* Focusing a container with a floating parent should raise it to the top. Since
+     * con_focus is called recursively for each parent we don't need to use
+     * con_inside_floating(). */
+    if (con->type == CT_FLOATING_CON) {
+        floating_raise_con(con);
+    }
 }
 
 /*
index 8d500fd9f24d7b177d30da82dc01a3babf3ed860..1da42ec25420c752e0dafd3a2c2848c5d74184f0 100644 (file)
@@ -1221,7 +1221,9 @@ static void handle_focus_in(xcb_focus_in_event_t *event) {
         return;
     }
 
-    if (focused_id == event->event) {
+    /* Floating windows should be refocused to ensure that they are on top of
+     * other windows. */
+    if (focused_id == event->event && !con_inside_floating(con)) {
         DLOG("focus matches the currently focused window, not doing anything\n");
         return;
     }
@@ -1232,7 +1234,7 @@ static void handle_focus_in(xcb_focus_in_event_t *event) {
         return;
     }
 
-    DLOG("focus is different, updating decorations\n");
+    DLOG("focus is different / refocusing floating window: updating decorations\n");
 
     /* Get the currently focused workspace to check if the focus change also
      * involves changing workspaces. If so, we need to call workspace_show() to
@@ -1244,7 +1246,7 @@ static void handle_focus_in(xcb_focus_in_event_t *event) {
     con_focus(con);
     /* We update focused_id because we don’t need to set focus again */
     focused_id = event->event;
-    x_push_changes(croot);
+    tree_render();
     return;
 }
 
index f23dabae444661ccd2a6b8398c8803b6ffa1cbe8..f21c0486ee1bf47268ed1a27531a0d565c2a0254 100644 (file)
@@ -216,4 +216,28 @@ cmd 'focus child';
 
 is($x->input_focus, $floating->id, 'floating window focused');
 
+#############################################################################
+# 8: verify that focusing a floating window raises it to the top.
+# This test can't verify that the floating container is visually on top, just
+# that it is placed on the tail of the floating_head.
+# See issue: 2572
+#############################################################################
+
+$tmp = fresh_workspace;
+
+$first = open_floating_window;
+$second = open_floating_window;
+
+is($x->input_focus, $second->id, 'second floating window focused');
+my $ws = get_ws($tmp);
+is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $second->id, 'second on top');
+is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $first->id, 'first behind');
+
+cmd '[id=' . $first->id . '] focus';
+
+is($x->input_focus, $first->id, 'first floating window focused');
+$ws = get_ws($tmp);
+is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $first->id, 'first on top');
+is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $second->id, 'second behind');
+
 done_testing;