Synchronizing _NET_WM_STATE writes and reads

Matthias Käppler m.kaeppler at googlemail.com
Fri Nov 9 00:53:28 PST 2007


Hi,

I have the following problem:
I am sending _NET_WM_STATE messages to the root window in order to perform
window state changes such as minimizing, maximizing, hiding and so forth. As
far as I understand, the window manager is then supposed to apply these
changes and set the according state flags on the target window. However,
when re-reading these state flags immediately after I set them (or better:
after the WM supposedly sets them), they are sometimes set, sometimes only
partially set, and sometimes they aren't set at all (although the actual
state change was successfully performed).

In other words, my code works fine in the sense that when I issue a
maximize, the window is correctly maximized, but the according flags are not
set by the WM (or at least they don't appear in whatever
XGetWindowProperty() returns for _NET_WM_STATE). That smells like a
synchronization issue! However, calling XSync() at every point that even
remotely makes sense to synchronize didn't help at all.

Here is a code example where I set a window state:

int maximizeWindow(Window window)
{
    unsigned long data[] = {
        _NET_WM_STATE_ADD,
        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False),
        0, 0
    };
    Status status = sendClientMessage(window, "_NET_WM_STATE", data);
    XSync(display, False);
    return status;
}

That code works just fine.

And here is the code I use to read these state flags again (I have
"borrowed" most of that code from libwnck):

bool getWindowStates(Window window, Atom atom, Atom **stateList, int *len)
{
    Atom type;
    int format;
    gulong nitems;
    gulong bytes_after;
    unsigned char *data;
    int err, result;

    *stateList = NULL;
    *len = 0;

    type = None;
    result = XGetWindowProperty(display, window, atom, 0, G_MAXLONG,
                   False, XA_ATOM, &type, &format, &nitems,
                   &bytes_after, &data);
    XSync(display, False);

    if (type != XA_ATOM)
    {
        std::cerr << "ERROR: Bad atom type" << std::endl;
        XFree (data);
        return false;
    }

    *stateList = g_new (Atom, nitems);
    memcpy (*stateList, data, sizeof (Atom) * nitems);
    *len = nitems;

    XFree (data);

    return true;
}

Now, calling maximizeWindow() and getWindowStates() immediately after does
sometimes, but NOT ALWAYS yield the two atoms representing the two states
that should be set for the given window.

Any help greatly appreciated!

Best,
Matthias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg/attachments/20071109/1e9aeea5/attachment.html>


More information about the xorg mailing list