Peter Hutterer 66aaa5d
From 87685a78e83f990705b7eeb5b3afb3045a8da5ce Mon Sep 17 00:00:00 2001
Peter Hutterer 66aaa5d
From: Hans de Goede <hdegoede@redhat.com>
Peter Hutterer 66aaa5d
Date: Fri, 21 Feb 2014 10:31:44 +0100
Peter Hutterer 66aaa5d
Subject: [PATCH synaptics 08/11] Wait for *new* coordinates on a clickpad
Peter Hutterer 66aaa5d
 click before reporting the click
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
It is possible for a click to get reported before any related touch events
Peter Hutterer 66aaa5d
get reported, here is the relevant part of an evemu-record session on a T440s:
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
E: 3.985585 0000 0000 0000	# ------------ SYN_REPORT (0) ----------
Peter Hutterer 66aaa5d
E: 3.997419 0003 0039 -001	# EV_ABS / ABS_MT_TRACKING_ID   -1
Peter Hutterer 66aaa5d
E: 3.997419 0001 014a 0000	# EV_KEY / BTN_TOUCH            0
Peter Hutterer 66aaa5d
E: 3.997419 0003 0018 0000	# EV_ABS / ABS_PRESSURE         0
Peter Hutterer 66aaa5d
E: 3.997419 0001 0145 0000	# EV_KEY / BTN_TOOL_FINGER      0
Peter Hutterer 66aaa5d
E: 3.997419 0000 0000 0000	# ------------ SYN_REPORT (0) ----------
Peter Hutterer 66aaa5d
E: 5.117881 0001 0110 0001	# EV_KEY / BTN_LEFT             1
Peter Hutterer 66aaa5d
E: 5.117881 0000 0000 0000	# ------------ SYN_REPORT (0) ----------
Peter Hutterer 66aaa5d
E: 5.133422 0003 0039 0187	# EV_ABS / ABS_MT_TRACKING_ID   187
Peter Hutterer 66aaa5d
E: 5.133422 0003 0035 3098	# EV_ABS / ABS_MT_POSITION_X    3098
Peter Hutterer 66aaa5d
E: 5.133422 0003 0036 3282	# EV_ABS / ABS_MT_POSITION_Y    3282
Peter Hutterer 66aaa5d
E: 5.133422 0003 003a 0046	# EV_ABS / ABS_MT_PRESSURE      46
Peter Hutterer 66aaa5d
E: 5.133422 0001 014a 0001	# EV_KEY / BTN_TOUCH            1
Peter Hutterer 66aaa5d
E: 5.133422 0003 0000 3102	# EV_ABS / ABS_X                3102
Peter Hutterer 66aaa5d
E: 5.133422 0003 0001 3282	# EV_ABS / ABS_Y                3282
Peter Hutterer 66aaa5d
E: 5.133422 0003 0018 0046	# EV_ABS / ABS_PRESSURE         46
Peter Hutterer 66aaa5d
E: 5.133422 0001 0145 0001	# EV_KEY / BTN_TOOL_FINGER      1
Peter Hutterer 66aaa5d
E: 5.133422 0000 0000 0000	# ------------ SYN_REPORT (0) ----------
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
Notice the BTN_LEFT event all by itself!
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
If this happens, it may lead to the following problem scenario:
Peter Hutterer 66aaa5d
-touch the touchpad in its right click area
Peter Hutterer 66aaa5d
-let go of the touchpad
Peter Hutterer 66aaa5d
-rapidly click in the middle area, so that BTN_LEFT gets reported before the
Peter Hutterer 66aaa5d
 new coordinates (such as seen in the trace above, this may require some
Peter Hutterer 66aaa5d
 practicing with evemu-record to reproduce)
Peter Hutterer 66aaa5d
-the driver registers the click as a right click because it uses the
Peter Hutterer 66aaa5d
 old coordinates from the cumulative coordinates to determine the
Peter Hutterer 66aaa5d
 click location
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
This commit fixes this by:
Peter Hutterer 66aaa5d
1) Resetting the cumulative coordinates not only when no button is pressed,
Peter Hutterer 66aaa5d
   but also when there is no finger touching the touchpad, so that when
Peter Hutterer 66aaa5d
   we do get a touch the cumulative coordinates start at the right place
