Comment 9 for bug 1310518

Revision history for this message
Eleni Maria Stea (hikiko) wrote :

My findings about this bug, so far:
The problem is that there's a mouse grab by compiz at some point, that is caused by the XGrabButton call in updatePassiveButtonGrabs in window.cpp:
[...]
 else
 {
 /* Grab all buttons */
        XGrabButton (screen->dpy (),
             AnyButton,
             AnyModifier,
      serverFrame, false,
      ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
             GrabModeSync,
      GrabModeAsync,
      None,
             None);
[...]

(I verified that this by replacing the default mouse pointer shape with the XC_pirate: when the bug occured the pointer changed to a pirate head.)

This grab is used by compiz for windows that don't have the focus: when the user clicks inside a window, compiz grabs the mouse so that the mouse events are handled by compiz and not by the window. That's useful in case someone needs to raise a window by clicking on it as opposed to clicking on its frame for example.

The XGrabButton uses the GrabModeSync. According to the XGrabPointer manpage:
if the pointer mode is GrabModeSync the state of the pointer, as seen by client applications, appears to freeze, and the X server generates no further pointer events until the grabbing client calls XAllowEvents or until the pointer grab is released. Actual pointer changes are not lost while the pointer is frozen; they are simply queued in the server for later processing.

(that's why we can't click anywhere after this grab occurs)

I believe that a race condition related to the grabs/ungrabs is triggered here and it's difficult to be found because the passive grab is initiated by the xserver when the conditions set by the XGrabButton call are satisfied, so backtraces are not really helpful.