2012-02-20 138 views
3

自4天以来,我尝试了解XLib如何工作,并且我终于明白了这一点。 Si我试图制作一个简短的程序来检索打开的窗口的名称。 对于这一点,我创建了2个功能:XLib窗口名称问题

Window *list (Display *disp, unsigned long *len) { 
    Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type; 
    int form; 
    unsigned long remain; 
    unsigned char *list; 

    if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,XA_WINDOW, 
       &type,&form,len,&remain,&list) != Success) { 
     return 0; 
    } 

    return (Window*)list; 
} 

所以,这第一个函数返回的所有窗口的窗口对象。 然后,我创建了一个函数来从所有这些窗口中检索名称。

char *name (Display *disp, Window win) { 
    Atom prop = XInternAtom(disp,"WM_NAME",False), type; 
    int form; 
    unsigned long remain, len; 
    unsigned char *list; 


    if (XGetWindowProperty(disp,win,prop,0,1024,False,XA_STRING, 
       &type,&form,&len,&remain,&list) != Success) { 

     return NULL; 
    } 

    return (char*)list; 
} 

而且此功能工作正常,一个main.c中例如:

int main(int argc, char* argv[]){ 
    int i; 
    unsigned long len; 
    XKeyEvent esend; 
    Display *disp = XOpenDisplay(NULL); 
    Window *list; 
    char *name; 

     list = (Window*)list(disp,&len); 
    for (i=0;i<(int)len;i++) { 
     name = name(disp,list[i]); 
     printf("%d : %s \n",i,name); 
     free(name); 
     } 
} 

而且,它的作品真的很好,除了它返回的Skype窗口:

1:Xlib的编程手册:键盘和指针事件 - Google Chrome

2:Debian Web [安装] - Oracle VM VirtualBox

3:XChat的:necromoine @ /(+ CSTfnst 10:2)

4:

5:根@根笔记本:〜

6:

并且,号码4和6是空白的(我实际上有两个打开的Skype窗口)。

你能帮我吗。

+0

您是否尝试过使用XFetchName函数来获取窗口名称? – 2012-02-20 17:01:10

+0

是的,它返回(null)。 – ex0ns 2012-02-20 18:48:05

回答

3

A WM_NAME不一定是简单的字符串。它可能是一个复合文本(不同类型的字符串),实际上Skype窗口就是这种情况。您需要使用AnyPropertyType而不是XA_STRING来获取该属性,然后根据实际类型进行格式化。看看xprops的来源,看看它是如何完成的。

+1

谢谢,我只是把XA_STRING改成了AnyPropertyType,让printf像之前一样,它工作得很好,我也看了xprop的源代码,但是我发现它有点复杂。 – ex0ns 2012-02-22 18:12:33

+0

如果标题中包含非ASCII字符,则可能会失败。 – 2014-12-31 09:50:41