[PATCH xf86-input-synaptics 1/8] Add another third state to TouchpadOff for disabling all but button clicks

Hans de Goede hdegoede at redhat.com
Fri Feb 21 01:31:37 PST 2014


From: Peter Hutterer <peter.hutterer at who-t.net>

On a new set of laptops like the Lenovo T440 the trackstick does not have
physical buttons. Instead, the touchpad's top edge is supposed to acts
software button area. To avoid spurious cursor jumps when the trackstick is in
use and the finger is resting on the touchpad, add another mode that disables
motion events.

Enabled by syndaemon with -t click-only, the default stays unchanged. No
specific integration with the traditional disable-while-typing is needed. On
such touchpads, disabling motion events is sufficient to avoid spurious
events and we don't want to stop HW buttons to send events.

Note that this only adds the new state to the driver and to syndaemon, there
is nothing hooked up otherwise to actually monitor the trackstick.

Special note for syndaemon: optional arguments are a GNU extension, so work
around it by messing with an optstring starting with ":" which allows us to
manually parse the options.

Original version of this patch by John Pham <jhnphm at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Reviewed-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 man/synaptics.man  |  1 +
 man/syndaemon.man  |  8 +++++---
 src/properties.c   |  2 +-
 src/synaptics.c    | 13 ++++++++++---
 src/synapticsstr.h |  2 ++
 tools/synclient.c  |  2 +-
 tools/syndaemon.c  | 33 ++++++++++++++++++++++++++-------
 7 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/man/synaptics.man b/man/synaptics.man
index a7889c7..8e7d27e 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -263,6 +263,7 @@ l l.
 0	Touchpad is enabled
 1	Touchpad is switched off
 2	Only tapping and scrolling is switched off
+3	Only cursor movement is switched off
 .TE
 Property: "Synaptics Off"
 .TP
diff --git a/man/syndaemon.man b/man/syndaemon.man
index 87691d8..30ea20b 100644
--- a/man/syndaemon.man
+++ b/man/syndaemon.man
@@ -45,9 +45,11 @@ A pid file will only be created if the program is started in daemon
 mode.
 .LP
 .TP
-\fB\-t\fP
-Only disable tapping and scrolling, not mouse movements, in response
-to keyboard activity.
+\fB\-t\fP [off|tapping|click-only]
+ Disable state. "off" for disabling the touchpad entirely, "tapping" for
+ disabling tapping and scrolling only, "click-only" for disabling
+ everything but physical clicks. The default if this option is missing is
+ "off". If this option is given without a mode it defaults to "tapping".
 .LP
 .TP
 \fB\-k\fP
diff --git a/src/properties.c b/src/properties.c
index 886d8c2..d4fd3cb 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -585,7 +585,7 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
 
         off = *(CARD8 *) prop->data;
 
-        if (off > 2)
+        if (off > 3)
             return BadValue;
 
         para->touchpad_off = off;
