user-interfacex11window-managers

X11/Xlib: Window always on top


A window should stay on top of all other windows. Is this somehow possible with plain x11/xlib? Googling for "Always on top" and "x11" / "xlib" didn't return anything useful.

I'd avoid toolkits like GTK+, if somehow possible.

I'm using Ubuntu with gnome desktop. In the window menu, there's an option "Always On Top". Is this provided by the X server or the window manager? If the second is the case, is there a general function that can be called for nearly any wm? Or how to do this in an "X11-generic" way?


Edit: I implemented fizzer's answer, now having following code:

XSelectInput(this->display, this->window,
    ButtonPressMask |
    StructureNotifyMask |
    ExposureMask |
    KeyPressMask |
    PropertyChangeMask |
    VisibilityChangeMask ); 
// ...
// In a loop:
if (XPending(this->display) >= 0)
{
    XNextEvent(this->display, &ev);
    switch(ev.type) {
    // ...
    case VisibilityNotify:
        XRaiseWindow(this->display, this->window);
        XFlush(this->display);
    break;
    // ...
    }
}

But the eventhandling and raising nearly never gets executed even my mask is correct?!


Solution

  • You don't want to use XRaiseWindow() to try to stay on top. Some window managers will ignore it entirely. For those that don't, consider what happens if more than one app tries to do this. Boom! That's why the window manager is in charge of stacking windows, not the app.

    The way you do this is to use the protocols defined in the Extended Window Manager Hints (EWMH), see: http://www.freedesktop.org/wiki/Specifications/wm-spec

    Specifically here you want _NET_WM_STATE_ABOVE which is how the "Always on Top" menu item works.

    If you aren't using a toolkit you'll want to get used to scavenging in toolkit source code to figure out how to do things. In this case you could look at the function gdk_window_set_keep_above() in GTK+'s X11 backend. That will show how to use the _NET_WM_STATE_ABOVE hint.