Comment 61 for bug 1015183

Revision history for this message
In , Peter Hutterer (peter-hutterer) wrote :

Ok, analysis of the bug as follows. To trigger this bug, we need the following client stack:
* touch client with a passive touch grab
* core client with a passive button grab in GrabmodeSync
* optional: core client with button mask on window
The touch client must reject the touch.

As the touch grab activates, all events are sent to the touch client, and stored in the touch event history. When the client rejects, the events are replayed on the next client.

The replayed TouchBegin will trigger the core passive grab, and switch the device's processInputProc to EnqueueEvent().
BUG 1: because touch event history replaying calls DeliverTouchEvents directly, EnqueueEvent is side-stepped and no events end up in the sync'd queue. Later, when the client calls XAllowEvents no events are there for syncing, ComputeFreezes() exits early and the emulated motion/release events are not sent to the client.

Fixing that is possible so that EnqueueEvent is honoured. Tricky though, because it will have a number of side-effects, see below.

BUG 2: because the TouchEnd never ends up in the history (by design) no release event ends up in the queue. So when replaying, the emulated button release is missing. Not sure yet how to fix this.

BUG3: If there's the optional third client, it's implicit passive grab currently does not get released. That's the easiest one to fix.

Side effects of the first bug:
If we use EnqueueEvent() for event history replaying, we will replay touch events into the sync buffer, but not actually process them. If there is at least one touch client below the client with the sync passive core grab, it cannot get touch events until the grabbing client calls XAllowEvents. If that touch client has the ownership mask set, that behaviour is against the protocol spec.

Coincidentally, this bug already exists anyway, it's just gone unnoticed so far because touch clients appear to be generally above the normal clients.

To be compliant with the touch specs, we need to wrap EnqueueEvent to still handle touch events for clients with the ownership mask even if the device is currently synced.