Blob Blame History Raw
From 2844b01a8571d30caa36f3bb22a64be5ed730062 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 14 May 2013 14:51:31 +1000
Subject: [PATCH 33/35] dix: call UpdateDeviceState() for emulated
 TouchEndEvents

ProcessTouchEvents() calls UDS for all touch events, but if the event type
was switched to TouchUpdate(pending end) UDS is a noop.

Daniel Drake found this can cause stuck buttons if a touch grab is
activated, rejected and the touch event is passed to a regular listener.
This sequence causes the TouchEnd to be changed to TouchUpdate(pending end).

The actual TouchEnd event is later generated by the server once it is passed
to the next listener. UDS is never called for this event, thus the button
remains logically down.

A previous patch suggested for UDS to handle TouchUpdate events [1], however
this would release the button when the first TouchEvent is processed, not
when the last grab has been released (as is the case for sync pointer
grabs). A client may thus have the grab on the device, receive a ButtonPress
but see the button logically up in an XQueryPointer request.

This patch adds a call to UDS to TouchEmitTouchEnd(). The device state must
be updated once a TouchEnd event was sent to the last grabbing listener and
the number of grabs on the touchpoint is 0.

[1] http://patchwork.freedesktop.org/patch/13464/

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 35c2e263db01b2b61354298e5e85aa3cae8ac317)
---
 dix/touch.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/dix/touch.c b/dix/touch.c
index 110b1cc..a4b6d7e 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -1122,6 +1122,8 @@ TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resourc
     TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
     GetDixTouchEnd(&event, dev, ti, flags);
     DeliverTouchEvents(dev, ti, &event, resource);
+    if (ti->num_grabs == 0)
+        UpdateDeviceState(dev, &event.device_event);
 }
 
 void
-- 
1.8.2.1