Re: [PATCH xf86-input-synaptics 8/8] Wait for *new* coordinates on a clickpad click before reporting the click

2014-02-24 Thread Peter Hutterer
On Fri, Feb 21, 2014 at 10:31:44AM +0100, Hans de Goede wrote:
 It is possible for a click to get reported before any related touch events
 get reported, here is the relevant part of an evemu-record session on a T440s:
 
 E: 3.985585   #  SYN_REPORT (0) --
 E: 3.997419 0003 0039 -001# EV_ABS / ABS_MT_TRACKING_ID   -1
 E: 3.997419 0001 014a # EV_KEY / BTN_TOUCH0
 E: 3.997419 0003 0018 # EV_ABS / ABS_PRESSURE 0
 E: 3.997419 0001 0145 # EV_KEY / BTN_TOOL_FINGER  0
 E: 3.997419   #  SYN_REPORT (0) --
 E: 5.117881 0001 0110 0001# EV_KEY / BTN_LEFT 1
 E: 5.117881   #  SYN_REPORT (0) --
 E: 5.133422 0003 0039 0187# EV_ABS / ABS_MT_TRACKING_ID   187
 E: 5.133422 0003 0035 3098# EV_ABS / ABS_MT_POSITION_X3098
 E: 5.133422 0003 0036 3282# EV_ABS / ABS_MT_POSITION_Y3282
 E: 5.133422 0003 003a 0046# EV_ABS / ABS_MT_PRESSURE  46
 E: 5.133422 0001 014a 0001# EV_KEY / BTN_TOUCH1
 E: 5.133422 0003  3102# EV_ABS / ABS_X3102
 E: 5.133422 0003 0001 3282# EV_ABS / ABS_Y3282
 E: 5.133422 0003 0018 0046# EV_ABS / ABS_PRESSURE 46
 E: 5.133422 0001 0145 0001# EV_KEY / BTN_TOOL_FINGER  1
 E: 5.133422   #  SYN_REPORT (0) --
 
 Notice the BTN_LEFT event all by itself!
 
 If this happens, it may lead to the following problem scenario:
 -touch the touchpad in its right click area
 -let go of the touchpad
 -rapidly click in the middle area, so that BTN_LEFT gets reported before the
  new coordinates (such as seen in the trace above, this may require some
  practicing with evemu-record to reproduce)
 -the driver registers the click as a right click because it uses the
  old coordinates from the cumulative coordinates to determine the
  click location
 
 This commit fixes this by:
 1) Resetting the cumulative coordinates not only when no button is pressed,
but also when there is no finger touching the touchpad, so that when
we do get a touch the cumulative coordinates start at the right place
 2) Delaying processing the BTN_LEFT down transition if there is no finger
touching the touchpad
 
 This approach has one downside, if we wrongly identify a touchpad as
 a clickpad, then the left button won't work unless the user touches the
 touchpad while clicking the left button.
 
 If we want we can fix this by doing something like this:
 1) Making update_hw_button_state return a delay; and
 2) Tracking that we've delayed BTN_LEFT down transition processing; and
 3) When we've delayed BTN_LEFT down transition return a small delay value; and
 4) If when we're called again we still don't have a finger down, just
treat the click as a BTN_LEFT
 
 But this is not worth the trouble IMHO, the proper thing to do in this
 scenario is to fix the mis-identification of the touchpad as a clickpad.

indeed, this is not something we need to hack around.

this series is Reviewed-by: Peter Hutterer peter.hutte...@who-t.net except
for the property patch, I'll do some more testing with my clickpad over the
week though.