Peter Hutterer 66aaa5d
2) Delaying processing the BTN_LEFT down transition if there is no finger
Peter Hutterer 66aaa5d
   touching the touchpad
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
This approach has one downside, if we wrongly identify a touchpad as
Peter Hutterer 66aaa5d
a clickpad, then the left button won't work unless the user touches the
Peter Hutterer 66aaa5d
touchpad while clicking the left button.
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
If we want we can fix this by doing something like this:
Peter Hutterer 66aaa5d
1) Making update_hw_button_state return a delay; and
Peter Hutterer 66aaa5d
2) Tracking that we've delayed BTN_LEFT down transition processing; and
Peter Hutterer 66aaa5d
3) When we've delayed BTN_LEFT down transition return a small delay value; and
Peter Hutterer 66aaa5d
4) If when we're called again we still don't have a finger down, just
Peter Hutterer 66aaa5d
   treat the click as a BTN_LEFT
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
But this is not worth the trouble IMHO, the proper thing to do in this
Peter Hutterer 66aaa5d
scenario is to fix the mis-identification of the touchpad as a clickpad.
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Peter Hutterer 66aaa5d
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer 66aaa5d
(cherry picked from commit bbe4c56c4998a90b478581a4d93717251d8e05be)
Peter Hutterer 66aaa5d
---
Peter Hutterer 66aaa5d
 src/eventcomm.c | 5 +++--
Peter Hutterer 66aaa5d
 src/synaptics.c | 7 +++++++
Peter Hutterer 66aaa5d
 2 files changed, 10 insertions(+), 2 deletions(-)
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
diff --git a/src/eventcomm.c b/src/eventcomm.c
Peter Hutterer 66aaa5d
index 8c30991..c5bc7ad 100644
Peter Hutterer 66aaa5d
--- a/src/eventcomm.c
Peter Hutterer 66aaa5d
+++ b/src/eventcomm.c
Peter Hutterer 66aaa5d
@@ -633,8 +633,9 @@ EventReadHwState(InputInfoPtr pInfo,
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
     SynapticsResetTouchHwState(hw, FALSE);
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
-    /* Reset cumulative values if buttons were not previously pressed */
Peter Hutterer 66aaa5d
-    if (!hw->left && !hw->right && !hw->middle) {
Peter Hutterer 66aaa5d
+    /* Reset cumulative values if buttons were not previously pressed,
Peter Hutterer 66aaa5d
+     * or no finger was previously present. */
Peter Hutterer 66aaa5d
+    if ((!hw->left && !hw->right && !hw->middle) || hw->z < para->finger_low) {
Peter Hutterer 66aaa5d
         hw->cumulative_dx = hw->x;
Peter Hutterer 66aaa5d
         hw->cumulative_dy = hw->y;
Peter Hutterer 66aaa5d
         sync_cumulative = TRUE;
Peter Hutterer 66aaa5d
diff --git a/src/synaptics.c b/src/synaptics.c
Peter Hutterer 66aaa5d
index 4cd45b6..1170963 100644
Peter Hutterer 66aaa5d
--- a/src/synaptics.c
Peter Hutterer 66aaa5d
+++ b/src/synaptics.c
Peter Hutterer 66aaa5d
@@ -2774,6 +2774,12 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
Peter Hutterer 66aaa5d
     if (para->clickpad) {
Peter Hutterer 66aaa5d
         /* hw->left is down, but no other buttons were already down */
Peter Hutterer 66aaa5d
         if (!(priv->lastButtons & 7) && hw->left && !hw->right && !hw->middle) {
Peter Hutterer 66aaa5d
+            /* If the finger down event is delayed, the x and y
Peter Hutterer 66aaa5d
+             * coordinates are stale so we delay processing the click */
Peter Hutterer 66aaa5d
+            if (hw->z < para->finger_low) {
Peter Hutterer 66aaa5d
+                hw->left = 0;
Peter Hutterer 66aaa5d
+                goto out;
Peter Hutterer 66aaa5d
+            }
Peter Hutterer 66aaa5d
             if (is_inside_rightbutton_area(para, hw->x, hw->y)) {
Peter Hutterer 66aaa5d
                 hw->left = 0;
Peter Hutterer 66aaa5d
                 hw->right = 1;
Peter Hutterer 66aaa5d
@@ -2805,6 +2811,7 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
Peter Hutterer 66aaa5d
     if (hw->left && !(priv->lastButtons & 7) && hw->numFingers >= 1)
Peter Hutterer 66aaa5d
         handle_clickfinger(priv, hw);
Peter Hutterer 66aaa5d
Peter Hutterer 66aaa5d
+out:
Peter Hutterer 66aaa5d
     /* Two finger emulation */
Peter Hutterer 66aaa5d
     if (hw->numFingers == 1 && hw->z >= para->emulate_twofinger_z &&
Peter Hutterer 66aaa5d
         hw->fingerWidth >= para->emulate_twofinger_w) {
Peter Hutterer 66aaa5d
--
Peter Hutterer 66aaa5d
1.8.5.3