You are not logged in.

#1 2016-02-08 16:13:43

ttz
Member
From: My Box
Registered: 2013-08-01
Posts: 56

[solved] How To Obtain Atom Value From XGetWindowProperty

I've done a search through topic titles and read through a few threads, haven't found anything that specifically addresses this.

I'm trying to write some code using Xlib and C to verify if a window has a value of "_NET_WM_WINDOW_TYPE_DESKTOP"  assigned to its "_NET_WM_WINDOW_TYPE" atom.

The relevant code is:

// XDPY is already defined earlier in code as the X display
prop_desktop = XInternAtom(XDPY, "_NET_WM_WINDOW_TYPE", True);

// assume everything here is already defined
int status = XGetWindowProperty(XDPY, child, prop_desktop,
						 0L, 1L, False,
						 AnyPropertyType, &type, &format,
						 &length, &after, &data);

if (status == Success and type != None)
    printf("Atom Property Value: %s \n", (const char *) data);

According to Xlib docs, the variable <data> should contain the value of the property found by XGetWindowProperty. However, <data> does not show up as "_NET_WM_WINDOW_TYPE_DESKTOP", unlike when I call <xprop> on that specific window; the <printf> call merely returns a single character (I am guessing this is because XGetWindowProperty feeds <data> a long data type, and <printf> is just doing a direct translation).

For example, what I might see is:

Atom Property Value: n

(the character varies each time I restart X).

Using <xprop> will specifically return

_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DESKTOP

How does one get the value (the right hand side of the above equality) of a window's atom using Xlib?

Last edited by ttz (2016-02-08 17:52:47)


Character shines in the great moments, but is polished in the little ones.

Offline

#2 2016-02-08 17:13:43

Vain
Member
Registered: 2008-10-19
Posts: 179
Website

Re: [solved] How To Obtain Atom Value From XGetWindowProperty

You already get the value. smile

However, an Atom is just a number. Printing it like that will return random-ish data or even crash ("data" is a pointer to an array of Atoms, not a C string). This is also why you have to call `XInternAtom(XDPY, "_NET_WM_WINDOW_TYPE", True);`: It returns the number/atom which was internally assigned to that atom name.

What you want to do is something like this:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>

int
main(int argc, char **argv)
{
    Atom prop_desktop, prop_type, prop, da;
    char *an;
    Display *dpy;
    int di;
    int status;
    unsigned char *prop_ret = NULL;
    unsigned long dl;
    Window child;

    if (argc == 2)
        child = atoi(argv[1]);
    else
        exit(EXIT_FAILURE);

    dpy = XOpenDisplay(NULL);

    prop_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", True);
    prop_desktop = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", True);

    status = XGetWindowProperty(dpy, child, prop_type, 0L, sizeof (Atom), False,
                                XA_ATOM, &da, &di, &dl, &dl, &prop_ret);

    if (status == Success && prop_ret)
    {
        prop = ((Atom *)prop_ret)[0];

        /* Debug output, not really relevant: Re-resolve atom number to
         * printable name */
        an = XGetAtomName(dpy, prop);
        fprintf(stderr, "Type found: %s\n", an);
        if (an)
            XFree(an);

        /* Compare internal atom numbers */
        if (prop == prop_desktop)
            fprintf(stderr, "It's a desktop window!\n");
    }

    exit(EXIT_SUCCESS);
}

"&da, &di, &dl, &dl" are just dummies. Note the fancy type casting of "prop_ret": We treat it as a pointer to an Atom (or a pointer to an array of Atoms) and then use the first item in that array.

This example accepts a window ID as argv[1], e.g.:

$ gcc -Wall -Wextra -o bla bla.c -lX11
$ xwininfo
... click on some window to find its ID ...
$ ./bla $(( 0x602d3c ))
Type found: _NET_WM_WINDOW_TYPE_NORMAL

Note that this is actually a list of atoms, not a single atom: https://specifications.freedesktop.org/ … 0472629520. In theory, a client could define multiple window types. Most clients don't, but, well, ...

Also note that an Atom is not a single byte. See also: `printf("%lu\n", sizeof (Atom));`.

(I always print debug messages to stderr to avoid line buffering issues.)

Offline

#3 2016-02-08 17:34:01

ttz
Member
From: My Box
Registered: 2013-08-01
Posts: 56

Re: [solved] How To Obtain Atom Value From XGetWindowProperty

Thanks vain; I think the crux of my issue was that I could not understand how to properly compare what the XGetWindowProperty was returning to <prop_ret>. The documentation I found online was not clear (to me at least) what type <prop_ret> was:

https://tronche.com/gui/x/xlib/window-i … perty.html

I will give this a try and see if it solves my issue smile


Character shines in the great moments, but is polished in the little ones.

Offline

#4 2016-02-08 17:52:26

ttz
Member
From: My Box
Registered: 2013-08-01
Posts: 56

Re: [solved] How To Obtain Atom Value From XGetWindowProperty

Yes, I think this is what I was looking for. Thank you for taking the time to provide such a detailed answer smile I learned more from this one example than all of the Xlib documentation tongue


Character shines in the great moments, but is polished in the little ones.

Offline

Board footer

Powered by FluxBB