我目前正在寻找检索存在于某个位置的窗口。我已经检索了Windows列表,但不确定如何继续检索最上面的窗口。
这是我到目前为止已完成的工作(包含测试主体):
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
typedef struct
{
int x;
int y;
int w;
int h;
} area_coords_t;
static inline Window get_toplevel_parent(Display * display, Window window)
{
Window parent;
Window root;
Window * children;
unsigned int num_children;
while (1) {
if (0 == XQueryTree(display, window, &root, &parent, &children, &num_children)) {
fprintf(stderr, "XQueryTree error\n");
abort(); //change to whatever error handling you prefer
}
if (children) { //must test for null
XFree(children);
}
if (window == root || parent == root) {
return window;
}
else {
window = parent;
}
}
}
static inline void print_windows(Display *display, area_coords_t *area)
{
Window *list;
Window toplevel;
Atom prop = XInternAtom(display, "_NET_CLIENT_LIST",False);
Atom type;
unsigned long len;
XWindowAttributes attr;
if (XGetWindowProperty(display, XDefaultRootWindow(display), prop,
0, 1024, False, XA_WINDOW, &type, &(int) { 0 }, &len, &(unsigned long) { 0 }, (unsigned char **) &list) != Success)
return;
for (unsigned long it = 0; it < len; ++it)
{
toplevel = get_toplevel_parent(display, list[it]);
XGetWindowAttributes(display, toplevel, &attr);
/* Retrieve only windows in the given area */
//if (area->x >= attr.x && area->x <= attr.x + attr.width && area->y >= attr.y && area->y <= attr.y + attr.height)
printf("%dx%dx%dx%d\n", attr.x, attr.y, attr.width, attr.height);
}
}
int main(void)
{
Display *display = XOpenDisplay(NULL);
/* Should retrieve a window occupying at least a pixel at of the bottom right part of the screen of a 1920x1080 screen */
area_coords_t coords = { 1920 / 2, 1080 / 2, 1920 / 2, 1080 / 2 };
print_windows(display, &coords);
return 0;
}
问题在于窗口似乎没有排序。
如何获取最上方的窗口以确保获得给定位置的适当窗口?
答案 0 :(得分:1)
XQueryTree()
以堆叠顺序返回窗口,最顶部最后一个。
说明
XQueryTree()
函数返回根ID,父窗口ID, 没有子窗口列表的指针(NULL
子代),以及列表中指定子代的数量 窗口。 子项按当前堆叠顺序列出,从 最底部(第一个)到顶部(最后一个)。XQueryTree()
返回零 失败,成功则返回非零值。释放非NULL
个孩子 列出不再需要的列表时,请使用XFree()
。
我从来没有为此目的使用过调用,并且多年来没有进行过直接的X11编程,但是我想您可以通过查询根窗口来循环返回的列表并保存窗口ID每次都将覆盖您所需位置的任何窗口中的一个覆盖到同一变量。由于找到的最后一个覆盖该位置的位置是最高位置(至少是在您拨打电话时...),因此该位置就是该位置处可见窗口的窗口ID。