]> git.sur5r.net Git - i3/i3/commitdiff
Assign the sticky value for _NET_WM_DESKTOP on scratchpad windows. (#2457)
authorIngo Bürk <admin@airblader.de>
Tue, 27 Sep 2016 05:39:17 +0000 (07:39 +0200)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Tue, 27 Sep 2016 05:39:17 +0000 (22:39 -0700)
fixes #2456

src/ewmh.c
src/manage.c
testcases/t/529-net-wm-desktop.t

index c4ae844ea0a1a523b54057ab248818636759f0eb..5459c7e922ea9c93437d6de94886d902cdc32e9a 100644 (file)
@@ -124,11 +124,13 @@ void ewmh_update_desktop_viewport(void) {
 }
 
 static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop) {
-    /* Recursively call this to descend through the entire subtree. */
     Con *child;
+
+    /* Recursively call this to descend through the entire subtree. */
     TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
         ewmh_update_wm_desktop_recursively(child, desktop);
     }
+
     /* If con is a workspace, we also need to go through the floating windows on it. */
     if (con->type == CT_WORKSPACE) {
         TAILQ_FOREACH(child, &(con->floating_head), floating_windows) {
@@ -139,8 +141,6 @@ static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop)
     if (!con_has_managed_window(con))
         return;
 
-    const xcb_window_t window = con->window->id;
-
     uint32_t wm_desktop = desktop;
     /* Sticky windows are only actually sticky when they are floating or inside
      * a floating container. This is technically still slightly wrong, since
@@ -151,11 +151,20 @@ static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop)
         wm_desktop = NET_WM_DESKTOP_ALL;
     }
 
+    /* If the window is on the scratchpad we assign the sticky value to it
+     * since showing it works on any workspace. We cannot remove the property
+     * as per specification. */
+    Con *ws = con_get_workspace(con);
+    if (ws != NULL && con_is_internal(ws)) {
+        wm_desktop = NET_WM_DESKTOP_ALL;
+    }
+
     /* If this is the cached value, we don't need to do anything. */
     if (con->window->wm_desktop == wm_desktop)
         return;
     con->window->wm_desktop = wm_desktop;
 
+    const xcb_window_t window = con->window->id;
     if (wm_desktop != NET_WM_DESKTOP_NONE) {
         DLOG("Setting _NET_WM_DESKTOP = %d for window 0x%08x.\n", wm_desktop, window);
         xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, A__NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &wm_desktop);
@@ -179,11 +188,11 @@ void ewmh_update_wm_desktop(void) {
     TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
         Con *workspace;
         TAILQ_FOREACH(workspace, &(output_get_content(output)->nodes_head), nodes) {
-            if (con_is_internal(workspace))
-                continue;
-
             ewmh_update_wm_desktop_recursively(workspace, desktop);
-            ++desktop;
+
+            if (!con_is_internal(workspace)) {
+                ++desktop;
+            }
         }
     }
 }
index 37d50e7bd22526dab63fdb9efc2132735c39e0f8..bbd8400726a17d271e3641838f4fd392b8792764 100644 (file)
@@ -430,7 +430,10 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_STICKY))
         nc->sticky = true;
 
-    if (cwindow->wm_desktop == NET_WM_DESKTOP_ALL) {
+    /* We ignore the hint for an internal workspace because windows in the
+     * scratchpad also have this value, but upon restarting i3 we don't want
+     * them to become sticky windows. */
+    if (cwindow->wm_desktop == NET_WM_DESKTOP_ALL && !con_is_internal(ws)) {
         DLOG("This window has _NET_WM_DESKTOP = 0xFFFFFFFF. Will float it and make it sticky.\n");
         nc->sticky = true;
         want_floating = true;
index f6a3b2184ca951aabd4e8d1be5ba18d6c5904444..8f2df735a2e512a759a221c717f577220e6fa199 100644 (file)
@@ -345,6 +345,26 @@ is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
 kill_windows;
 exit_gracefully($pid);
 
+###############################################################################
+# _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
+###############################################################################
+
+$pid = launch_with_config($config);
+
+cmd 'workspace 0';
+$con = open_window;
+cmd 'floating enable';
+is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
+
+cmd 'move scratchpad';
+is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
+
+cmd 'scratchpad show';
+is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
+
+kill_windows;
+exit_gracefully($pid);
+
 ###############################################################################
 
 done_testing;