diff --git a/src/synaptics.c b/src/synaptics.c
index 075e1ca..34de488 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -1752,7 +1752,8 @@ SelectTapButton(SynapticsPrivate * priv, enum EdgeType edge)
 {
     enum TapEvent tap;
 
-    if (priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF) {
+    if (priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF ||
+        priv->synpara.touchpad_off == TOUCHPAD_CLICK_ONLY) {
         priv->tap_button = 0;
         return;
     }
@@ -2291,7 +2292,9 @@ HandleScrolling(SynapticsPrivate * priv, struct SynapticsHwState *hw,
     SynapticsParameters *para = &priv->synpara;
     int delay = 1000000000;
 
-    if ((priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF) || (priv->finger_state == FS_BLOCKED)) {
+    if ((priv->synpara.touchpad_off == TOUCHPAD_TAP_OFF) ||
+        (priv->synpara.touchpad_off == TOUCHPAD_CLICK_ONLY) ||
+        (priv->finger_state == FS_BLOCKED)) {
         stop_coasting(priv);
         priv->circ_scroll_on = FALSE;
         priv->vert_scroll_edge_on = FALSE;
@@ -2890,6 +2893,9 @@ HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw)
     Bool restart_touches = FALSE;
     int i;
 
+    if (para->touchpad_off == TOUCHPAD_CLICK_ONLY)
+        goto out;
+
     if (para->click_action[F3_CLICK1] || para->tap_action[F3_TAP])
         min_touches = 4;
     else if (para->click_action[F2_CLICK1] || para->tap_action[F2_TAP] ||
@@ -3111,7 +3117,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
     }
 
     /* Post events */
-    if (finger >= FS_TOUCHED && (dx || dy))
+    if (finger >= FS_TOUCHED && (dx || dy) &&
+        (para->touchpad_off != TOUCHPAD_CLICK_ONLY))
         xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
 
     if (priv->mid_emu_state == MBE_LEFT_CLICK) {
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 54bc154..8e1efc5 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -63,6 +63,7 @@ enum OffState {
     TOUCHPAD_ON = 0,
     TOUCHPAD_OFF = 1,
     TOUCHPAD_TAP_OFF = 2,
+    TOUCHPAD_CLICK_ONLY = 3
 };
 
 enum TapEvent {
@@ -182,6 +183,7 @@ typedef struct _SynapticsParameters {
                                  * 0 : Not off
                                  * 1 : Off
                                  * 2 : Only tapping and scrolling off
+                                 * 3 : All but physical clicks off
                                  */
     Bool locked_drags;          /* Enable locked drags */
     int locked_drag_time;       /* timeout for locked drags */
diff --git a/tools/synclient.c b/tools/synclient.c
index ac31a66..98285ac 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -105,7 +105,7 @@ static struct Parameter params[] = {
     {"UpDownScrollRepeat",    PT_BOOL,   0, 1,     SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT,   8,	0},
     {"LeftRightScrollRepeat", PT_BOOL,   0, 1,     SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT,   8,	1},
     {"ScrollButtonRepeat",    PT_INT,    SBR_MIN , SBR_MAX, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32,	0},
-    {"TouchpadOff",           PT_INT,    0, 2,     SYNAPTICS_PROP_OFF,		8,	0},
+    {"TouchpadOff",           PT_INT,    0, 3,     SYNAPTICS_PROP_OFF,		8,	0},
     {"LockedDrags",           PT_BOOL,   0, 1,     SYNAPTICS_PROP_LOCKED_DRAGS,	8,	0},
     {"LockedDragTimeout",     PT_INT,    0, 30000, SYNAPTICS_PROP_LOCKED_DRAGS_TIMEOUT,	32,	0},
     {"RTCornerButton",        PT_INT,    0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION,	8,	0},
diff --git a/tools/syndaemon.c b/tools/syndaemon.c
index 29e75f5..b181d16 100644
--- a/tools/syndaemon.c
+++ b/tools/syndaemon.c
@@ -50,7 +50,8 @@
 enum TouchpadState {
     TouchpadOn = 0,
     TouchpadOff = 1,
-    TappingOff = 2
+    TappingOff = 2,
+    ClickOnly = 3
 };
 
 static Bool pad_disabled
@@ -73,7 +74,7 @@ static void
 usage(void)
 {
     fprintf(stderr,
-            "Usage: syndaemon [-i idle-time] [-m poll-delay] [-d] [-t] [-k]\n");
+            "Usage: syndaemon [-i idle-time] [-m poll-delay] [-d] [-t [off|tapping|click-only]] [-k]\n");
     fprintf(stderr,
             "  -i How many seconds to wait after the last key press before\n");
     fprintf(stderr, "     enabling the touchpad. (default is 2.0s)\n");
@@ -82,7 +83,10 @@ usage(void)
     fprintf(stderr, "  -d Start as a daemon, i.e. in the background.\n");
     fprintf(stderr, "  -p Create a pid file with the specified name.\n");
     fprintf(stderr,
-            "  -t Only disable tapping and scrolling, not mouse movements.\n");
+            "  -t Disable state.\n"
+            "     'off' for disabling the touchpad entirely, \n"
+            "     'tapping' for disabling tapping and scrolling only,\n"
+            "     'click-only' for disabling everything but physical clicks.\n");
     fprintf(stderr,
             "  -k Ignore modifier keys when monitoring keyboard activity.\n");
     fprintf(stderr, "  -K Like -k but also ignore Modifier+Key combos.\n");
@@ -547,7 +551,7 @@ main(int argc, char *argv[])
     int use_xrecord = 0;
 
     /* Parse command line parameters */
-    while ((c = getopt(argc, argv, "i:m:dtp:kKR?v")) != EOF) {
+    while ((c = getopt(argc, argv, ":i:m:dp:kKR?v")) != EOF) {
         switch (c) {
         case 'i':
             idle_time = atof(optarg);
@@ -558,9 +562,6 @@ main(int argc, char *argv[])
         case 'd':
             background = 1;
             break;
-        case 't':
-            disable_state = TappingOff;
-            break;
         case 'p':
             pid_file = optarg;
             break;
@@ -578,6 +579,24 @@ main(int argc, char *argv[])
             verbose = 1;
             break;
         case '?':
+            if (optopt != 't')
+                usage();
+            else {
+                if (optind < argc) {
+                    if (argv[optind][0] == '-')
+                        disable_state = TappingOff;
+                    else if (strcmp(argv[optind], "off") == 0)
+                        disable_state = TouchpadOff;
+                    else if (strcmp(argv[optind], "tapping") == 0)
+                        disable_state = TappingOff;
+                    else if (strcmp(argv[optind], "click-only") == 0)
+                        disable_state = ClickOnly;
+                    else
+                        usage();
+                } else
+                    disable_state = TappingOff;
+            }
+            break;
         default:
             usage();
             break;
-- 
1.9.0



More information about the xorg-devel mailing list