2009-07-07 105 views
6

我正试图在屏幕上的某个位置获取X窗口。当我向人们询问一个函数来做到这一点时,他们说你只会递归地调用XQueryTree。我的X11代码有什么问题?

这是我认为是错误的代码片段。当我调试它时,它似乎完美地工作。唯一的问题是它的输出看起来有点奇怪。当我在根窗口上执行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中的一些代码,它将使用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; 
+1

我不敢相信有人真的在这里问一个xlib问题!我已经使用了xlib,但还不足以帮助调试您的问题:( – hhafez 2009-07-07 04:58:47

+0

它会更好,它将您的解决方案发布为答案,而不是编辑问题帖。 – 2015-01-23 13:19:20

回答

3

您的代码看起来权(我没有测试过),而且似乎你所描述的结果不奇怪的。 Metacity(以及其他X窗口管理器)将在应用程序拥有的窗口周围和附近创建大量窗口,以显示窗口标题,边框和其他装饰。

尝试用TVM等简单的窗口管理器运行测试(甚至根本没有)。 TVM应该比当前的窗口管理器创建更少的窗口。这应该使事情更容易理解。

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

+0

这个想法是我想写一些可以作为人工作的东西我认为如果我为xlib编写它,它可以移植到许多系统上,而不仅仅是为我使用的窗口管理器工作,我将尝试使用它与下一个不同的窗口管理器 – 2009-07-07 06:58:50

3

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