XFetchName 始终返回 0

kil*_*ode 7 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;
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

Hao*_*shu 7

你可以尝试使用XGetWMName函数。虽然双方的描述XGetWMName都说XFetchName会归还WM_NAME财产,但似乎各有各的不同。有时,它们返回相同的名称。有时,仅XGetWMName返回名称。

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

此代码可以列出所有窗口并打印窗口 id 和 的XFetchName结果XGetWMName。您可以使用窗口 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);
}
Run Code Online (Sandbox Code Playgroud)

下面的输出显示两个函数的结果可能不同。

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)"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


San*_*raj -1

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

您需要为您的窗口设置一个名称。

我启动了一个xterm会话并执行了您的代码并得到了以下输出:

sangeeth@home:~/work/test$ ./a.out 
ret = 1 
Title = sangeeth@home: ~/work/test
sangeeth@home:~/work/test$ 
Run Code Online (Sandbox Code Playgroud)

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

(.text+0x18): undefined reference to `main'
Run Code Online (Sandbox Code Playgroud)

你需要改变

int _main( int argc, char* argv[] )
Run Code Online (Sandbox Code Playgroud)

int main(int argc, char* argv[]) 
Run Code Online (Sandbox Code Playgroud)