XFetchName始终返回0

时间:2012-01-11 19:47:03

标签: c linux xlib

我尝试编写一个C代码来获取Linux系统中活动窗口的标题,但函数XFetchName总是返回零,我也尝试了XGetWMName,结果相同...... 但是使用xprop,我可以看到“WM_NAME”属性中有一个字符串

任何人都可以告诉我我的代码有什么问题吗?

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


int main( int argc, char* argv[] )
{
      Display *display;
      Window focus;
      char *window_name;
      int revert;

      display = XOpenDisplay(NULL);
      XGetInputFocus(display, &focus, &revert);
      int ret = XFetchName(display, focus, &window_name);
      printf("ret = %d\n", ret);
      if (window_name) printf("Title = %s\n", window_name);
      return 0;
}

感谢。

3 个答案:

答案 0 :(得分:2)

您可以尝试使用XGetWMName功能。虽然XGetWMNameXFetchName的说法都表示他们会返回WM_NAME属性,但似乎它们彼此不同。有时,它们会返回相同的名称。有时,只有XGetWMName会返回名称。

您还可以使用xwininfo -root -tree获取所有窗口的名称,并与XFetchNameXGetWMName的结果进行比较。

此代码可列出所有窗口并打印XFetchNameXGetWMName的窗口ID和结果。您可以使用窗口ID在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);
}

这是一段输出,显示两个函数的结果可能不同。

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)"

以下是显示这些窗口名称的xwininfo -root -tree输出的一部分。 xwininfo:窗口ID:0x2c7(根窗口)(没有名称)

  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

答案 1 :(得分:0)

XFetchName函数返回指定窗口的名称。如果成功,则返回非零状态;否则,没有为窗口设置名称,它返回零。

您需要为窗口设置名称。

我开始了xterm会话并执行了代码并得到了以下输出:

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

OTOH,我尝试编译你的程序并得到以下错误:

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

您需要更改

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

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

答案 2 :(得分:0)

 /*
  * 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使用XGetWMName

请参阅:enter link description here