【问题标题】:What is wrong with my X11 code?我的 X11 代码有什么问题?
【发布时间】:2010-11-08 14:10:58
【问题描述】:

我正在尝试在屏幕上的某个位置获取 X 窗口。当我要求人们提供一个函数来执行此操作时,他们说您只需递归调用 XQueryTree。

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

如果这有任何帮助: 显示来自XOpenDisplay(NULL),我最初传递给它的根窗口是XDefaultRootWindow(display)。我正在使用 metacity 在 debian 下运行 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 的一些代码,它将使用 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;

【问题讨论】:

  • 我不敢相信居然有人在这里问 xlib 问题!我使用过 xlib 但不足以帮助调试您的问题:(
  • 最好将您的解决方案发布为答案,而不是编辑问题帖子。

标签: c x11 xlib xorg


【解决方案1】:

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

【讨论】:

  • 谢谢,但我找到了其他可行的方法。我正在使用来自 xwininfo 的功能来完成这项工作。它可能完全按照你的建议做,我不确定。感谢您的帮助。
【解决方案2】:

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

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

但是,通常情况下,与窗口管理器作斗争是个坏主意。难道你不能直接使用 xlib 以更高层次的方式解决你的问题吗?

【讨论】:

  • 我的想法是我想写一些可以在尽可能多的人平台上运行的东西。我想如果我为 xlib 编写它,它将可以移植到许多系统,而不仅仅是为我使用的窗口管理器工作。接下来我将尝试将它与不同的窗口管理器一起使用。
猜你喜欢
  • 2011-07-28
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2016-01-31
相关资源
最近更新 更多