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; |