+
+void toggle_visibility(void)
+{
+ visible = !visible;
+ if (!visible)
+ clear_input_focus();
+ for (monitor_t *m = mon_head; m != NULL; m = m->next)
+ for (node_t *n = first_extrema(m->desk->root); n != NULL; n = next_leaf(n, m->desk->root))
+ window_set_visibility(n->client->window, visible);
+ if (visible)
+ update_input_focus();
+}
+
+void desktop_show(desktop_t *d)
+{
+ if (!visible)
+ return;
+ for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+ window_show(n->client->window);
+}
+
+void desktop_hide(desktop_t *d)
+{
+ if (!visible)
+ return;
+ for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+ window_hide(n->client->window);
+}
+
+void enable_motion_recorder(void)
+{
+ PUTS("enable motion recorder");
+ window_raise(motion_recorder);
+ window_show(motion_recorder);
+}
+
+void disable_motion_recorder(void)
+{
+ PUTS("disable motion recorder");
+ window_hide(motion_recorder);
+}
+
+void update_motion_recorder(void)
+{
+ xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply(dpy, xcb_get_geometry(dpy, root), NULL);
+
+ if (geo != NULL) {
+ window_resize(motion_recorder, geo->width, geo->height);
+ PRINTF("update motion recorder size: %ux%u\n", geo->width, geo->height);
+ }
+
+ free(geo);
+}
+
+void update_input_focus(void)
+{
+ set_input_focus(mon->desk->focus);
+}
+
+void set_input_focus(node_t *n)
+{
+ if (n == NULL)
+ return;
+ xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, n->client->window, XCB_CURRENT_TIME);
+}
+
+void clear_input_focus(void)
+{
+ xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, root, XCB_CURRENT_TIME);
+}
+
+void center_pointer(monitor_t *m)
+{
+ int16_t cx = m->rectangle.x + m->rectangle.width / 2;
+ int16_t cy = m->rectangle.y + m->rectangle.height / 2;
+ window_lower(motion_recorder);
+ xcb_warp_pointer(dpy, XCB_NONE, root, 0, 0, 0, 0, cx, cy);
+ window_raise(motion_recorder);
+}