问题
im trying to write a C code to get the title of the Active Window in my Linux System, but the Function XFetchName always returnes zero, i also tried XGetWMName, same result... but using xprop, i can see that there is a string in the "WM_NAME" property
can anyone tell me whats wrong with my code?
#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;
}
thanks.
回答1:
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
回答2:
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[])
回答3:
/*
* 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
来源:https://stackoverflow.com/questions/8825661/xfetchname-always-returns-0