Tuminoid
Tuminoid

Reputation: 9715

Grabbing the X server with XGrabServer

In an embedded Linux system, I'm trying to show a shutdown notification that should override any other windows when shutting down. Now creating the window isn't a problem, but showing the window reliably is. The X server or WM is somehow too busy to draw the notification every time. Considering the limited CPU power we have, its not surprising.

So, I figured I will make it easy to the WM/X by grabbing the X server using gdk_x11_grab_server() (which calls XGrabServer on default display). But when should I call the grab func? If I call it before building my window, prior showing my window or event in expose-event of my window, nothing is drawn to the screen (even in no-load test)!

The documentation says:

The XGrabServer function disables processing of requests and close downs on all other connections than the one this request arrived on.

I suppose that would mean that only requests from my app should be processed, but it seems that is not the case, since nothing is drawn if X is grabbed by my app.

So, how and when should grabbing the X server be used to achieve wanted outcome, or is it totally a wrong tool and I've misunderstood the use (or trying to use it too high level for it to work really).

Upvotes: 2

Views: 1563

Answers (4)

yyny
yyny

Reputation: 1726

There seems to be some confusing as to what XGrabServer actually does precisely, and not just on this question. The man pages are pretty ambiguous about this. We can easily verify though that the server indeed still processes requests from our connection:

// cc grab-test.c `pkg-config --cflags --libs x11`
#include <assert.h>
#include <stdio.h>
#include <unistd.h>

#include <X11/Xlib.h>

int main(void)
{
    // Initialize
    Display* dpy = XOpenDisplay(NULL);
    assert(dpy != NULL);
    int s = DefaultScreen(dpy);
    // Grab the Server
    XGrabServer(dpy); // XFlush(dpy);
    // Create some stuffs
    Window win = XCreateSimpleWindow(dpy, RootWindow(dpy, s), 10, 10, 640, 480, 1, BlackPixel(dpy, s), WhitePixel(dpy, s));
    XSelectInput(dpy, win, ExposureMask);
    XMapWindow(dpy, win);
    XStoreName(dpy, win, "An X11 window");
    // Notice we can query the attributes BEFORE ungrabbing the server
    XWindowAttributes wa;
    XGetWindowAttributes(dpy, win, &wa);
    int width = wa.width;
    int height = wa.height;
    printf("Current window size: %dx%d\n", width, height);
    sleep(2); // Give some time to see the window
    XDestroyWindow(dpy, win); XFlush(dpy);
    sleep(2); // Give some time to NOT see the window
    // Ungrab the server
    XUngrabServer(dpy); // XFlush(dpy);
    // Shutdown
    XCloseDisplay(dpy);
    return 0;
}

There is probably a window manager or composite manager preventing the window from being displayed, if I run the above program in Xephyr (without a window manager or composite manager), I can see a white window for 2 seconds followed by a black screen for 2 seconds, after which all other windows are redrawn again.

Upvotes: 0

Mike Playle
Mike Playle

Reputation: 386

I'd guess that nothing is being drawn because you're opening a normal top level window, in which case the window manager needs to operate on it before it'll be visible; however you've locked out the window manager by calling XGrabServer().

You could try setting OverrideRedirect on the window, which tells the X server that the window manager shouldn't be involved with this window at all. This also has the effect of removing any decorations (title bar, close button, etc) from the window, which could well be what you want for a shutdown notification.

Upvotes: 2

Hasturkun
Hasturkun

Reputation: 36402

You may need to follow the call with XSync/XFlush.

Upvotes: 1

ephemient
ephemient

Reputation: 204718

Shouldn't you follow up with a call to XUngrabServer so that the X server resumes processing requests? All other connections have already been closed because you called XGrabServer, but you obviously need request handling to resume because you want to make requests on your connection.

Upvotes: 0

Related Questions