问题
I have problems reading some XWindow ICCCM Properties.
The problem actually is when i try to read _NET_WM_STATUS property. The function i'm using is:
int get_property_value(Display* display, Window window,char *propname, long max_length,
unsigned long *nitems_return, unsigned char **prop_return){
int result;
Atom property;
Atom actual_type_return;
int actual_format_return;
unsigned long bytes_after_return;
unsigned char* prop_to_return;
unsigned long n_items;
printf("-----GET_PROPERTY_VALUE-------\n");
printf("\tPropname: %s\n", propname);
property = XInternAtom(display, propname, True);
if(property==None){
printf("\tWrong Atom\n");
return;
}
result = XGetWindowProperty(display, window, property, 0, /* long_offset */
(~0L), /* long_length */
False, /* delete */
AnyPropertyType, /* req_type */
&actual_type_return,
&actual_format_return,
&n_items, &bytes_after_return, &prop_to_return);
if (result != Success){
printf("\tXGetWindowProperty failed\n");
return (-1);
} else {
printf("\tActual Type: %s\n", XGetAtomName(display,property));
printf("\tProperty format: %d\n", actual_format_return);
//printf("Actual property return: %s\n", XGetAtomName(display,actual_type_return));
printf("\tByte after return: %ld\n", bytes_after_return);
printf("\tnitems return: %d\n", n_items);
printf("\tprop return: %s\n", prop_to_return);
}
printf("-----END OF GET_PROPERTY_VALUE-------\n");
return (0);
}
The get_property_value function is called after a ClientMessage is received, and this is the piece of code that handle the Event:
case ClientMessage:
printf("ClientMessage\n");
printf("Message: %s\n", XGetAtomName(display,local_event.xclient.message_type));
unsigned long nitems_return;
unsigned char *prop_return;
get_property_value(display, local_event.xclient.window, XGetAtomName(display,local_event.xclient.message_type), 256, &nitems_return, (unsigned char **)&prop_return);
break;
But when i read properties sometimes i get a property with no values, is that possible? The problem mainly is when i'm trying read AtomProperties sent from firefox (i'm trying to read the _NET_WM_STATE value) in ClientMessage Event.
As you can see from the output the property name is correctly read, but then it seems that it doesn't contains any item.
ClientMessage
Message: _NET_WM_STATE
-----GET_PROPERTY_VALUE-------
Propname: _NET_WM_STATE
Actual Type: _NET_WM_STATE
Property format: 0
Byte after return: 0
nitems return: 0
prop return: (null)
-----END OF GET_PROPERTY_VALUE-------
回答1:
I don't have enough rep to comment yet (I'm kind of new to this), but I've been spending some time wrestling Xlib myself and I'll try to see if I can help. I wrote a small program incorporating your code:
#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>
int get_property_value(Display* display, Window window,char *propname, long max_length,
unsigned long *nitems_return, unsigned char **prop_return){
int result;
Atom property;
Atom actual_type_return;
int actual_format_return;
unsigned long bytes_after_return;
unsigned char* prop_to_return;
unsigned long n_items;
printf("-----GET_PROPERTY_VALUE-------\n");
printf("\tPropname: %s\n", propname);
property = XInternAtom(display, propname, True);
if(property==None){
printf("\tWrong Atom\n");
return;
}
result = XGetWindowProperty(display, window, property, 0, /* long_offset */
(~0L), /* long_length */
False, /* delete */
AnyPropertyType, /* req_type */
&actual_type_return,
&actual_format_return,
&n_items, &bytes_after_return, &prop_to_return);
if (result != Success){
printf("\tXGetWindowProperty failed\n");
return (-1);
} else {
printf("\tActual Type: %s\n", XGetAtomName(display,actual_type_return));
printf("\tProperty format: %d\n", actual_format_return);
//printf("Actual property return: %s\n", XGetAtomName(display,actual_type_return));
printf("\tByte after return: %ld\n", bytes_after_return);
printf("\tnitems return: %d\n", n_items);
printf("\tprop return: %s %s\n", XGetAtomName(display,*(Atom*)prop_to_return), XGetAtomName(display,((Atom*)prop_to_return)[1]));
}
printf("-----END OF GET_PROPERTY_VALUE-------\n");
return (0);
}
int main(int argc, char** argv) {
Display* dsp = XOpenDisplay(NULL);
unsigned long nitems_return;
unsigned char* prop_return;
get_property_value(dsp, (Window)atoi(argv[1]), "_NET_WM_STATE", 100000, &nitems_return, &prop_return);
return 0;
}
I did change some of the output things: I changed the "Actual type" output to print the name of actual_type_return
rather than property
(since that seemed like a typo) and I changed the "prop return" output to print atom names instead of the binary data. Anyway, I pointed this version of the code at an instance of Firefox running on my computer, and this is what I got:
$ ./xproptest 60817587
-----GET_PROPERTY_VALUE-------
Propname: _NET_WM_STATE
Actual Type: ATOM
Property format: 32
Byte after return: 0
nitems return: 2
prop return: _NET_WM_STATE_MAXIMIZED_VERT _NET_WM_STATE_MAXIMIZED_HORZ
-----END OF GET_PROPERTY_VALUE-------
So, the good news is that your code actually works perfectly on my machine. I'm not sure why it doesn't work on yours, though. Of course, the above output is from when Firefox is maximized; when it is not, the output is this:
$ ./xproptest 60817587
-----GET_PROPERTY_VALUE-------
Propname: _NET_WM_STATE
Actual Type: ATOM
Property format: 32
Byte after return: 0
nitems return: 0
prop return:
…and then a couple errors about how I'm reading invalid Atoms because the code above just assumes there are two. This is the correct output for when a property is empty and has no values; however, notice how my property format is 32 and yours is 0. From reading the manuals, it looks like the only way to get a 0 property format out of a successful call to XGetWindowProperty
is to call it on a property that doesn't exist. I'm not sure why your Firefox wouldn't have _NET_WM_STATE
set, though.
In summary, my guess is that your code actually functions perfectly (besides the typo on one of the outputs), but that for some reason the property that you're trying to read doesn't exist on the window you're trying to read it from. If I'm right, if you examine the value of actual_type_return
after reading the property you should find that it is None
. Furthermore, you should be able to (if you haven't already) print the window id you're attempting to read from in your code (window
) and use xwininfo
and xprop
with the -id
flag in order to check whether the window you're reading from is the one that you think it is and whether it actually has the property that you're trying to read. Hopefully this will help you to figure out what the actual problem is.
来源:https://stackoverflow.com/questions/31187800/xlib-xgetwindowproperty-zero-items-returned