You identify the windows by name. The window name is a property you can fetch via XGetWindowProperty(), they are unsigned char strings. The name is whatever you have set the window title to, so you can do a strcmp() to find it.
Here's some demo code that fetches a list of all the current windows and prints their names/titles. Nb, I don't use XQueryTree() to get the list, I fetch another property, "_NET_CLIENT_LIST" from the root window.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <errno.h>
/* compile -lX11 */
Window *winlist (Display *disp, unsigned long *len);
char *winame (Display *disp, Window win);
int main(int argc, char *argv[]) {
int i;
unsigned long len;
Display *disp = XOpenDisplay(NULL);
Window *list;
char *name;
if (!disp) {
puts("no display!");
return -1;
}
list = (Window*)winlist(disp,&len);
for (i=0;i<(int)len;i++) {
name = winame(disp,list[i]);
printf("-->%s<--\n",name);
free(name);
}
XFree(list);
XCloseDisplay(disp);
return 0;
}
Window *winlist (Display *disp, unsigned long *len) {
Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type;
int form;
unsigned long remain;
unsigned char *list;
errno = 0;
if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,XA_WINDOW,
&type,&form,len,&remain,&list) != Success) {
perror("winlist() -- GetWinProp");
return 0;
}
return (Window*)list;
}
char *winame (Display *disp, Window win) {
Atom prop = XInternAtom(disp,"WM_NAME",False), type;
int form;
unsigned long remain, len;
unsigned char *list;
errno = 0;
if (XGetWindowProperty(disp,win,prop,0,1024,False,XA_STRING,
&type,&form,&len,&remain,&list) != Success) {
perror("winlist() -- GetWinProp");
return NULL;
}
return (char*)list;
}
Xlib is a tough nut to crack. Here's another function you can throw into the above program to check any property -- the properties are also strings altho they may appear to be defines or macros in the documentation because they are all CAPS (like "_NET_CLIENT_LIST" and "WM_NAME") they are not defined anywhere, you just use them as quoted char strings (this is different than the Atom types, XA_, which are actual defines):
Code:
int getprop (Display *disp, char *name, Window win) {
Atom prop = XInternAtom(disp,name,False), type;
int form, r = 0;
unsigned long len, remain;
unsigned char *list;
char *tname;
errno = 0;
if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType,
&type,&form,&len,&remain,&list) != Success) {
perror("GetWinProp");
return 0;
}
if (type == None) printf("%s is not available.\n",name);
else {
tname = atomtype(type);
printf ("%s (type %s, %lu %d-bit items) remaining: %lu\n",name,tname,len,form,remain);
XFree(tname);
r = 1;
}
XFree(list);
return r;
}
char *atomtype (Atom x) {
char *type = malloc(32);
switch (x) {
case XA_PRIMARY:
strcpy(type,"XA_PRIMARY");
break;
case XA_SECONDARY:
strcpy(type,"XA_SECONDARY");
break;
case XA_ARC:
strcpy(type,"XA_ARC");
break;
case XA_ATOM:
strcpy(type,"XA_ATOM");
break;
case XA_CARDINAL:
strcpy(type,"XA_CARDINAL");
break;
case XA_INTEGER:
strcpy(type,"XA_INTEGER");
break;
case XA_STRING:
strcpy(type,"XA_STRING");
break;
case XA_WINDOW:
strcpy(type,"XA_WINDOW");
break;
case XA_WM_HINTS:
strcpy(type,"XA_WM_HINTS");
break;
default:
sprintf(type,"unlisted (%lu), see Xatom.h",x);
break;
}
return type;
}
I turned the Atom type defines into strings here for human readability in the output.