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