XGrabKey: Passive grabs on a key by multiple clients

edmund brown edmndbrwn at gmail.com
Sun Aug 7 19:45:03 PDT 2011


I am using the following basic code in a client to grab and act on
a single specific "hotkey":

/* Only one key is grabbed by the client (no other XGrabKey() call) */
XGrabKey(dpy, hotkeycode, 0,
    DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);

for(i=0; i < MAX_HITS; i++) { /* Main event loop */
  XNextEvent(dpy, &ev);
  if (ev.type == KeyPress || ev.type == KeyRelease) {
     * Got an active grab on the hotkey at this point, but this
     * active grab is auto-terminated at key release (RTFM).
    printf("Key event %d: keycode=%d\n", i, ev.xkey.keycode);

When this client is started but the hotkey has not been pressed yet,
the execution blocks at the XNextEvent() call in the very first pass
through the loop (i==0).  If a second instance of the client is now
started (with no occurrence of the hotkey still), its XGrabKey() call
returns a BadAccess error, which is what I had expected.

Now suppose that we hit the hotkey a few times (with the first client
as the only one running), so that the loop is traversed a few times.
(The client keeps receiving the hotkey hits globally, irrespective of
focus, so the hotkey seems to remain in a passive grab by the client.)
We then stop hitting the hotkey, so that execution again blocks at the
XNextEvent() call in the loop, but with i > 0.  But now if a second
instance of the client is again started, its XGrabKey() call (on the
same hotkey) does not see the BadAccess error any more!  In fact,
the second client this time is able to successfully install a passive
grab on the hotkey, _overriding_ the first client's grab, and all
subsequent hotkey presses go to the second client, irrespective
of focus.  (If the second client is terminated, the first client's
passive grab seems to be restored, as subsequent presses of the
hotkey are sent to the first client again.)

Note that all this happens irrespective of focus target.

Q:  I am fairly new to Xlib programming and find it puzzling that
other clients are able to override passive grabs on a key by
previously running clients.  Is this a feature?

I would expect that the first client's passive grab, even after
some hotkey presses, will prevent another client's XGrabKey() call
on the same key via a BadAccess error, but that is not the case.

Can anyone please explain this?

Thanks very much.

Edmond Brown


More information about the xorg mailing list