[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#437254: xserver-xorg-input-synaptics: found the bugs, better patch.



Package: xserver-xorg-input-synaptics
Version: 0.14.7~git20070517-2
Followup-For: Bug #437254



Hello again.

I had time so i spend some time on it and found some details about the bugs.

Anyway these bugs appear because the driver is confused by readings that
should normally be ignored, but are not.

Starting with my problems : The patch i have done ends two finger
scrolling when finger pressure drops below FingerLow. The previous
behaviour trusted numFinger too much. I could scroll only by hovering my
finger over the touchpad, because numFinger would still be == 2.

Twofinger scrolling is much more precise now.


I can't fully reproduce the tap bug (i'm not fast enought !), but for me this
patch helps.
This patch change the behaviour of a ambigious state machine.

(seeing xfree86-driver-synaptics-0.14.7~git20070517/docs/tapndrag.dia
helps here)

When on state 1, the diagrams tells that it can go into tap state if
release is true, or into move mode if tap_timeout or move is true.

These conditions are ambigious. if we do a release and a move,
then the two conditions are true.

The code check the condition with if/else if, so it induce priority. the
conditions are checked in this order :

- if move then move state
- if timeout then move state
- if release then tap state

So if we do a release and a move at the same time, the machines goes into
move state. the code is made so it immediatly return to start state
because release is true.

I think that when we could have a release and a move event when the
reading that tell that the finger is released have that (1,5855)
position. In that case the drivers would ignore these taps.
Lots of taps records in the log on launchpad fall into these cases.

In that case the drivers would ignore this tap, because the machine as a move but will
not move the pointer to the bottom left because it won't stay into move
state.

My patch change the priority, so it becomes :

- if timeout then move state
- if release then tap state
- if move then move state

So if we do a timeout and a release, the timeout is still taken into
account. And if we do a release and a move, a tap will be registered.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.22.2batchyx1.23 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to fr_FR.UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages xserver-xorg-input-synaptics depends on:
ii  libc6                  2.6.1-1+b1        GNU C Library: Shared libraries
ii  libx11-6               2:1.0.3-7         X11 client-side library
ii  libxext6               1:1.0.3-2         X11 miscellaneous extension librar
ii  libxi6                 2:1.1.2-1         X11 Input extension library
ii  xserver-xorg-core      2:1.3.0.0.dfsg-12 X.Org X server -- core server

xserver-xorg-input-synaptics recommends no packages.

-- no debconf information
--- xfree86-driver-synaptics-0.14.7~git20070517/synaptics.c	2007-05-19 17:56:20.000000000 +0200
+++ xfree86-driver-synaptics-patched/synaptics.c	2007-09-08 14:59:00.000000000 +0200
@@ -1158,11 +1158,7 @@
 	    SetTapState(priv, TS_1, hw->millis);
 	break;
     case TS_1:
-	if (move) {
-	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
-	    SetTapState(priv, TS_MOVE, hw->millis);
-	    goto restart;
-	} else if (is_timeout) {
+	if (is_timeout) {
 	    if (finger == FS_TOUCHED) {
 		SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
 	    } else if (finger == FS_PRESSED) {
@@ -1173,6 +1169,10 @@
 	} else if (release) {
 	    SelectTapButton(priv, edge);
 	    SetTapState(priv, TS_2A, hw->millis);
+	} else if (move) {
+	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, hw->millis);
+	    SetTapState(priv, TS_MOVE, hw->millis);
+	    goto restart;
 	}
 	break;
     case TS_MOVE:
@@ -1552,7 +1552,7 @@
 	    priv->circ_scroll_on = FALSE;
 	}
 
-	if (hw->numFingers < 2) {
+	if (hw->numFingers < 2 || !finger) {
 	    if (priv->vert_scroll_twofinger_on) {
 		DBG(7, ErrorF("vert two-finger scroll off\n"));
 		priv->vert_scroll_twofinger_on = FALSE;

Reply to: