]> git.sur5r.net Git - i3/i3/commitdiff
Keep a sticky window focused if it was the focused window on the source workspace. 1931/head
authorIngo Bürk <ingo.buerk@tngtech.com>
Thu, 17 Sep 2015 20:52:56 +0000 (22:52 +0200)
committerIngo Bürk <ingo.buerk@tngtech.com>
Thu, 24 Sep 2015 20:10:17 +0000 (22:10 +0200)
fixes #1924

include/output.h
src/commands.c
src/handlers.c
src/output.c
src/workspace.c
testcases/t/251-sticky.t

index 38e2689add05eb529dce2465850f93bc490bd751..8299a19bc1ddefd6fb7f37cec5f3bfbd4635e499 100644 (file)
@@ -27,4 +27,4 @@ Output *get_output_from_string(Output *current_output, const char *output_str);
  * workspace on that output.
  *
  */
-void output_push_sticky_windows(void);
+void output_push_sticky_windows(Con *to_focus);
index 1472a812117fda78a43201c03781aec3a707a73b..bbe3ee80b4a579b7bc16d295c5297cd81cf6b6bf 100644 (file)
@@ -1598,7 +1598,7 @@ void cmd_sticky(I3_CMD, char *action) {
 
     /* A window we made sticky might not be on a visible workspace right now, so we need to make
      * sure it gets pushed to the front now. */
-    output_push_sticky_windows();
+    output_push_sticky_windows(focused);
 
     cmd_output->needs_tree_render = true;
     ysuccess(true);
index d0b663740148db666b2cf7b64b62eaf7eb3aa381..f8c45bcfda4516868fc082d8eeb2b33cd7931ece 100644 (file)
@@ -736,7 +736,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
                 con->sticky = !con->sticky;
 
             DLOG("New sticky status for con = %p is %i.\n", con, con->sticky);
-            output_push_sticky_windows();
+            output_push_sticky_windows(focused);
         }
 
         tree_render();
index e29ab7469123eb954c1388eb3e5cdd50bf2ec57f..62b146a74150fa65e094e09a6b4e4570552700b1 100644 (file)
@@ -52,31 +52,34 @@ Output *get_output_from_string(Output *current_output, const char *output_str) {
  * workspace on that output.
  *
  */
-void output_push_sticky_windows(void) {
+void output_push_sticky_windows(Con *to_focus) {
     Con *output;
-    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
+    TAILQ_FOREACH(output, &(croot->focus_head), focused) {
         Con *workspace, *visible_ws = NULL;
         GREP_FIRST(visible_ws, output_get_content(output), workspace_is_visible(child));
 
         /* We use this loop instead of TAILQ_FOREACH to avoid problems if the
          * sticky window was the last window on that workspace as moving it in
          * this case will close the workspace. */
-        for (workspace = TAILQ_FIRST(&(output_get_content(output)->nodes_head));
-             workspace != TAILQ_END(&(output_get_content(output)->nodes_head));) {
+        for (workspace = TAILQ_FIRST(&(output_get_content(output)->focus_head));
+             workspace != TAILQ_END(&(output_get_content(output)->focus_head));) {
             Con *current_ws = workspace;
-            workspace = TAILQ_NEXT(workspace, nodes);
+            workspace = TAILQ_NEXT(workspace, focused);
 
             /* Since moving the windows actually removes them from the list of
              * floating windows on this workspace, here too we need to use
              * another loop than TAILQ_FOREACH. */
             Con *child;
-            for (child = TAILQ_FIRST(&(current_ws->floating_head));
-                 child != TAILQ_END(&(current_ws->floating_head));) {
+            for (child = TAILQ_FIRST(&(current_ws->focus_head));
+                 child != TAILQ_END(&(current_ws->focus_head));) {
                 Con *current = child;
-                child = TAILQ_NEXT(child, floating_windows);
+                child = TAILQ_NEXT(child, focused);
+                if (current->type != CT_FLOATING_CON)
+                    continue;
 
-                if (con_is_sticky(current))
-                    con_move_to_workspace(current, visible_ws, true, false, true);
+                if (con_is_sticky(current)) {
+                    con_move_to_workspace(current, visible_ws, true, false, current != to_focus->parent);
+                }
             }
         }
     }
index 1a3b15d53c3975dfc42bc0ad567f7b030bec27df..d3a97453187ee63efefb66f92db78f8e8a722100 100644 (file)
@@ -363,6 +363,7 @@ static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents
 
 static void _workspace_show(Con *workspace) {
     Con *current, *old = NULL;
+    Con *old_focus = focused;
 
     /* safe-guard against showing i3-internal workspaces like __i3_scratch */
     if (con_is_internal(workspace))
@@ -478,7 +479,7 @@ static void _workspace_show(Con *workspace) {
     ewmh_update_current_desktop();
 
     /* Push any sticky windows to the now visible workspace. */
-    output_push_sticky_windows();
+    output_push_sticky_windows(old_focus);
 }
 
 /*
index 6729556dd5e1196d8f3b17d8a3d1b2d7744fc6cc..85fc11f70befd5027c347114fd9733fa260feaa4 100644 (file)
@@ -18,7 +18,7 @@
 # Ticket: #1455
 use i3test;
 
-my ($ws, $focused);
+my ($ws, $tmp, $focused);
 
 ###############################################################################
 # 1: Given a sticky tiling container, when the workspace is switched, then
@@ -62,9 +62,9 @@ is(@{get_ws($ws)->{floating_nodes}}, 2, 'multiple sticky windows can be used at
 cmd '[class="findme"] kill';
 
 ###############################################################################
-# 4: Given a sticky floating container and a tiling container on the target
-#    workspace, when the workspace is switched, then the tiling container is
-#    focused.
+# 4: Given an unfocused sticky floating container and a tiling container on the
+#    target workspace, when the workspace is switched, then the tiling container
+#    is focused.
 ###############################################################################
 $ws = fresh_workspace;
 open_window;
@@ -72,13 +72,30 @@ $focused = get_focused($ws);
 fresh_workspace;
 open_floating_window(wm_class => 'findme');
 cmd 'sticky enable';
+open_window;
 cmd 'workspace ' . $ws;
 
 is(get_focused($ws), $focused, 'the tiling container has focus');
 cmd '[class="findme"] kill';
 
 ###############################################################################
-# 5: Given a floating container on a non-visible workspace, when the window
+# 5: Given a focused sticky floating container and a tiling container on the
+#    target workspace, when the workspace is switched, then the tiling container
+#    is focused.
+###############################################################################
+$ws = fresh_workspace;
+open_window;
+$tmp = fresh_workspace;
+open_floating_window(wm_class => 'findme');
+$focused = get_focused($tmp);
+cmd 'sticky enable';
+cmd 'workspace ' . $ws;
+
+is(get_focused($ws), $focused, 'the sticky container has focus');
+cmd '[class="findme"] kill';
+
+###############################################################################
+# 6: Given a floating container on a non-visible workspace, when the window
 #    is made sticky, then the window immediately jumps to the currently
 #    visible workspace.
 ###############################################################################