[PATCH] Xi: use correct touch event type for pointer emulation

Carlos Garnacho carlosg at gnome.org
Fri Apr 5 12:07:49 PDT 2013

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  <carlosg at gnome.org>

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

More information about the xorg-devel mailing list