我试图将X Window放在屏幕上的某个位置。当我向人们要求函数执行此操作时,他们表示您只需递归调用XQueryTree。
这是我认为有些错误的代码片段。当我调试它时,它似乎工作得很好。唯一的问题是它给出的输出似乎有点奇怪。当我在根窗口上执行XQueryTree时,我得到数百个的孩子,当我只有五个左右打开时。此外,它似乎认为在某个地方有一个顶级窗口,根本没有一个,并返回它作为结果。无论我如何移动我的实际窗口,XQueryTree似乎表明我的窗口顶部还有另一个窗口(不覆盖整个屏幕。)当我看到窗口所在的位置时,它在我桌面上的某个任意点。
如果有任何帮助: 显示来自XOpenDisplay(NULL),我最初传递的根窗口是XDefaultRootWindow(显示)。我正在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;
答案 0 :(得分:4)
我认为您要做的是查询根窗口的_NET_CLIENT_LIST
属性。这将为所有客户端窗口生成一个窗口ID列表,不包括窗口管理器创建的所有“虚拟”窗口。大多数窗口管理器显然支持_NET_CLIENT_LIST
,但您也可以查询是否支持任何给定功能。
答案 1 :(得分:3)
您的代码看起来正确(我还没有测试过),您描述的结果似乎并不奇怪。 Metacity(以及其他X窗口管理器)将在应用程序拥有的窗口周围和附近创建大量窗口,以显示窗口标题,边框和其他装饰。
尝试使用一些更简单的窗口管理器(如TVM)运行测试(甚至根本不使用)。 TVM应该创建比当前窗口管理器少得多的窗口。这应该使事情更容易理解。
然而,通常,与窗口管理器作斗争是一个坏主意。你不能直接使用xlib以更高级别的方式解决问题吗?