[PATCH 06/10] Create a new dix touch record for an emulated touch with no listeners
Peter Hutterer
peter.hutterer at who-t.net
Tue Apr 17 23:33:18 PDT 2012
On Tue, Apr 17, 2012 at 04:33:25PM -0700, Chase Douglas wrote:
> As a special case, if a pointer emulated touch has no listeners and the
> device is explicitly grabbed for pointer events, create a new dix touch
> record for the grab only.
this should include "and the touch is still physically down".
Cheers,
Peter
> This allows for clients to "hand off" grabs. For example, when dragging
> a window under compiz the window decorator sees the button press and
> then ungrabs the implicit grab. It then tells compiz to grab the device,
> and compiz then moves the window with the pointer motion. This is racy,
> but is allowed by the input protocol for pointer events when there are
> no other clients with a grab on the device.
>
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
> Xi/exevents.c | 28 ++++++++++++++++++++++++++++
> dix/touch.c | 5 +++++
> 2 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index ae3652b..c8bd222 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1610,6 +1610,34 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
> else
> ti = TouchFindByClientID(dev, touchid);
>
> + /* Under the following circumstances we create a new touch record for an
> + * existing touch:
> + *
> + * - The touch may be pointer emulated
> + * - An explicit grab is active on the device
> + * - The grab is a pointer grab
> + *
> + * This allows for an explicit grab to receive pointer events for an already
> + * active touch.
> + */
> + if (!ti && type != ET_TouchBegin && emulate_pointer &&
> + dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
> + (dev->deviceGrab.grab->grabtype == CORE ||
> + dev->deviceGrab.grab->grabtype == XI ||
> + !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) {
> + ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
> + emulate_pointer);
> + if (!ti) {
> + DebugF("[Xi] %s: Failed to create new dix record for explicitly "
> + "grabbed touchpoint %d\n",
> + dev->name, type, touchid);
> + return;
> + }
> +
> + TouchBuildSprite(dev, ti, ev);
> + TouchSetupListeners(dev, ti, ev);
> + }
> +
> if (!ti) {
> DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
> dev->name, type, touchid);
> diff --git a/dix/touch.c b/dix/touch.c
> index af32103..9f849b7 100644
> --- a/dix/touch.c
> +++ b/dix/touch.c
> @@ -852,6 +852,11 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
> if (dev->deviceGrab.grab)
> TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
>
> + /* We set up an active touch listener for existing touches, but not any
> + * passive grab or regular listeners. */
> + if (ev->any.type != ET_TouchBegin)
> + return;
> +
> /* First, find all grabbing clients from the root window down
> * to the deepest child window. */
> for (i = 0; i < sprite->spriteTraceGood; i++) {
> --
> 1.7.9.1
>
More information about the xorg-devel
mailing list