void x_client_name::update_wm_name(void) { m_wm_name.clear(); xcb_generic_error_t * error; xcb_icccm_get_text_property_reply_t wm_name; xcb_get_property_cookie_t c = xcb_icccm_get_wm_name(m_c(), m_x_client.window()); xcb_icccm_get_wm_name_reply(m_c(), c, &wm_name, &error); // TODO: cause clang to crash, FILE A BUG REPORT #if defined __GNUC__ if (error) { delete error; } else { m_wm_name = std::string(wm_name.name, wm_name.name_len); xcb_icccm_get_text_property_reply_wipe(&wm_name); } #else #error "Fix compilation with anything else but GNUC" #endif }
void set_window_name(xcwm_window_t *window, xcwm_property_t *property) { xcb_get_property_cookie_t cookie; xcb_icccm_get_text_property_reply_t reply; xcb_ewmh_get_utf8_strings_reply_t data; /* Check _NET_WM_NAME first */ cookie = xcb_ewmh_get_wm_name(&window->context->atoms.ewmh_conn, window->window_id); if (xcb_ewmh_get_wm_name_reply(&window->context->atoms.ewmh_conn, cookie, &data, NULL)) { window->name = strndup(data.strings, data.strings_len); xcb_ewmh_get_utf8_strings_reply_wipe(&data); return; } cookie = xcb_icccm_get_wm_name(window->context->conn, window->window_id); if (!xcb_icccm_get_wm_name_reply(window->context->conn, cookie, &reply, NULL)) { window->name = malloc(sizeof(char)); window->name[0] = '\0'; return; } window->name = strndup(reply.name, reply.name_len); xcb_icccm_get_text_property_reply_wipe(&reply); }
void Client::updateState(xcb_ewmh_connection_t* ewmhConn) { xcb_connection_t* conn = ewmhConn->connection; xcb_get_geometry_cookie_t geomCookie; if (!mOwned) geomCookie = xcb_get_geometry_unchecked(conn, mWindow); const xcb_get_property_cookie_t normalHintsCookie = xcb_icccm_get_wm_normal_hints(conn, mWindow); const xcb_get_property_cookie_t leaderCookie = xcb_get_property(conn, 0, mWindow, Atoms::WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 0, 1); const xcb_get_property_cookie_t transientCookie = xcb_icccm_get_wm_transient_for(conn, mWindow); const xcb_get_property_cookie_t hintsCookie = xcb_icccm_get_wm_hints(conn, mWindow); const xcb_get_property_cookie_t classCookie = xcb_icccm_get_wm_class(conn, mWindow); const xcb_get_property_cookie_t nameCookie = xcb_icccm_get_wm_name(conn, mWindow); const xcb_get_property_cookie_t protocolsCookie = xcb_icccm_get_wm_protocols(conn, mWindow, Atoms::WM_PROTOCOLS); const xcb_get_property_cookie_t strutCookie = xcb_ewmh_get_wm_strut(ewmhConn, mWindow); const xcb_get_property_cookie_t partialStrutCookie = xcb_ewmh_get_wm_strut_partial(ewmhConn, mWindow); const xcb_get_property_cookie_t stateCookie = xcb_ewmh_get_wm_state(ewmhConn, mWindow); const xcb_get_property_cookie_t typeCookie = xcb_ewmh_get_wm_window_type(ewmhConn, mWindow); const xcb_get_property_cookie_t pidCookie = xcb_ewmh_get_wm_pid(ewmhConn, mWindow); if (!mOwned) updateSize(conn, geomCookie); updateNormalHints(conn, normalHintsCookie); updateLeader(conn, leaderCookie); updateTransient(conn, transientCookie); updateHints(conn, hintsCookie); updateClass(conn, classCookie); updateName(conn, nameCookie); updateProtocols(conn, protocolsCookie); updateStrut(ewmhConn, strutCookie); updatePartialStrut(ewmhConn, partialStrutCookie); updateEwmhState(ewmhConn, stateCookie); updateWindowTypes(ewmhConn, typeCookie); updatePid(ewmhConn, pidCookie); }
void Client::propertyNotify(xcb_atom_t atom) { #warning Need to notify js that properties have changed warning() << "Got propertyNotify" << Atoms::name(atom) << mWindow; auto ewmhConnection = WindowManager::instance()->ewmhConnection(); auto conn = ewmhConnection->connection; if (atom == XCB_ATOM_WM_NORMAL_HINTS) { const xcb_get_property_cookie_t normalHintsCookie = xcb_icccm_get_wm_normal_hints(conn, mWindow); updateNormalHints(conn, normalHintsCookie); } else if (atom == XCB_ATOM_WM_TRANSIENT_FOR) { const xcb_get_property_cookie_t transientCookie = xcb_icccm_get_wm_transient_for(conn, mWindow); updateTransient(conn, transientCookie); } else if (atom == Atoms::WM_CLIENT_LEADER) { const xcb_get_property_cookie_t leaderCookie = xcb_get_property(conn, 0, mWindow, Atoms::WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 0, 1); updateLeader(conn, leaderCookie); } else if (atom == XCB_ATOM_WM_HINTS) { const xcb_get_property_cookie_t hintsCookie = xcb_icccm_get_wm_hints(conn, mWindow); updateHints(conn, hintsCookie); } else if (atom == XCB_ATOM_WM_CLASS) { const xcb_get_property_cookie_t classCookie = xcb_icccm_get_wm_class(conn, mWindow); updateClass(conn, classCookie); } else if (atom == XCB_ATOM_WM_NAME) { const xcb_get_property_cookie_t nameCookie = xcb_icccm_get_wm_name(conn, mWindow); updateName(conn, nameCookie); } else if (atom == Atoms::WM_PROTOCOLS) { const xcb_get_property_cookie_t protocolsCookie = xcb_icccm_get_wm_protocols(conn, mWindow, Atoms::WM_PROTOCOLS); updateProtocols(conn, protocolsCookie); } else if (atom == ewmhConnection->_NET_WM_STRUT) { const xcb_get_property_cookie_t strutCookie = xcb_ewmh_get_wm_strut(ewmhConnection, mWindow); updateStrut(ewmhConnection, strutCookie); } else if (atom == ewmhConnection->_NET_WM_STRUT_PARTIAL) { const xcb_get_property_cookie_t partialStrutCookie = xcb_ewmh_get_wm_strut_partial(ewmhConnection, mWindow); updatePartialStrut(ewmhConnection, partialStrutCookie); } else if (atom == ewmhConnection->_NET_WM_STATE) { const xcb_get_property_cookie_t stateCookie = xcb_ewmh_get_wm_state(ewmhConnection, mWindow); updateEwmhState(ewmhConnection, stateCookie); } else if (atom == ewmhConnection->_NET_WM_WINDOW_TYPE) { const xcb_get_property_cookie_t typeCookie = xcb_ewmh_get_wm_window_type(ewmhConnection, mWindow); updateWindowTypes(ewmhConnection, typeCookie); } else if (atom == ewmhConnection->_NET_WM_PID) { const xcb_get_property_cookie_t pidCookie = xcb_ewmh_get_wm_pid(ewmhConnection, mWindow); updatePid(ewmhConnection, pidCookie); } else { warning() << "Unhandled propertyNotify atom" << Atoms::name(atom); } }
xcb_window_t Window_With_Name ( xcb_connection_t *dpy, xcb_window_t top, const char *name) { struct wininfo_cookies cookies; atom_net_wm_name = Get_Atom (dpy, "_NET_WM_NAME"); atom_utf8_string = Get_Atom (dpy, "UTF8_STRING"); if (atom_net_wm_name && atom_utf8_string) cookies.get_net_wm_name = xcb_get_net_wm_name (dpy, top); cookies.get_wm_name = xcb_icccm_get_wm_name (dpy, top); cookies.query_tree = xcb_query_tree (dpy, top); xcb_flush (dpy); return recursive_Window_With_Name(dpy, top, &cookies, name, strlen(name)); }
void get_window_title(xcb_window_t win, char *title, size_t len) { xcb_ewmh_get_utf8_strings_reply_t ewmh_txt_prop; xcb_icccm_get_text_property_reply_t icccm_txt_prop; ewmh_txt_prop.strings = icccm_txt_prop.name = NULL; title[0] = '\0'; if (win != XCB_NONE && (xcb_ewmh_get_wm_name_reply(ewmh, xcb_ewmh_get_wm_name(ewmh, win), &ewmh_txt_prop, NULL) == 1 || xcb_icccm_get_wm_name_reply(dpy, xcb_icccm_get_wm_name(dpy, win), &icccm_txt_prop, NULL) == 1)) { char *src = NULL; size_t title_len = 0; if (ewmh_txt_prop.strings != NULL) { src = ewmh_txt_prop.strings; title_len = MIN(len, ewmh_txt_prop.strings_len); } else if (icccm_txt_prop.name != NULL) { src = icccm_txt_prop.name; title_len = MIN(len, icccm_txt_prop.name_len); } if (src != NULL) { strncpy(title, src, title_len); title[title_len] = '\0'; } } }
static xcb_window_t recursive_Window_With_Name ( xcb_connection_t *dpy, xcb_window_t window, struct wininfo_cookies *cookies, const char *name, size_t namelen) { xcb_window_t *children; unsigned int nchildren; int i; xcb_window_t w = 0; xcb_generic_error_t *err; xcb_query_tree_reply_t *tree; struct wininfo_cookies *child_cookies; xcb_get_property_reply_t *prop; if (cookies->get_net_wm_name.sequence) { prop = xcb_get_property_reply (dpy, cookies->get_net_wm_name, &err); if (prop) { if (prop->type == atom_utf8_string) { const char *prop_name = xcb_get_property_value (prop); int prop_name_len = xcb_get_property_value_length (prop); /* can't use strcmp, since prop.name is not null terminated */ if ((namelen == prop_name_len) && memcmp (prop_name, name, namelen) == 0) { w = window; } } free (prop); } else if (err) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } } if (w) { xcb_discard_reply (dpy, cookies->get_wm_name.sequence); } else { #ifdef USE_XCB_ICCCM xcb_icccm_get_text_property_reply_t nameprop; if (xcb_icccm_get_wm_name_reply (dpy, cookies->get_wm_name, &nameprop, &err)) { /* can't use strcmp, since nameprop.name is not null terminated */ if ((namelen == nameprop.name_len) && memcmp (nameprop.name, name, namelen) == 0) { w = window; } xcb_icccm_get_text_property_reply_wipe (&nameprop); } #else prop = xcb_get_property_reply (dpy, cookies->get_wm_name, &err); if (prop) { if (prop->type == XCB_ATOM_STRING) { const char *prop_name = xcb_get_property_value (prop); int prop_name_len = xcb_get_property_value_length (prop); /* can't use strcmp, since prop.name is not null terminated */ if ((namelen == prop_name_len) && memcmp (prop_name, name, namelen) == 0) { w = window; } } free (prop); } #endif else if (err) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } } if (w) { xcb_discard_reply (dpy, cookies->query_tree.sequence); return w; } tree = xcb_query_tree_reply (dpy, cookies->query_tree, &err); if (!tree) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } nchildren = xcb_query_tree_children_length (tree); children = xcb_query_tree_children (tree); child_cookies = calloc(nchildren, sizeof(struct wininfo_cookies)); if (child_cookies == NULL) Fatal_Error("Failed to allocate memory in recursive_Window_With_Name"); for (i = 0; i < nchildren; i++) { if (atom_net_wm_name && atom_utf8_string) child_cookies[i].get_net_wm_name = xcb_get_net_wm_name (dpy, children[i]); child_cookies[i].get_wm_name = xcb_icccm_get_wm_name (dpy, children[i]); child_cookies[i].query_tree = xcb_query_tree (dpy, children[i]); } xcb_flush (dpy); for (i = 0; i < nchildren; i++) { w = recursive_Window_With_Name (dpy, children[i], &child_cookies[i], name, namelen); if (w) break; } if (w) { /* clean up remaining replies */ for (/* keep previous i */; i < nchildren; i++) { if (child_cookies[i].get_net_wm_name.sequence) xcb_discard_reply (dpy, child_cookies[i].get_net_wm_name.sequence); xcb_discard_reply (dpy, child_cookies[i].get_wm_name.sequence); xcb_discard_reply (dpy, child_cookies[i].query_tree.sequence); } } free (child_cookies); free (tree); /* includes storage for children[] */ return (w); }