Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XGetWindowProperty作为窗口标题时出现C-Xlib-BadWindow错误_C_Window_Xlib - Fatal编程技术网

使用XGetWindowProperty作为窗口标题时出现C-Xlib-BadWindow错误

使用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

我想用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(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