使用XGetWindowProperty作为窗口标题时出现C-Xlib-BadWindow错误
我想用C语言中的Xlib获取所有打开的windows标题列表。我正在运行Ubuntu 12.04。我使用以下代码来完成此任务:使用XGetWindowProperty作为窗口标题时出现C-Xlib-BadWindow错误,c,window,xlib,C,Window,Xlib,我想用C语言中的Xlib获取所有打开的windows标题列表。我正在运行Ubuntu 12.04。我使用以下代码来完成此任务: #include <X11/Xlib.h> #include <X11/Xatom.h> #include <stdio.h> #include <stdlib.h> Window *list(Display *disp, unsigned long *len) { Atom prop = XInternAtom
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, &len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
所以我想知道是否有人知道这是什么原因/如何修复它
据我所知,list函数正在返回一些我无法检索其名称的窗口,但我不确定
提前谢谢 根据我的评论,由于问题中列出了代码,我得到了编译器警告: 在函数“list”中:14:29:警告:传递的参数为 来自不兼容指针类型的“XGetWindowProperty”[由启用] 默认值]
&type, &form, &len, &remain, &list);
^
在包含的文件中…:
/usr/include/X11/Xlib.h:2688:12:注意:应为'long unsigned int',但参数的类型为'long unsigned int*'
通过从第10个参数中删除运算符地址,将&len
更改为len
,将其传递到list()
作为无符号长*len
,可以修复此问题
注意:在name()
函数中,由于声明为unsigned long len
,运算符的地址是必需的
因此,我从以下代码开始,这些代码在编译时没有警告:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
我只是创建了一个小函数
int catcher(Display*,xerrorvevent*)
来捕获错误,避免运行时终止
如果您有更多的代码需要遵循,我已经包含了对XErrorHandler()
的第二个调用,传递NULL
以恢复默认处理程序
其他一些注释首先通过关闭我创建的最后一个窗口来测试这段代码,但这还不足以确定它在收到错误后是否会继续。所以我做了第二次测试,在测试中我杀死了列表末尾之前的windows,并验证了成功
最后几点注意事项: 显然,错误处理程序过于简化了。捕捉到错误后,将显示消息,程序将继续运行。 但是,窗口项仍会打印,但会反映为
(null)
例如:
希望这能让你开始。。。我将把有趣的部分留给您,比如检测“发生了”哪一个错误,以及调整列表的编号/显示;) 在这里列出的代码中,第14行生成编译器警告“预期为'long unsigned int*',但参数的类型为'long unsigned int**'”,然后main中的len(第38行之后)为0,循环未运行。我将参数(#10)从
&len
更改为len
(因为它已经作为指针传递给list()),它在没有警告的情况下编译,并生成所需的输出,没有错误。在另一个测试中,我在循环之前插入了sleep()
,以便有时间关闭打开的窗口,错误已被复制。非常感谢您的详细回答!!!我还在想办法搞定Xlib!是的,这是可行的,但当它开始看起来好像我可能根本没有得到答案时,我研究了其他替代方案,并使用XQueryTree编写了一个解决方案!我把这个问题留给了我,因为我很好奇是什么导致了这个问题,尽管我希望现在我可以把它作为一个学术练习。有趣的是,运行您的代码时,我没有收到任何错误,也没有(null)s。也许只是编译器警告引起的?我真的希望不是,如果是。。。再次感谢您的帮助!!:D
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
int catcher( Display *disp, XErrorEvent *xe )
{
printf( "Something had happened, bruh.\n" );
return 0;
}
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
sleep( 3 ); // <-- inserted to give me time to close an open window
XSetErrorHandler( catcher ); // <-- inserted to set error handler
int i;
for(i = 0; i < (int)len; i++){
// if(wlist[i] != 0){ // <-- apparently futile?
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
// }
}
XSetErrorHandler( NULL ); // <-- restore the default error handler
return 0;
}
7: neo – Dolphin
8: neo – Dolphin
Something had happened, bruh.
9: (null)
10: neo – Dolphin