i3 - improved tiling WM


Handle EWMH requests to change current desktop

Patch status: merged

Patch by Tony Crisci

Long description:

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

To apply this patch, use:
curl http://cr.i3wm.org/patch/618/raw.patch | git am

b/src/handlers.c

21
@@ -806,6 +806,39 @@ static void handle_client_message(xcb_client_message_event_t *event) {
22
             DLOG("Not handling WM_CHANGE_STATE request. (window = %d, state = %d)\n", event->window, event->data.data32[0]);
23
         }
24
 
25
+    } else if (event->type == A__NET_CURRENT_DESKTOP) {
26
+        /* This request is used by pagers and bars to change the current
27
+         * desktop likely as a result of some user action. We interpret this as
28
+         * a request to focus the given workspace. See
29
+         * http://standards.freedesktop.org/wm-spec/latest/ar01s03.html#idm140251368135008
30
+         * */
31
+        Con *output;
32
+        uint32_t idx = 0;
33
+        DLOG("Request to change current desktop to index %d\n", event->data.data32[0]);
34
+
35
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
36
+            Con *ws;
37
+            TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
38
+                if (STARTS_WITH(ws->name, "__"))
39
+                    continue;
40
+
41
+                if (idx == event->data.data32[0]) {
42
+                    /* data32[1] is a timestamp used to prevent focus race conditions */
43
+                    if (event->data.data32[1])
44
+                        last_timestamp = event->data.data32[1];
45
+
46
+
47
+                    DLOG("Handling request to focus workspace %s\n", ws->name);
48
+
49
+                    workspace_show(ws);
50
+                    tree_render();
51
+
52
+                    return;
53
+                }
54
+
55
+                ++idx;
56
+            }
57
+        }
58
     } else {
59
         DLOG("unhandled clientmessage\n");
60
         return;

b/testcases/t/217-NET_CURRENT_DESKTOP.t

65
@@ -71,6 +71,40 @@ is(current_desktop_index, 1, "Open on 0 and view 1");
66
 cmd 'workspace 2';
67
 is(current_desktop_index, 2, "Open and view empty");
68
 
69
+#########################################################
70
+# Test the _NET_CURRENT_DESKTOP client request
71
+# This request is sent by pagers and bars to switch the current desktop (which
72
+# is like an ersatz workspace) to the given index
73
+#########################################################
74
+
75
+sub send_current_desktop_request {
76
+    my ($idx) = @_;
77
+
78
+    my $msg = pack "CCSLLLLLL",
79
+        X11::XCB::CLIENT_MESSAGE, # response_type
80
+        32, # format
81
+        0, # sequence
82
+        0,
83
+        $_NET_CURRENT_DESKTOP,
84
+        $idx, # data32[0] (the desktop index)
85
+        0, # data32[1] (can be a timestamp)
86
+        0, # data32[2]
87
+        0, # data32[3]
88
+        0; # data32[4]
89
+
90
+    $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
91
+}
92
+
93
+send_current_desktop_request(1);
94
+is(current_desktop_index, 1, 'current desktop request switched to desktop 1');
95
+# note that _NET_CURRENT_DESKTOP is an index and that in this case, workspace 1
96
+# is at index 1 as a convenience for the test
97
+is(focused_ws, '1', 'current desktop request switched to workspace 1');
98
+
99
+send_current_desktop_request(0);
100
+is(current_desktop_index, 0, 'current desktop request switched to desktop 0');
101
+is(focused_ws, '0', 'current desktop request switched to workspace 0');
102
+
103
 exit_gracefully($pid);
104
 
105
 done_testing;