XFetchName总是返回0
即时尝试编写一个C代码来获得我的Linux系统中的活动窗口的标题,但函数XFetchName总是返回零,我也试过XGetWMName,结果相同... 但使用xprop,我可以看到“WM_NAME”属性中有一个字符串XFetchName总是返回0
任何人都可以告诉我我的代码有什么问题吗?
#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;
}
谢谢。
XFetchName
函数返回指定窗口的名称。如果成功,则返回非零状态;否则,没有为该窗口设置名称,并且它返回零。
您需要为您的窗口设置一个名称。
我开始一个xterm
会话和执行你的代码,并得到了以下的输出:
[email protected]:~/work/test$ ./a.out
ret = 1
Title = [email protected]: ~/work/test
[email protected]:~/work/test$
OTOH,我试图编译程序,并得到了以下错误:
(.text+0x18): undefined reference to `main'
你需要改变
int _main(int argc, char* argv[])
到
int main(int argc, char* argv[])
我怀疑'_main()'是因为它是一个大型框架的钩子,可能是实际的问题。 – 2012-01-11 20:13:34
@BrianRoach这是一个很好的观点。我们需要听取来自OP的更多细节。 – 2012-01-11 20:15:48
'_'只是定义一个入口点名称“-Wl,-e__main”,因为我没有使用stdlib – killercode 2012-01-12 01:41:09
您可以尝试使用XGetWMName
函数。尽管XGetWMName
和XFetchName
的描述都表示他们会返回WM_NAME
属性,但它们似乎彼此不同。有时候,他们会返回相同的名字。有时候,只有XGetWMName
返回名称。
您也可以使用xwininfo -root -tree
来获取所有窗口的名称,并与XFetchName
和XGetWMName
的结果进行比较。
此代码可以列出所有窗口并打印窗口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);
}
这里的一个片输出的表示两个函数的结果可以是不同的。
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
/*
* 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
为什么'_'在'_main '? – 2012-01-11 19:55:29
从Xterm运行(默认情况下名称为“xterm”设置),您的代码在我正在使用的计算机(OSX Lion)上运行得非常好。另外,我添加了一个对'XStoreName()'的调用,将其设置为其他第一个,并且按照预期工作,并且您的代码检索新名称就好了。这当然是在将_main()重命名为main()之后的 - 你如何运行你的程序? – 2012-01-11 20:07:37
'_'只是用命令行“-Wl,-e__main”来定义入口点名称,因为我没有使用stdlib,我不认为这必须做任何事情。并仍然从Ubuntu的终端执行时返回0,但从xterm工作,是否有这个原因? – killercode 2012-01-12 01:44:52