基本上我的目标是获取所有窗口(我正在谈论每一个窗口,而不是附加到我的程序中的窗口)并将它们编译成列表。我正在尝试使我的应用程序尽可能跨平台友好,所以我正在为Windows和Linux移植JNA。在Windows中使用JNA非常简单容易。但是,JNA使用XLib时缺少文档和示例并没有使编码过程变得更容易。
This question, regarding to coding with XLib in C++,确实提供了如何使用XLib在X11环境中获取窗口的一些信息。 我基本上需要在Java中实现XQueryTree 。我缺乏知识使我无法轻易地使用此代码,因为我在Java中编码。我从来没有用C ++编写代码,也没试过用XLib编写代码。有什么想法吗?
答案 0 :(得分:1)
XQueryTree在platform.jar中定义。
int XQueryTree(Display display, Window window, WindowByReference root, WindowByReference parent, PointerByReference children, IntByReference childCount);
使用XOpenDisplay()
获取显示。
由于您需要所有窗口,因此您应该使用根窗口作为父窗口(使用XRootWindow()
进行查找)。
通话结束后,children.getValue()
将有一个指向窗口ID块的指针;在root用户,这些是原生long
类型,因此请基于Pointer.getIntArray(0, size)
使用Pointer.getLongArray(0, size)
或Native.LONG_SIZE
,其中size
是childCount
中返回的值}。然后,您可以使用该ID数组来初始化可能传递给其他X11函数的Window
个对象。
使用XFree
后,您需要手动释放返回的阵列内存。
答案 1 :(得分:1)
我发现我需要减速。在Ubuntu 16.04中,许多Windows并没有直接从顶层生成,而是出现了几层...例如
null
null
xeyes
null
null
user@user-virtual-machine: ~
null
null
workspace-test - Java - JnaTest/src/FindWindows.java - Eclipse
代码
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);
}
}