4

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-------
Ivan
  • 4,186
  • 5
  • 39
  • 72
  • any idea? I'm really stuck with that issue, and i can't find any helpful documentation, this seems to happen only with firefox. – Ivan Jul 07 '15 at 23:45
  • I don't think you'll get over this easily. Firefox doesn't use the window system as normal applications do. You probably should split the questions because "unhiding firefox menu" is a different question than the original one (you'll get more visibility that way IMO). – Daniele Ricci Jul 16 '15 at 14:34
  • Thank you daniele! I'll follow your suggestion, and create a separate question for the firefox related issues. – Ivan Jul 21 '15 at 09:24

1 Answers1

5

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.

hdastwb
  • 149
  • 2
  • I really appreciate your help, even if it doesn't answer to all my questions, is at least starting point. I'll give you a +1 for your answer. Anyway, what is not still clear to me is why the menu doesn't show up. When i click on it. But What i can check is if i'm reading the property from the wrong window. I'll check and let you know. – Ivan Jul 13 '15 at 09:28
  • Hdast anyway what i don't understand is that i try to read this property after a ClientMessage event, and why i'm reading a null property, i update the code in my question pointing where the get_property_value is called. – Ivan Jul 13 '15 at 10:47
  • since i moved the second part of this question to another one, i will accept your answer! Thank you for your effort! If you have any idea, on how to help me, here is the new question: http://stackoverflow.com/questions/31535560/xlib-and-firefox-behavior – Ivan Jul 21 '15 at 09:44