touchpad: don't init edge palm detection on touchpads less than 8cm across
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 15 Jul 2014 04:01:00 +0000 (14:01 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Sun, 20 Jul 2014 22:56:12 +0000 (08:56 +1000)
On small touchpads, a touch that intends to go across the width of the
touchpad is likely to start in the edge zone. Likewise, on those touchpads the
chances of a palm event happening on the edge is small.

A minimum width of 8cm determined by an elaborate process of completely
unscientific guesswork: the x220 is roughly 7.5cm across and doesn't suffer
much from edge events, the T440s is 10cm across and definitely suffers from
it. So the trigger width likely somewhere in between which makes 8cm about as
valid as any other guess.

Note that this disables palm detection for resolution-less touchpads too - if
we don't know how big the touchpad is we can't know if palm detection on the
edges is necessary.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev-mt-touchpad.c
test/touchpad.c

index 2cf8b567eccc8d4092a6dc6b723123407e30d8e6..1636e7a2615857d0a7374d8dc9f02a8c6f5d83ac 100644 (file)
@@ -25,6 +25,7 @@
 #include <assert.h>
 #include <math.h>
 #include <stdbool.h>
+#include <limits.h>
 
 #include "evdev-mt-touchpad.h"
 
@@ -753,9 +754,21 @@ tp_init_palmdetect(struct tp_dispatch *tp,
 {
        int width;
 
+       /* We don't know how big the touchpad is */
+       if (device->abs.absinfo_x->resolution == 1)
+               return 0;
+
        width = abs(device->abs.absinfo_x->maximum -
                    device->abs.absinfo_x->minimum);
 
+       /* Enable palm detection on touchpads >= 80 mm. Anything smaller
+          probably won't need it, until we find out it does */
+       if (width/device->abs.absinfo_x->resolution < 80) {
+               tp->palm.right_edge = INT_MAX;
+               tp->palm.left_edge = INT_MIN;
+               return 0;
+       }
+
        /* palm edges are 5% of the width on each side */
        tp->palm.right_edge = device->abs.absinfo_x->maximum - width * 0.05;
        tp->palm.left_edge = device->abs.absinfo_x->minimum + width * 0.05;
index 1d95399c6c7f8412672d0786b0519d5a14f2aa0e..c1bdbd533cde89a82da1eb7f7e9219630dec451b 100644 (file)
@@ -1241,11 +1241,24 @@ START_TEST(touchpad_tap_default)
 }
 END_TEST
 
+static int
+touchpad_has_palm_detect_size(struct litest_device *dev)
+{
+       double width, height;
+
+       libinput_device_get_size(dev->libinput_device, &width, &height);
+
+       return width >= 80;
+}
+
 START_TEST(touchpad_palm_detect_at_edge)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        litest_drain_events(li);
 
        litest_touch_down(dev, 0, 99, 50);
@@ -1265,6 +1278,9 @@ START_TEST(touchpad_palm_detect_at_bottom_corners)
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        /* Run for non-clickpads only: make sure the bottom corners trigger
           palm detection too */
        litest_drain_events(li);
@@ -1286,6 +1302,9 @@ START_TEST(touchpad_palm_detect_at_top_corners)
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        /* Run for non-clickpads only: make sure the bottom corners trigger
           palm detection too */
        litest_drain_events(li);
@@ -1307,6 +1326,9 @@ START_TEST(touchpad_palm_detect_palm_stays_palm)
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        litest_drain_events(li);
 
        litest_touch_down(dev, 0, 99, 20);
@@ -1323,6 +1345,9 @@ START_TEST(touchpad_palm_detect_palm_becomes_pointer)
        struct libinput_event *ev;
        enum libinput_event_type type;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        litest_drain_events(li);
 
        litest_touch_down(dev, 0, 99, 50);
@@ -1352,6 +1377,9 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges)
        struct libinput_event *ev;
        enum libinput_event_type type;
 
+       if (!touchpad_has_palm_detect_size(dev))
+               return;
+
        /* moving non-palm into the edge does not label it as palm */
        litest_drain_events(li);