From bc33dd0d1ef2bf9607f29b3d9aad3bf9792b584c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 29 Dec 2013 11:05:06 -0500 Subject: [PATCH synaptics] Add another third state to TouchpadOff for disabling motion events 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 motion, 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 Signed-off-by: Peter Hutterer --- man/synaptics.man | 1 + man/syndaemon.man | 8 +++++--- src/properties.c | 2 +- src/synaptics.c | 2 +- src/synapticsstr.h | 2 ++ tools/syndaemon.c | 33 ++++++++++++++++++++++++++------- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/man/synaptics.man b/man/synaptics.man index 079a5f8..d9423be 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -228,6 +228,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..1b18af8 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|motion] + Disable state. "off" for disabling the touchpad entirely, "tapping" for + disabling tapping and scrolling only, "motion" for disabling + motion only. 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 797f1da..4623f42 100644 --- a/src/properties.c +++ b/src/properties.c @@ -526,7 +526,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 5b95d9d..7115de5 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -2920,7 +2920,7 @@ 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_MOTION_OFF)) 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 3d6f756..7082990 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -59,6 +59,7 @@ enum OffState { TOUCHPAD_ON = 0, TOUCHPAD_OFF = 1, TOUCHPAD_TAP_OFF = 2, + TOUCHPAD_MOTION_OFF = 3 }; enum TapEvent { @@ -172,6 +173,7 @@ typedef struct _SynapticsParameters { * 0 : Not off * 1 : Off * 2 : Only tapping and scrolling off + * 3 : Only motion off */ Bool locked_drags; /* Enable locked drags */ int locked_drag_time; /* timeout for locked drags */ diff --git a/tools/syndaemon.c b/tools/syndaemon.c index 29e75f5..f152b95 100644 --- a/tools/syndaemon.c +++ b/tools/syndaemon.c @@ -50,7 +50,8 @@ enum TouchpadState { TouchpadOn = 0, TouchpadOff = 1, - TappingOff = 2 + TappingOff = 2, + MotionOff = 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|motion]] [-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" + " 'motion' for disabling motion only.\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], "motion") == 0) + disable_state = MotionOff; + else + usage(); + } else + disable_state = TappingOff; + } + break; default: usage(); break; -- 1.8.4.2