]> git.sur5r.net Git - i3/i3/commitdiff
Handle EWMH requests to change current desktop
authorTony Crisci <tony@dubstepdish.com>
Fri, 4 Jul 2014 09:39:07 +0000 (05:39 -0400)
committerMichael Stapelberg <michael@stapelberg.de>
Thu, 10 Jul 2014 20:39:42 +0000 (22:39 +0200)
This request is used by pagers and bars to change the current
desktop likely as a result of some user action. We interpret this as
a request to focus the given workspace.

for more information see:

http://standards.freedesktop.org/wm-spec/latest/ar01s03.html#idm140251368135008

src/handlers.c
testcases/t/217-NET_CURRENT_DESKTOP.t

index 5d21a9855b0031a577342b9cd1acf78e9ae7829b..65fa46a03de34a720cbcd95bfb2c334ad836f821 100644 (file)
@@ -806,6 +806,38 @@ static void handle_client_message(xcb_client_message_event_t *event) {
             DLOG("Not handling WM_CHANGE_STATE request. (window = %d, state = %d)\n", event->window, event->data.data32[0]);
         }
 
+    } else if (event->type == A__NET_CURRENT_DESKTOP) {
+        /* This request is used by pagers and bars to change the current
+         * desktop likely as a result of some user action. We interpret this as
+         * a request to focus the given workspace. See
+         * http://standards.freedesktop.org/wm-spec/latest/ar01s03.html#idm140251368135008
+         * */
+        Con *output;
+        uint32_t idx = 0;
+        DLOG("Request to change current desktop to index %d\n", event->data.data32[0]);
+
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
+            Con *ws;
+            TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
+                if (STARTS_WITH(ws->name, "__"))
+                    continue;
+
+                if (idx == event->data.data32[0]) {
+                    /* data32[1] is a timestamp used to prevent focus race conditions */
+                    if (event->data.data32[1])
+                        last_timestamp = event->data.data32[1];
+
+                    DLOG("Handling request to focus workspace %s\n", ws->name);
+
+                    workspace_show(ws);
+                    tree_render();
+
+                    return;
+                }
+
+                ++idx;
+            }
+        }
     } else {
         DLOG("unhandled clientmessage\n");
         return;
index fe2ea675f62fd922368371fdd4fcac321e24ebf4..7ca6fbc26214258d60a8f50993f13c218fde265a 100644 (file)
@@ -71,6 +71,40 @@ is(current_desktop_index, 1, "Open on 0 and view 1");
 cmd 'workspace 2';
 is(current_desktop_index, 2, "Open and view empty");
 
+#########################################################
+# Test the _NET_CURRENT_DESKTOP client request
+# This request is sent by pagers and bars to switch the current desktop (which
+# is like an ersatz workspace) to the given index
+#########################################################
+
+sub send_current_desktop_request {
+    my ($idx) = @_;
+
+    my $msg = pack "CCSLLLLLL",
+        X11::XCB::CLIENT_MESSAGE, # response_type
+        32, # format
+        0, # sequence
+        0,
+        $_NET_CURRENT_DESKTOP,
+        $idx, # data32[0] (the desktop index)
+        0, # data32[1] (can be a timestamp)
+        0, # data32[2]
+        0, # data32[3]
+        0; # data32[4]
+
+    $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
+}
+
+send_current_desktop_request(1);
+is(current_desktop_index, 1, 'current desktop request switched to desktop 1');
+# note that _NET_CURRENT_DESKTOP is an index and that in this case, workspace 1
+# is at index 1 as a convenience for the test
+is(focused_ws, '1', 'current desktop request switched to workspace 1');
+
+send_current_desktop_request(0);
+is(current_desktop_index, 0, 'current desktop request switched to desktop 0');
+is(focused_ws, '0', 'current desktop request switched to workspace 0');
+
 exit_gracefully($pid);
 
 done_testing;