X11根据区域位置检索最上面的窗口

时间:2018-08-22 10:58:55

标签: c x11 xlib

我目前正在寻找检索存在于某个位置的窗口。我已经检索了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;
}

问题在于窗口似乎没有排序。

如何获取最上方的窗口以确保获得给定位置的适当窗口?

1 个答案:

答案 0 :(得分:1)

XQueryTree()以堆叠顺序返回窗口,最顶部最后一个。

  

说明

     

XQueryTree()函数返回根ID,父窗口ID,   没有子窗口列表的指针(NULL   子代),以及列表中指定子代的数量   窗口。 子项按当前堆叠顺序列出,从   最底部(第一个)到顶部(最后一个)。 XQueryTree()返回零   失败,成功则返回非零值。释放非NULL个孩子   列出不再需要的列表时,请使用XFree()

我从来没有为此目的使用过调用,并且多年来没有进行过直接的X11编程,但是我想您可以通过查询根窗口来循环返回的列表并保存窗口ID每次都将覆盖您所需位置的任何窗口中的一个覆盖到同一变量。由于找到的最后一个覆盖该位置的位置是最高位置(至少是在您拨打电话时...),因此该位置就是该位置处可见窗口的窗口ID。