static void lookat(Display *dpy, Window root, Bool verbose, int maxcmdlen) { Window dummy, *children = NULL, client; unsigned int i, nchildren = 0; /* * clients are not allowed to stomp on the root and ICCCM doesn't yet * say anything about window managers putting stuff there; but, try * anyway. */ print_client_properties (dpy, root, verbose, maxcmdlen); /* * then, get the list of windows */ if (!XQueryTree (dpy, root, &dummy, &dummy, &children, &nchildren)) { return; } for (i = 0; i < nchildren; i++) { client = XmuClientWindow (dpy, children[i]); if (client != None) print_client_properties (dpy, client, verbose, maxcmdlen); } }
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); }