我的 X11 代码有什么问题?

发布于 07-27 03:06 字数 1983 浏览 11 评论 0原文

我试图在屏幕上的某个位置获取 X 窗口。 当我向人们询问一个函数来执行此操作时,他们说您只需递归调用 XQueryTree 即可。

这是我认为有些错误的代码片段。 当我调试它时,它似乎工作得很好。 唯一的问题是它给出的输出看起来有点奇怪。 当我在根窗口上执行 XQueryTree 时,我得到了数百个子窗口,而我只打开了五个左右的子窗口。 另外,它似乎认为在某个根本不存在的地方有一个顶级窗口,并将其作为结果返回。 无论我如何移动实际窗口,XQueryTree 似乎都表明在我的窗口顶部还有另一个窗口(没有覆盖整个屏幕)。当我查看它所说的窗口位置时,它位于我桌面上的任意位置。

如果这有任何帮助: 显示来自XOpenDisplay(NULL),我最初传递给它的根窗口是XDefaultRootWindow(display)。 我在 Debian 下使用 Metacity 运行 gnome。

point getwindowatloc(Display * display, Window root, jint x, jint y) {
        Window returnedroot;
        Window returnedparent;
        Window * children;
        unsigned int numchildren;
        XQueryTree(display,root,&returnedroot,&returnedparent,&children, &numchildren);
        XWindowAttributes w;
        int i;
        for(i=numchildren-1; i>=0; i--) {
            XGetWindowAttributes(display,children[i],&w);   
            if(x>=w.x && x<=w.x+w.width && y>=w.y && y <= w.y+w.height) {
                point result={w.x,w.y};
                XFree(children);
                return result;
            } else {
                point result=getwindowatloc(display,children[i],x-w.x,y-w.y);
                if(result.x!=INT_MAX) {
                    result.x+=w.x;
                    result.y+=w.y;
                    XFree(children);
                    return result;
                }
            }
        }
        if(children) {
            XFree(children);
        }
        return notfound;
    }

谢谢!

编辑:对于任何正在搜索类似信息的人:我最终调查了 xwininfo 的来源。 关键函数是 dsimple.c 中的 Find_Client,它以某种方式忽略窗口管理器来获取您实际查找的窗口。 如果您想查看子窗口,这是我添加到 dsimple.c 中的 Select_Window 中的一些代码,它将使用 XTranslateCooperatives 递归地查看子窗口内部。

Window child;
do {
  XTranslateCoordinates(dpy,target_temp,target_win,x,y,&x,&y,&child);
  target_temp=target_win;
  target_win=child;
} while(target_win);
return target_temp;

I am attempting to get the X Window at a certain location on screen. When I asked people for a function to do this, they said you would just call XQueryTree recursively.

This is the code snippet which I think is somehow wrong. When I debug it, it seems to work perfectly. The only problem is that the output it gives seems a little strange. When I do XQueryTree on the root window, I get hundreds of children, when I only have five or so open. Also, it seems to think that there is a top-level window somewhere where there simply isn't one, and returns it as a result. No matter how I move my actual windows around, XQueryTree seems to indicate that there is another window on top of my windows (not covering the entire screen.) When I look at where it says the window is, it is at some arbitrary point on my desktop.

If this is of any help:
The display is from XOpenDisplay(NULL), and the root window I originally pass it is XDefaultRootWindow(display). I am running gnome under debian with metacity.

point getwindowatloc(Display * display, Window root, jint x, jint y) {
        Window returnedroot;
        Window returnedparent;
        Window * children;
        unsigned int numchildren;
        XQueryTree(display,root,&returnedroot,&returnedparent,&children, &numchildren);
        XWindowAttributes w;
        int i;
        for(i=numchildren-1; i>=0; i--) {
            XGetWindowAttributes(display,children[i],&w);   
            if(x>=w.x && x<=w.x+w.width && y>=w.y && y <= w.y+w.height) {
                point result={w.x,w.y};
                XFree(children);
                return result;
            } else {
                point result=getwindowatloc(display,children[i],x-w.x,y-w.y);
                if(result.x!=INT_MAX) {
                    result.x+=w.x;
                    result.y+=w.y;
                    XFree(children);
                    return result;
                }
            }
        }
        if(children) {
            XFree(children);
        }
        return notfound;
    }

Thanks!

EDIT: For anyone who is searching for similar information: I ended up looking into the source of xwininfo. The key function is Find_Client in dsimple.c, which somehow ignores window managers to get the window you are actually looking for. If you want to look into subwindows, this is some code I added to Select_Window in dsimple.c which will recursively look inside subwindows, using XTranslateCoordinates.

Window child;
do {
  XTranslateCoordinates(dpy,target_temp,target_win,x,y,&x,&y,&child);
  target_temp=target_win;
  target_win=child;
} while(target_win);
return target_temp;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

说不完的你爱2024-08-03 03:06:15

我认为您想要做的是查询根窗口的 _NET_CLIENT_LIST 属性。 这将为所有客户端窗口生成一个窗口 ID 列表,不包括窗口管理器创建的所有“虚拟”窗口。 大多数窗口管理器显然都支持_NET_CLIENT_LIST,但您也可以查询是否支持任何给定的功能。

I think what you want to do is query the root window's _NET_CLIENT_LIST property. This will produce a list of Window IDs for all client windows, excluding all of the "virtual" windows created by the window manager. Most window managers apparently support _NET_CLIENT_LIST, but you can also query whether or not any given feature is supported.

这个俗人2024-08-03 03:06:15

您的代码看起来是正确的(我还没有测试过),并且您描述的结果看起来一点也不奇怪。 Metacity(和其他 X 窗口管理器)将在应用程序拥有的窗口周围和附近创建大量窗口,以显示窗口标题、边框和其他装饰。

尝试使用一些更简单的窗口管理器(例如 TVM)(甚至根本不使用)来运行测试。 TVM 创建的窗口应该比当前的窗口管理器少得多。 这应该会让事情更容易理解。

然而,通常与窗口管理器对抗并不是一个好主意。 您不能以更高级别的方式解决您的问题而不必直接使用 xlib 吗?

Your code looks right (I haven't tested it), and the results you describe don't seem strange at all. Metacity (and other X window managers) will create lots of windows around and near the application-owned windows to show the window title, borders and other decorations.

Try running your test with some simpler window manager like TVM (or even none at all). TVM should create a lot less windows than current window managers. This should make things easier to understand.

Usually, however, it's a bad idea to fight against the window manager. Can't you solve your problem in a higher level way withour having to use xlib directly?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文