I found I needed to recurse down. In Ubuntu 16.04 many Windows were not directly rooted from the top level, instead they appear several layers down... For example
null
null
xeyes
null
null
user@user-virtual-machine: ~
null
null
workspace-test - Java - JnaTest/src/FindWindows.java - Eclipse
- Also sometimes childrenRef returned null
Code
public static void main(String[] args) {
X11 x11 = X11.INSTANCE;
Display display = x11.XOpenDisplay(null);
Window root = x11.XDefaultRootWindow(display);
recurse(x11, display, root, 0);
}
private static void recurse(X11 x11, Display display, Window root, int depth) {
X11.WindowByReference windowRef = new X11.WindowByReference();
X11.WindowByReference parentRef = new X11.WindowByReference();
PointerByReference childrenRef = new PointerByReference();
IntByReference childCountRef = new IntByReference();
x11.XQueryTree(display, root, windowRef, parentRef, childrenRef, childCountRef);
if (childrenRef.getValue() == null) {
return;
}
long[] ids;
if (Native.LONG_SIZE == Long.BYTES) {
ids = childrenRef.getValue().getLongArray(0, childCountRef.getValue());
} else if (Native.LONG_SIZE == Integer.BYTES) {
int[] intIds = childrenRef.getValue().getIntArray(0, childCountRef.getValue());
ids = new long[intIds.length];
for (int i = 0; i < intIds.length; i++) {
ids[i] = intIds[i];
}
} else {
throw new IllegalStateException("Unexpected size for Native.LONG_SIZE" + Native.LONG_SIZE);
}
for (long id : ids) {
if (id == 0) {
continue;
}
Window window = new Window(id);
X11.XTextProperty name = new X11.XTextProperty();
x11.XGetWMName(display, window, name);
System.out.println(String.join("", Collections.nCopies(depth, " ")) + name.value);
x11.XFree(name.getPointer());
recurse(x11, display, window, depth + 1);
}
}