static void nextwin (void) { xcb_query_tree_reply_t *r; xcb_window_t *c,t = 0; xcb_get_window_attributes_cookie_t ac; xcb_get_window_attributes_reply_t *ar; r = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), 0); if (!r || !r->children_len) return; c = xcb_query_tree_children(r); for (unsigned int i=0; i < r->children_len; i++) { ac = xcb_get_window_attributes(conn, c[i]); ar = xcb_get_window_attributes_reply(conn, ac, NULL); if (ar && ar->map_state == XCB_MAP_STATE_VIEWABLE) { if (!(ar->override_redirect || c[i] == (*focuswin))) { t = c[i]; } break; } } if (t) { focus(t, ACTIVE); center_pointer(t); } free(r); }
static xcb_visualtype_t * get_visualtype_for_window(xcb_connection_t *conn, xcb_window_t window, unsigned *depth) { xcb_query_tree_cookie_t tree_cookie; xcb_get_window_attributes_cookie_t attrib_cookie; xcb_query_tree_reply_t *tree; xcb_get_window_attributes_reply_t *attrib; tree_cookie = xcb_query_tree(conn, window); attrib_cookie = xcb_get_window_attributes(conn, window); tree = xcb_query_tree_reply(conn, tree_cookie, NULL); attrib = xcb_get_window_attributes_reply(conn, attrib_cookie, NULL); if (attrib == NULL || tree == NULL) { free(attrib); free(tree); return NULL; } xcb_window_t root = tree->root; xcb_visualid_t visual_id = attrib->visual; free(attrib); free(tree); xcb_screen_t *screen = get_screen_for_root(conn, root); if (screen == NULL) return NULL; return screen_get_visualtype(screen, visual_id, depth); }
/* * This sets up the DAMAGE extentsion to receive damage events on all * child windows * */ static void set_up_damage_notifications(xcb_connection_t *conn, xcb_screen_t *scr) { xcb_damage_query_version_unchecked(conn, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); dam_ext_data = xcb_get_extension_data(conn, &xcb_damage_id); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL); xcb_window_t *children = xcb_query_tree_children(reply); xcb_get_window_attributes_cookie_t *attribs = (xcb_get_window_attributes_cookie_t *)malloc( sizeof(xcb_get_window_attributes_cookie_t) * reply->children_len); if (!attribs) { errx(EXIT_FAILURE, "Failed to allocate memory"); } for (int i = 0; i < reply->children_len; ++i) { attribs[i] = xcb_get_window_attributes_unchecked(conn, children[i]); } for (int i = 0; i < reply->children_len; ++i) { /* Get attributes to check if input-only window */ xcb_get_window_attributes_reply_t *attrib = xcb_get_window_attributes_reply(conn, attribs[i], NULL); create_damage(conn, children[i], attrib); } free(attribs); free(reply); }
void find_window_by_property(xcb_window_t window, xcb_atom_t property, xcb_window_t *res) { *res = XCB_WINDOW_NONE; xcb_get_property_cookie_t get_property_cookie = xcb_get_property(display, 0, window, property, XCB_ATOM_ANY, 0, 0); xcb_get_property_reply_t *get_property_reply = xcb_get_property_reply(display, get_property_cookie, NULL); if (get_property_reply != NULL) { if (get_property_reply->type != XCB_ATOM_NONE) { *res = window; free(get_property_reply); return; } free(get_property_reply); } xcb_query_tree_cookie_t query_tree_cookie = xcb_query_tree(display, window); xcb_query_tree_reply_t *query_tree_reply = xcb_query_tree_reply(display, query_tree_cookie, NULL); if (query_tree_reply == NULL) return; int length = xcb_query_tree_children_length(query_tree_reply); xcb_window_t *children = xcb_query_tree_children(query_tree_reply); for (int i = 0; i < length; i++) { find_window_by_property(children[i], property, res); if (*res != XCB_WINDOW_NONE) break; } free(query_tree_reply); }
/* * Go through all existing windows (if the window manager is restarted) and manage them * */ void manage_existing_windows(xcb_window_t root) { xcb_query_tree_reply_t *reply; int i, len; xcb_window_t *children; xcb_get_window_attributes_cookie_t *cookies; /* Get the tree of windows whose parent is the root window (= all) */ if ((reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, root), 0)) == NULL) return; len = xcb_query_tree_children_length(reply); cookies = smalloc(len * sizeof(*cookies)); /* Request the window attributes for every window */ children = xcb_query_tree_children(reply); for (i = 0; i < len; ++i) cookies[i] = xcb_get_window_attributes(conn, children[i]); /* Call manage_window with the attributes for every window */ for (i = 0; i < len; ++i) manage_window(children[i], cookies[i], true); free(reply); free(cookies); }
bool DisplayVkXcb::isValidNativeWindow(EGLNativeWindowType window) const { // There doesn't appear to be an xcb function explicitly for checking the validity of a // window ID, but xcb_query_tree_reply will return nullptr if the window doesn't exist. xcb_query_tree_cookie_t cookie = xcb_query_tree(mXcbConnection, window); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(mXcbConnection, cookie, nullptr); if (reply) { free(reply); return true; } return false; }
/* * Find a window that has WM_STATE set in the window tree below win. * Unmapped/unviewable windows are not considered valid matches. * Children are searched in top-down stacking order. * The first matching window is returned, None if no match is found. */ static xcb_window_t Find_Client_In_Children(xcb_connection_t * dpy, xcb_window_t win) { xcb_query_tree_cookie_t qt_cookie; xcb_query_tree_reply_t *tree; xcb_window_t *children; unsigned int n_children; int i; qt_cookie = xcb_query_tree (dpy, win); tree = xcb_query_tree_reply (dpy, qt_cookie, NULL); if (!tree) return XCB_WINDOW_NONE; n_children = xcb_query_tree_children_length (tree); if (!n_children) { free (tree); return XCB_WINDOW_NONE; } children = xcb_query_tree_children (tree); /* Check each child for WM_STATE and other validity */ win = XCB_WINDOW_NONE; for (i = (int) n_children - 1; i >= 0; i--) { if (!Window_Is_Viewable(dpy, children[i])) { /* Don't bother descending into this one */ children[i] = XCB_WINDOW_NONE; continue; } if (!Window_Has_Property(dpy, children[i], atom_wm_state)) continue; /* Got one */ win = children[i]; goto done; } /* No children matched, now descend into each child */ for (i = (int) n_children - 1; i >= 0; i--) { if (children[i] == XCB_WINDOW_NONE) continue; win = Find_Client_In_Children(dpy, children[i]); if (win != XCB_WINDOW_NONE) break; } done: free (tree); /* includes children */ return win; }
QList< xcb_window_t > LinuxWindowCapture::listWindowsRecursive( const xcb_window_t& window ) { QList< xcb_window_t > windows; xcb_connection_t* xcbConn = QX11Info::connection(); xcb_query_tree_cookie_t queryC = xcb_query_tree( xcbConn, window ); CScopedPointer< xcb_query_tree_reply_t > queryR( xcb_query_tree_reply( xcbConn, queryC, nullptr ) ); if ( queryR ) { xcb_window_t* children = xcb_query_tree_children( queryR.data() ); for( auto c = 0; c < xcb_query_tree_children_length( queryR.data() ); ++c ) { windows << children[ c ]; windows << listWindowsRecursive( children[ c ] ); } } return windows; }
void find_toplevel_window(xcb_window_t window, xcb_window_t *res) { for (;;) { xcb_query_tree_cookie_t cookie = xcb_query_tree(display, window); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(display, cookie, NULL); if (reply == NULL) break; if (reply->parent == XCB_WINDOW_NONE || reply->parent == reply->root) { free(reply); break; } window = reply->parent; free(reply); } *res = window; }
/* Generate a XCWM_EVENT_WINDOW_CREATE event for all existing mapped top-level windows when we start */ static void _xcwm_windows_adopt(xcwm_context_t *context, xcwm_event_cb_t callback_ptr) { xcb_query_tree_cookie_t tree_cookie = xcb_query_tree(context->conn, context->root_window->window_id); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(context->conn, tree_cookie, NULL); if (NULL == reply) { return; } int len = xcb_query_tree_children_length(reply); xcb_window_t *children = xcb_query_tree_children(reply); int i; for (i = 0; i < len; i ++) { xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(context->conn, children[i]); xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(context->conn, cookie, NULL); if (!attr) { fprintf(stderr, "Couldn't get attributes for window 0x%08x\n", children[i]); continue; } if (attr->map_state == XCB_MAP_STATE_VIEWABLE) { printf("window 0x%08x viewable\n", children[i]); xcwm_window_t *window = _xcwm_window_create(context, children[i], context->root_window->window_id); if (!window) { continue; } _xcwm_window_composite_pixmap_update(window); xcwm_event_t return_evt; return_evt.window = window; return_evt.event_type = XCWM_EVENT_WINDOW_CREATE; callback_ptr(&return_evt); } else { printf("window 0x%08x non-viewable\n", children[i]); } free(attr); } free(reply); }
static void lookat(xcb_connection_t *dpy, xcb_window_t root, int verbose, int maxcmdlen) { root_list_state *rl = malloc(sizeof(*rl)); if (!rl) return; /* TODO: OOM message */ /* * get the list of windows */ rl->c = dpy; rl->cookie = xcb_query_tree(dpy, root); rl->verbose = verbose; rl->maxcmdlen = maxcmdlen; enqueue(root_list, rl); }
QList< xcb_window_t > LinuxWindowCapture::listWindowsRecursive( xcb_connection_t* dpy, xcb_window_t& window ) { QList< xcb_window_t > windows; xcb_query_tree_reply_t* queryR; xcb_query_tree_cookie_t queryC = xcb_query_tree( dpy, window ); if( ( queryR = xcb_query_tree_reply( dpy, queryC, NULL ) ) ) { xcb_window_t* children = xcb_query_tree_children( queryR ); for( int c = 0; c < xcb_query_tree_children_length( queryR ); ++c ) { windows << children[ c ]; windows << listWindowsRecursive( dpy, children[ c ]); } free( queryR ); } return windows; }
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_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); }
void adopt_orphans(void) { xcb_query_tree_reply_t *qtr = xcb_query_tree_reply(dpy, xcb_query_tree(dpy, root), NULL); if (qtr == NULL) { return; } int len = xcb_query_tree_children_length(qtr); xcb_window_t *wins = xcb_query_tree_children(qtr); for (int i = 0; i < len; i++) { uint32_t idx; xcb_window_t win = wins[i]; if (xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop(ewmh, win), &idx, NULL) == 1) { schedule_window(win); } } free(qtr); }
static void discover (void) { xcb_query_tree_reply_t *r; xcb_window_t *c; r = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL); if (r == NULL) { warnx("cannot get a list of windows"); return; } c = xcb_query_tree_children(r); for (unsigned int i = 0; i < r->children_len; i++) { setup_win(c[i]); focus(c[i], INACTIVE); } nextwin(); }
static void root_list(void *closure) { int i; xcb_window_t *child; xcb_query_tree_reply_t *reply; root_list_state *rl = closure; reply = xcb_query_tree_reply(rl->c, rl->cookie, NULL); if (!reply) goto done; child = xcb_query_tree_children(reply); for (i = 0; i < reply->children_len; i++) { /* Get information about each child */ child_wm_state *cs = malloc(sizeof(*cs) + sizeof(*cs->prop_cookie) + sizeof(*cs->tree_cookie) + sizeof(*cs->win)); if (!cs) goto done; /* TODO: print OOM message */ cs->c = rl->c; cs->verbose = rl->verbose; cs->maxcmdlen = rl->maxcmdlen; cs->prop_cookie = (void *)&cs[1]; cs->tree_cookie = (void *)&cs->prop_cookie[1]; cs->win = (void *)&cs->tree_cookie[1]; cs->orig_win = child[i]; cs->win[0] = child[i]; cs->prop_cookie[0] = xcb_get_property(rl->c, 0, child[i], WM_STATE, XCB_GET_PROPERTY_TYPE_ANY, 0, 0); /* Just in case the property isn't there, get the tree too */ cs->tree_cookie[0] = xcb_query_tree(rl->c, child[i]); cs->list_length = 1; enqueue(child_info, cs); } free(reply); done: free(rl); }
void xconn_clean(xconn_t c) { #if 0 xcb_query_tree_cookie_t wintree; xcb_query_tree_reply_t *rep; xcb_window_t *children; xcb_window_t root; int i,len; if(!c) return; root=xconn_get_root(c); wintree = xcb_query_tree(c->c, root); rep = xcb_query_tree_reply(c->c, wintree, 0); if(!rep) return; len = xcb_query_tree_children_length(rep); children = xcb_query_tree_children(rep); for(i=0;i<len;i++) xcb_kill_client(c->c,children[i]); free(rep); xcb_flush(c->c); #endif }
static SCM scm_dump_client(SCM client_smob) { client_t *client = (client_t *)SCM_SMOB_DATA(client_smob); SCM out_port = scm_current_output_port(); char *str = NULL; int len; const char *fmt = "window: %u\nposition: (%d, %d)\nsize: %u x %u\nborder width: %u\n"; if ((len = asprintf(&str, fmt, client->window, client->rect.x, client->rect.y, client->rect.width, client->rect.height, client->border_width)) < 0) { fprintf(stderr, "asprintf failed\n"); /* not sure what to return here, will figure it out later */ return SCM_UNSPECIFIED; } scm_c_write(out_port, str, len); free(str); xcb_query_tree_cookie_t c = xcb_query_tree(wm_conf.connection, client->window); xcb_query_tree_reply_t *r = xcb_query_tree_reply(wm_conf.connection, c, NULL); if ((len = asprintf(&str, "root: %u\nparent: %u\nchildren_len: %u\n", r->root, r->parent, r->children_len)) < 0) { fprintf(stderr, "asprintf failed\n"); return SCM_UNSPECIFIED; } scm_c_write(out_port, str, len); free(str); if (r) free(r); return SCM_UNSPECIFIED; }
bool LinuxWindowCapture::ExtractWindowProperties( xcb_window_t winId, QRect* winRect, bool* winFocus ) { if( !winId ) return false; xcb_connection_t* xcbConn = QX11Info::connection(); xcb_get_geometry_cookie_t geometryC = xcb_get_geometry( xcbConn, winId ); CScopedPointer< xcb_get_geometry_reply_t > geometryR( xcb_get_geometry_reply( xcbConn, geometryC, nullptr ) ); if( !geometryR ) return false; // assume the parent window is the screen then we can just use the coordinates directly int x = geometryR->x; int y = geometryR->y; CScopedPointer< xcb_query_tree_reply_t > treeR( xcb_query_tree_reply( xcbConn, xcb_query_tree( xcbConn, winId ), nullptr ) ); if ( !treeR ) return false; // if the parent isn't screen translate coords if ( treeR->parent != QX11Info::appRootWindow() ) { xcb_translate_coordinates_cookie_t translateC = xcb_translate_coordinates( xcbConn, winId, QX11Info::appRootWindow(), x, y ); CScopedPointer< xcb_translate_coordinates_reply_t > translateR( xcb_translate_coordinates_reply( xcbConn, translateC, nullptr ) ); if ( !translateR ) return false; x = translateR->dst_x; y = translateR->dst_y; } winRect->setRect( x, y, geometryR->width, geometryR->height ); xcb_get_input_focus_cookie_t focusC = xcb_get_input_focus( xcbConn ); CScopedPointer < xcb_get_input_focus_reply_t > focusR( xcb_get_input_focus_reply( xcbConn, focusC, nullptr ) ); if ( !focusR ) return false; *winFocus = ( focusR->focus == winId ); return true; }
static xcb_window_t recursive_Window_With_Name ( xcb_connection_t *dpy, xcb_window_t window, struct wininfo_cookies *cookies, const char *name) { 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 (strncmp (prop_name, name, prop_name_len) == 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_get_text_property_reply_t nameprop; if (xcb_get_wm_name_reply (dpy, cookies->get_wm_name, &nameprop, &err)) { /* can't use strcmp, since nameprop.name is not null terminated */ if (strncmp (nameprop.name, name, nameprop.name_len) == 0) { w = window; } xcb_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 (strncmp (prop_name, name, prop_name_len) == 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_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); 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); }
void krad_x11_enable_capture (krad_x11_t *x11, uint32_t window_id) { xcb_get_geometry_reply_t *geo; xcb_query_tree_reply_t *tree; xcb_translate_coordinates_cookie_t translateCookie; xcb_translate_coordinates_reply_t *trans; geo = xcb_get_geometry_reply (x11->connection, xcb_get_geometry (x11->connection, window_id), NULL); if (geo == NULL) { window_id = 0; } else { tree = xcb_query_tree_reply (x11->connection, xcb_query_tree (x11->connection, window_id), NULL); if (tree == NULL) { window_id = 0; free (geo); } else { translateCookie = xcb_translate_coordinates (x11->connection, window_id, x11->screen->root, geo->x, geo->y); trans = xcb_translate_coordinates_reply (x11->connection, translateCookie, NULL); if (trans == NULL) { window_id = 0; free (tree); free (geo); } else { x11->width = geo->width; x11->height = geo->height; x11->x = trans->dst_x - geo->x; x11->y = trans->dst_y - geo->y; free (trans); free (tree); free (geo); } } } if (window_id == 0) { x11->width = x11->screen_width; x11->height = x11->screen_height; x11->window = x11->screen->root; } //printf ("capture width %d height %d x %d y %d\n", // x11->width, x11->height, x11->x, x11->y); x11->img = xcb_image_create_native (x11->connection, x11->width, x11->height, XCB_IMAGE_FORMAT_Z_PIXMAP, x11->screen_bit_depth, 0, ~0, 0); if (!x11->img) { exit (15); } x11->stride = x11->img->stride; x11->shminfo.shmid = shmget (IPC_PRIVATE, x11->img->stride * x11->img->height, (IPC_CREAT | 0666)); if (x11->shminfo.shmid == (uint32_t)-1) { xcb_image_destroy (x11->img); failfast ("shminfo fail"); } x11->shminfo.shmaddr = shmat (x11->shminfo.shmid, 0, 0); x11->img->data = x11->shminfo.shmaddr; if (x11->img->data == (uint8_t *)-1) { xcb_image_destroy (x11->img); failfast ("xcb image fail"); } x11->shminfo.shmseg = xcb_generate_id (x11->connection); xcb_shm_attach (x11->connection, x11->shminfo.shmseg, x11->shminfo.shmid, 0); x11->capture_enabled = 1; }
static void child_info(void *closure) { child_wm_state *cs = closure; xcb_window_t orig = cs->orig_win; xcb_connection_t *c = cs->c; int verbose = cs->verbose; int maxcmdlen = cs->maxcmdlen; int i, j; int child_count, num_rep; xcb_query_tree_reply_t **reply; for (i = 0; i < cs->list_length; i++) { xcb_get_property_reply_t *reply; reply = xcb_get_property_reply(c, cs->prop_cookie[i], NULL); if (reply) { if (reply->type) { /* Show information for this window */ print_client_properties(c, cs->win[i], cs->verbose, cs->maxcmdlen); free(reply); /* drain stale replies */ for (j = i+1; j < cs->list_length; j++) { reply = xcb_get_property_reply(c, cs->prop_cookie[j], NULL); if (reply) free(reply); } for (j = 0; j < cs->list_length; j++) { xcb_query_tree_reply_t *rep; rep = xcb_query_tree_reply(c, cs->tree_cookie[j], NULL); if (rep) free(rep); } goto done; } free(reply); } } /* WM_STATE not found. Recurse into children: */ num_rep = 0; reply = malloc(sizeof(*reply) * cs->list_length); if (!reply) goto done; /* TODO: print OOM message, drain reply queue */ for (i = 0; i < cs->list_length; i++) { reply[num_rep] = xcb_query_tree_reply(c, cs->tree_cookie[i], NULL); if (reply[num_rep]) num_rep++; } child_count = 0; for (i = 0; i < num_rep; i++) child_count += reply[i]->children_len; if (!child_count) { /* No children have CS_STATE; try the parent window */ print_client_properties(c, cs->orig_win, cs->verbose, cs->maxcmdlen); goto reply_done; } cs = malloc(sizeof(*cs) + child_count * (sizeof(*cs->prop_cookie) + sizeof(*cs->tree_cookie) + sizeof(*cs->win))); if (!cs) goto reply_done; /* TODO: print OOM message */ cs->c = c; cs->verbose = verbose; cs->maxcmdlen = maxcmdlen; cs->orig_win = orig; cs->prop_cookie = (void *)&cs[1]; cs->tree_cookie = (void *)&cs->prop_cookie[child_count]; cs->win = (void *)&cs->tree_cookie[child_count]; cs->list_length = child_count; child_count = 0; for (i = 0; i < num_rep; i++) { xcb_window_t *child = xcb_query_tree_children(reply[i]); for (j = 0; j < reply[i]->children_len; j++) { cs->win[child_count] = child[j]; cs->prop_cookie[child_count] = xcb_get_property(c, 0, child[j], WM_STATE, XCB_GET_PROPERTY_TYPE_ANY, 0, 0); /* Just in case the property isn't there, get the tree too */ cs->tree_cookie[child_count++] = xcb_query_tree(c, child[j]); } } enqueue(child_info, cs); reply_done: for (i = 0; i < num_rep; i++) free(reply[i]); free(reply); done: free(closure); }
/* * List all hidden windows. * */ int findhidden(void) { xcb_query_tree_reply_t *reply; int i; int len; xcb_window_t *children; xcb_get_window_attributes_reply_t *attr; uint32_t state; xcb_get_property_cookie_t cookie; xcb_icccm_get_text_property_reply_t prop; xcb_generic_error_t *error; /* Get all children. */ reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, screen->root), 0); if (NULL == reply) { return -1; } len = xcb_query_tree_children_length(reply); children = xcb_query_tree_children(reply); /* List all hidden windows on this root. */ for (i = 0; i < len; i ++) { attr = xcb_get_window_attributes_reply( conn, xcb_get_window_attributes(conn, children[i]), NULL); if (!attr) { fprintf(stderr, "Couldn't get attributes for window %d.", children[i]); continue; } /* * Don't bother windows in override redirect mode. * * This mode means they wouldn't have been reported to us * with a MapRequest if we had been running, so in the * normal case we wouldn't have seen them. */ if (!attr->override_redirect) { state = get_wm_state(children[i]); if (state == XCB_ICCCM_WM_STATE_ICONIC) { /* * Example names: * * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, * 0x76, 0x74 WM_ICON_NAME(STRING) = "urxvt" * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76, * 0x74 WM_NAME(STRING) = "urxvt" */ cookie = xcb_icccm_get_wm_icon_name(conn, children[i]); xcb_icccm_get_wm_icon_name_reply(conn, cookie, &prop, &error); prop.name[prop.name_len] = '\0'; if (printcommand) { /* FIXME: Need to escape : in prop.name. */ printf("'%s':'xdotool windowmap 0x%x windowraise 0x%x'\n", prop.name, children[i], children[i]); } else { puts(prop.name); } } } /* if not override redirect */ free(attr); } /* for */ free(reply); return 0; }
xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md, bool ignoreNonXdndAwareWindows) { if (w == shapedPixmapWindow()->handle()->winId()) return 0; if (md) { xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(xcb_connection(), w); xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(xcb_connection(), cookie, 0); if (!reply) return 0; if (reply->map_state != XCB_MAP_STATE_VIEWABLE) return 0; free(reply); xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w); xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0); if (!greply) return 0; QRect windowRect(greply->x, greply->y, greply->width, greply->height); free(greply); if (windowRect.contains(pos)) { bool windowContainsMouse = !ignoreNonXdndAwareWindows; { xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); bool isAware = reply && reply->type != XCB_NONE; free(reply); if (isAware) { const QPoint relPos = pos - windowRect.topLeft(); // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we // need to check both here so that in the case one is set and the other is not we still get the correct result. if (connection()->hasInputShape()) windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_INPUT); if (windowContainsMouse && connection()->hasXShape()) windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_BOUNDING); if (!connection()->hasInputShape() && !connection()->hasXShape()) windowContainsMouse = true; if (windowContainsMouse) return w; } } xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, 0); if (!reply) return 0; int nc = xcb_query_tree_children_length(reply); xcb_window_t *c = xcb_query_tree_children(reply); xcb_window_t r = 0; for (uint i = nc; !r && i--;) r = findRealWindow(pos - windowRect.topLeft(), c[i], md-1, ignoreNonXdndAwareWindows); free(reply); if (r) return r; // We didn't find a client window! Just use the // innermost window. // No children! if (!windowContainsMouse) return 0; else return w; } } return 0; }