XFetchName always returns 0

可紊 提交于 2019-12-01 06:11:53

You can try using XGetWMName function. Although the discriptions of XGetWMName and XFetchName both say they will return the WM_NAME property, it seems that they are different from each other. Some times, they return the same name. Some times, only XGetWMName returns the name.

You can also use xwininfo -root -tree to get all the windows' name, and compare with the result of XFetchName and XGetWMName.

This code can list all the windows and print the window id and result of XFetchName and XGetWMName. You can use the window id to look up in the output of xwininfo -root -tree.

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

void enum_windows(Display* display, Window window, int depth) {
  int i;

  XTextProperty text;
  XGetWMName(display, window, &text);
  char* name;
  XFetchName(display, window, &name);
  for (i = 0; i < depth; i++)
    printf("\t");
  printf("id=0x%x, XFetchName=\"%s\", XGetWMName=\"%s\"\n", window, name != NULL ? name : "(no name)", text.value);

  Window root, parent;
  Window* children;
  int n;
  XQueryTree(display, window, &root, &parent, &children, &n);
  if (children != NULL) {
    for (i = 0; i < n; i++) {
      enum_windows(display, children[i], depth + 1);
    }
    XFree(children);
  }
}

int main() {
  Display* display = XOpenDisplay(NULL);
  Window root = XDefaultRootWindow(display);
  enum_windows(display, root, 0);
}

Here's a piece of output showing that the result of two functions may be different.

id=0x2c7, XFetchName="(no name)", XGetWMName="(null)"
    id=0x400001, XFetchName="(no name)", XGetWMName="(null)"
    id=0x800036, XFetchName="(no name)", XGetWMName="(null)"
        id=0x1400001, XFetchName="(no name)", XGetWMName="c - XFetchName always returns 0 - Stack Overflow - Chromium"
    id=0x1000001, XFetchName="terminator", XGetWMName="terminator"
        id=0x1000002, XFetchName="(no name)", XGetWMName="(null)"
    id=0x1200001, XFetchName="chromium", XGetWMName="chromium"
        id=0x1200002, XFetchName="(no name)", XGetWMName="(null)"

Here's a piece of the output of xwininfo -root -tree showing the name of these windows. xwininfo: Window id: 0x2c7 (the root window) (has no name)

  Root window id: 0x2c7 (the root window) (has no name)
  Parent window id: 0x0 (none)
     29 children:
     0x1200001 "chromium": ("chromium" "Chromium")  10x10+10+10  +10+10
        1 child:
        0x1200002 (has no name): ()  1x1+-1+-1  +9+9
     0x1000001 "terminator": ("terminator" "Terminator")  10x10+10+10  +10+10
        1 child:
        0x1000002 (has no name): ()  1x1+-1+-1  +9+9
     0x800036 (has no name): ()  1364x741+0+25  +0+25
        1 child:
        0x1400001 "c - XFetchName always returns 0 - Stack Overflow - Chromium": ("Chromium" "Chromium")  1364x741+0+0  +1+26
     0x400001 (has no name): ()  10x10+-20+-20  +-20+-20

The XFetchName function returns the name of the specified window. If it succeeds, it returns a nonzero status; otherwise, no name has been set for the window, and it returns zero.

You need to set a name for your window.

I started an xterm session and executed you code and got the following output:

sangeeth@home:~/work/test$ ./a.out 
ret = 1 
Title = sangeeth@home: ~/work/test
sangeeth@home:~/work/test$ 

OTOH, I tried compiling your program and got the following error:

(.text+0x18): undefined reference to `main'

You need to change

int _main( int argc, char* argv[] )

to

int main(int argc, char* argv[]) 
 /*
  * The following functions are internationalized substitutions
  * for XFetchName and XGetIconName using XGetWMName and
  * XGetWMIconName.  
  *
  * Please note that the third arguments have to be freed using free(), 
  * not XFree().
  */
 Status
 I18N_FetchName(dpy, w, winname)
     Display *dpy;
     Window w;
     char ** winname;
 {
     int    status;
     XTextProperty text_prop;
     char **list;
     int    num;

     status = XGetWMName(dpy, w, &text_prop);
     if (!status || !text_prop.value || !text_prop.nitems) return 0;
     status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
     if (status < Success || !num || !*list) return 0;
     XFree(text_prop.value);
     *winname = (char *)strdup(*list);
     XFreeStringList(list);
     return 1;
 }

//XFetchName uses XGetWMName

see: enter link description here

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!