Commit eea73358 authored by Peter Hutterer's avatar Peter Hutterer

Add another third state to TouchpadOff for disabling all but button clicks

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@gmail.com>
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent ac78616d
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -1763,7 +1763,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;
}
......@@ -2302,7 +2303,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;
......@@ -2909,6 +2912,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] ||
......@@ -3130,7 +3136,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) {
......
......@@ -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 */
......
......@@ -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},
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment