/** * @brief Create the EWMH connection, request all of the atoms and set some * sensible defaults for them. */ void setup_ewmh(void) { xcb_ewmh_coordinates_t viewport[] = { {0, 0} }; xcb_ewmh_geometry_t workarea[] = { {0, conf.bar_bottom ? 0 : wss[cw].bar_height, screen_width, screen_height - wss[cw].bar_height} }; ewmh = calloc(1, sizeof(xcb_ewmh_connection_t)); if (!ewmh) { log_err("Unable to create ewmh connection\n"); exit(EXIT_FAILURE); } if (xcb_ewmh_init_atoms_replies(ewmh, xcb_ewmh_init_atoms(dpy, ewmh), NULL) == 0) log_err("Couldn't initialise ewmh atoms"); xcb_atom_t ewmh_net_atoms[] = { ewmh->_NET_SUPPORTED, ewmh->_NET_SUPPORTING_WM_CHECK, ewmh->_NET_DESKTOP_VIEWPORT, ewmh->_NET_WM_NAME, ewmh->_NET_WM_STATE, ewmh->_NET_CLOSE_WINDOW, ewmh->_NET_WM_STATE_FULLSCREEN, ewmh->_NET_CURRENT_DESKTOP, ewmh->_NET_NUMBER_OF_DESKTOPS, ewmh->_NET_DESKTOP_GEOMETRY, ewmh->_NET_WORKAREA, ewmh->_NET_ACTIVE_WINDOW }; xcb_ewmh_set_supported(ewmh, 0, LENGTH(ewmh_net_atoms), ewmh_net_atoms); xcb_ewmh_set_supporting_wm_check(ewmh, 0, screen->root); xcb_ewmh_set_desktop_viewport(ewmh, 0, LENGTH(viewport), viewport); xcb_ewmh_set_wm_name(ewmh, 0, strlen("howm"), "howm"); xcb_ewmh_set_current_desktop(ewmh, 0, cw); xcb_ewmh_set_number_of_desktops(ewmh, 0, WORKSPACES); xcb_ewmh_set_workarea(ewmh, 0, LENGTH(workarea), workarea); xcb_ewmh_set_desktop_geometry(ewmh, 0, screen_width, screen_height); }
void ewmh_set_supporting(xcb_window_t win) { pid_t wm_pid = getpid(); xcb_ewmh_set_supporting_wm_check(ewmh, root, win); xcb_ewmh_set_supporting_wm_check(ewmh, win, win); xcb_ewmh_set_wm_name(ewmh, win, strlen(WM_NAME), WM_NAME); xcb_ewmh_set_wm_pid(ewmh, win, wm_pid); }
void create_wm_cm_window(xcwm_context_t *context) { context->wm_cm_window = xcb_generate_id(context->conn); printf("Created WM/CM window with XID 0x%08x\n", context->wm_cm_window); xcb_create_window(context->conn, XCB_COPY_FROM_PARENT, context->wm_cm_window, context->root_window->window_id, 0, 0, 1, 1, 0, /* 1x1 size, no border */ XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, 0, NULL); /* Set the name for the window */ xcb_ewmh_set_wm_name(&context->atoms.ewmh_conn, context->wm_cm_window, strlen("xcwm"), "xcwm"); /* Set the atoms for the window */ xcb_ewmh_set_supporting_wm_check(&context->atoms.ewmh_conn, context->root_window->window_id, context->wm_cm_window); xcb_ewmh_set_supporting_wm_check(&context->atoms.ewmh_conn, context->wm_cm_window, context->wm_cm_window); /* Take & announce ownership of the _NET_CM_Sn selection */ xcb_ewmh_set_wm_cm_owner(&context->atoms.ewmh_conn, context->conn_screen, context->wm_cm_window, XCB_CURRENT_TIME, 0, 0); /* Likewise WM_Sn selection */ /* XXX: Need to do this in a way which complies with ICCCM "Manager Selections" i.e. use an actual timestamp, so in the case of races, we either acquire selection or don't */ }
inline void ewmh_update_wm_name(const char *wm_name) { xcb_ewmh_set_wm_name(cfg.ewmh, cfg.screen->root, strlen(wm_name), wm_name); }