Hey Daniel, Reading through your issue it felt familiar to me, now I figured out why... the patch on http://lists.x.org/archives/xorg-devel/2012-December/034837.html was meant to address this, but went under the radar (and after that below mine...), and now you've stepped on this again. I like more your patch though, feels like a better way to deal with such situation, so:
Reviewed-by: Carlos Garnacho <[email protected]> On mar, 2013-04-02 at 10:43 -0400, Daniel Drake wrote: > In Sugar we are seeing a problem where after using the touchscreen to select > certain UI elements (through a quick touch and release), pointer emulation > gets confused, and further movements of the mouse happen as if the left > mouse button is held down on the virtual core pointer (it is not). > > What seems to be happening is: > > TouchBegin happens, which creates a new TouchInfo, and 2 listeners get > added, a LISTENER_GRAB and a LISTENER_REGULAR. This must represent some > grab placed by the widget in question, plus a grab from Sugar's gesture > handler (which uses XIGrabTouchBegin). > The events here get delivered as intended, and importantly, the TouchBegin > event gets passed to UpdateDeviceState() on the virtual core pointer, causing > the "left mouse button pressed" emulation to happen. > > TouchEnd then happens. The following code in DeliverTouchEndEvent() triggers: > > if ((ti->num_listeners > 1 || > listener->state != LISTENER_HAS_ACCEPTED) && > (ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) { > ev->any.type = ET_TouchUpdate; > ev->device_event.flags |= TOUCH_PENDING_END; > ti->pending_finish = TRUE; > } > > So the event is now changed to be a TouchUpdate. I think this means that we > don't actually deliver any TouchEnd event at the moment. But one important > effect that happens here is that UpdateDeviceState() is called with a > TouchUpdate event, *not* a TouchEnd event at this time, so X thinks the mouse > button is still pressed. > > Then, Sugar's gesture code sends XIRejectTouch, and a lot of stuff happens > (touch history replay, etc). I don't fully understand what happens here, but > I have studied the code enough to see that UpdateDeviceState() does not get > called with a TouchEnd event, which would be required for this mouse button > emulation state to be corrected. > > Taking a step back, pointer emulation seems to be mostly driven by > ProcessTouchEvents, so it seems to me that this code should also be > responsible for passing the TouchEnd event to UpdateDeviceState() to fix > the emulated mouse button state. > > So, restore the original event type here so that the TouchEnd event > correctly makes it all the way to UpdateDeviceState, even if it was > previously wrangled into a TouchUpdate for reasons related to touch > history/ownership. > > --- > > There is related work ongoing at > https://bugs.freedesktop.org/show_bug.cgi?id=56578 > > This patch is intended to go on top of the patches already posted on that > bug. However, in practice I'm not sure if it matters; this bug appears both > before and after the #56578 patches are applied. > > Index: xorg-server-1.14.0/Xi/exevents.c > =================================================================== > --- xorg-server-1.14.0.orig/Xi/exevents.c > +++ xorg-server-1.14.0/Xi/exevents.c > @@ -1614,8 +1614,13 @@ ProcessTouchEvent(InternalEvent *ev, Dev > TouchEndTouch(dev, ti); > } > > - if (emulate_pointer) > + if (emulate_pointer) { > + /* The event type might have been changed above. However, for pointer > + * emulation purposes, we want to restore the original event type for > + * correct processing of TouchEnd events. */ > + ev->any.type = type; > UpdateDeviceState(dev, &ev->device_event); > + } > } > > static void _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