Cheers,
   Peter

 
 Signed-off-by: Hans de Goede hdego...@redhat.com
 ---
  src/eventcomm.c | 5 +++--
  src/synaptics.c | 7 +++
  2 files changed, 10 insertions(+), 2 deletions(-)
 
 diff --git a/src/eventcomm.c b/src/eventcomm.c
 index fe57aa8..231afbc 100644
 --- a/src/eventcomm.c
 +++ b/src/eventcomm.c
 @@ -675,8 +675,9 @@ EventReadHwState(InputInfoPtr pInfo,
  
  SynapticsResetTouchHwState(hw, FALSE);
  
 -/* Reset cumulative values if buttons were not previously pressed */
 -if (!hw-left  !hw-right  !hw-middle) {
 +/* Reset cumulative values if buttons were not previously pressed,
 + * or no finger was previously present. */
 +if ((!hw-left  !hw-right  !hw-middle) || hw-z  
 para-finger_low) {
  hw-cumulative_dx = hw-x;
  hw-cumulative_dy = hw-y;
  sync_cumulative = TRUE;
 diff --git a/src/synaptics.c b/src/synaptics.c
 index bd14100..59fcf48 100644
 --- a/src/synaptics.c
 +++ b/src/synaptics.c
 @@ -2810,6 +2810,12 @@ update_hw_button_state(const InputInfoPtr pInfo, 
 struct SynapticsHwState *hw,
  if (para-clickpad) {
  /* hw-left is down, but no other buttons were already down */
  if (!(priv-lastButtons  7)  hw-left  !hw-right  
 !hw-middle) {
 +/* If the finger down event is delayed, the x and y
 + * coordinates are stale so we delay processing the click */
 +if (hw-z  para-finger_low) {
 +hw-left = 0;
 +goto out;
 +}
  if (is_inside_rightbutton_area(para, hw-x, hw-y)) {
  hw-left = 0;
  hw-right = 1;
 @@ -2841,6 +2847,7 @@ update_hw_button_state(const InputInfoPtr pInfo, struct 
 SynapticsHwState *hw,
  if 

[PATCH xf86-input-synaptics 8/8] Wait for *new* coordinates on a clickpad click before reporting the click

2014-02-21 Thread Hans de Goede
It is possible for a click to get reported before any related touch events
get reported, here is the relevant part of an evemu-record session on a T440s:

E: 3.985585     #  SYN_REPORT (0) --
E: 3.997419 0003 0039 -001  # EV_ABS / ABS_MT_TRACKING_ID   -1
E: 3.997419 0001 014a   # EV_KEY / BTN_TOUCH0
E: 3.997419 0003 0018   # EV_ABS / ABS_PRESSURE 0
E: 3.997419 0001 0145   # EV_KEY / BTN_TOOL_FINGER  0
E: 3.997419     #  SYN_REPORT (0) --
E: 5.117881 0001 0110 0001  # EV_KEY / BTN_LEFT 1
E: 5.117881     #  SYN_REPORT (0) --
E: 5.133422 0003 0039 0187  # EV_ABS / ABS_MT_TRACKING_ID   187
E: 5.133422 0003 0035 3098  # EV_ABS / ABS_MT_POSITION_X3098
E: 5.133422 0003 0036 3282  # EV_ABS / ABS_MT_POSITION_Y3282
E: 5.133422 0003 003a 0046  # EV_ABS / ABS_MT_PRESSURE  46
E: 5.133422 0001 014a 0001  # EV_KEY / BTN_TOUCH1
E: 5.133422 0003  3102  # EV_ABS / ABS_X3102
E: 5.133422 0003 0001 3282  # EV_ABS / ABS_Y3282
E: 5.133422 0003 0018 0046  # EV_ABS / ABS_PRESSURE 46
E: 5.133422 0001 0145 0001  # EV_KEY / BTN_TOOL_FINGER  1
E: 5.133422     #  SYN_REPORT (0) --

Notice the BTN_LEFT event all by itself!

If this happens, it may lead to the following problem scenario:
-touch the touchpad in its right click area
-let go of the touchpad
-rapidly click in the middle area, so that BTN_LEFT gets reported before the
 new coordinates (such as seen in the trace above, this may require some
 practicing with evemu-record to reproduce)
-the driver registers the click as a right click because it uses the
 old coordinates from the cumulative coordinates to determine the
 click location

This commit fixes this by:
1) Resetting the cumulative coordinates not only when no button is pressed,
   but also when there is no finger touching the touchpad, so that when
   we do get a touch the cumulative coordinates start at the right place
2) Delaying processing the BTN_LEFT down transition if there is no finger
   touching the touchpad

This approach has one downside, if we wrongly identify a touchpad as
a clickpad, then the left button won't work unless the user touches the
touchpad while clicking the left button.

If we want we can fix this by doing something like this:
1) Making update_hw_button_state return a delay; and
2) Tracking that we've delayed BTN_LEFT down transition processing; and
3) When we've delayed BTN_LEFT down transition return a small delay value; and
4) If when we're called again we still don't have a finger down, just
   treat the click as a BTN_LEFT

But this is not worth the trouble IMHO, the proper thing to do in this
scenario is to fix the mis-identification of the touchpad as a clickpad.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 src/eventcomm.c | 5 +++--
 src/synaptics.c | 7 +++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/eventcomm.c b/src/eventcomm.c
index fe57aa8..231afbc 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -675,8 +675,9 @@ EventReadHwState(InputInfoPtr pInfo,
 
 SynapticsResetTouchHwState(hw, FALSE);
 
-/* Reset cumulative values if buttons were not previously pressed */
-if (!hw-left  !hw-right  !hw-middle) {
+/* Reset cumulative values if buttons were not previously pressed,
+ * or no finger was previously present. */
+if ((!hw-left  !hw-right  !hw-middle) || hw-z  para-finger_low) {
 hw-cumulative_dx = hw-x;
 hw-cumulative_dy = hw-y;
 sync_cumulative = TRUE;
diff --git a/src/synaptics.c b/src/synaptics.c
index bd14100..59fcf48 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -2810,6 +2810,12 @@ update_hw_button_state(const InputInfoPtr pInfo, struct 
SynapticsHwState *hw,
 if (para-clickpad) {
 /* hw-left is down, but no other buttons were already down */
 if (!(priv-lastButtons  7)  hw-left  !hw-right  !hw-middle) 
{
+/* If the finger down event is delayed, the x and y
+ * coordinates are stale so we delay processing the click */
+if (hw-z  para-finger_low) {
+hw-left = 0;
+goto out;
+}
 if (is_inside_rightbutton_area(para, hw-x, hw-y)) {
 hw-left = 0;
 hw-right = 1;
@@ -2841,6 +2847,7 @@ update_hw_button_state(const InputInfoPtr pInfo, struct 
SynapticsHwState *hw,
 if (hw-left  !(priv-lastButtons  7)  hw-numFingers = 1)
 handle_clickfinger(priv, hw);
 
+out:
 /* Two finger emulation */
 if (hw-numFingers == 1  hw-z = para-emulate_twofinger_z 
 hw-fingerWidth = para-emulate_twofinger_w) {
-- 
1.9.0

___
xorg-devel@lists.x.org: X.Org development
Archives: