summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-04-14 15:21:50 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-04-18 08:40:42 +1000
commitfcc9a2bf187ee0e7aacf6f2f2d691337f4d471a6 (patch)
tree78aadfa87028fd44cd0759eef535ee3ac06f459d /src
parentb31618b25b03dd609f6104ca5159343f446033d5 (diff)
evdev: always defuzz absolute touchscreens
If a touchscreen has a fuzz value use it for motion hysteresis similar to how we do it for a touchpad. This stops pointer wobbles as seen in https://bugs.freedesktop.org/show_bug.cgi?id=94918 It's up to the system to override or set the kernel's fuzz value correctly, i.e. a udev hwdb entry is required where the kernel driver does not set it. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/evdev.c34
-rw-r--r--src/evdev.h3
2 files changed, 37 insertions, 0 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 4f69cb1e..bfa61806 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -342,6 +342,30 @@ evdev_post_trackpoint_scroll(struct evdev_device *device,
return true;
}
+static inline bool
+evdev_filter_defuzz_touch(struct evdev_device *device, struct mt_slot *slot)
+{
+ struct device_coords point;
+
+ if (!device->mt.want_hysteresis)
+ return false;
+
+ point.x = evdev_hysteresis(slot->point.x,
+ slot->hysteresis_center.x,
+ device->mt.hysteresis_margin.x);
+ point.y = evdev_hysteresis(slot->point.y,
+ slot->hysteresis_center.y,
+ device->mt.hysteresis_margin.y);
+
+ slot->hysteresis_center = slot->point;
+ if (point.x == slot->point.x && point.y == slot->point.y)
+ return true;
+
+ slot->point = point;
+
+ return false;
+}
+
static void
evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
{
@@ -414,6 +438,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
seat->slot_map |= 1 << seat_slot;
point = slot->point;
+ slot->hysteresis_center = point;
evdev_transform_absolute(device, &point);
touch_notify_touch_down(base, time, slot_idx, seat_slot,
@@ -429,6 +454,9 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
if (seat_slot == -1)
break;
+ if (evdev_filter_defuzz_touch(device, slot))
+ break;
+
evdev_transform_absolute(device, &point);
touch_notify_touch_motion(base, time, slot_idx, seat_slot,
&point);
@@ -2015,6 +2043,12 @@ evdev_configure_mt_device(struct evdev_device *device)
device->mt.slots_len = num_slots;
device->mt.slot = active_slot;
+ if (device->abs.absinfo_x->fuzz || device->abs.absinfo_y->fuzz) {
+ device->mt.want_hysteresis = true;
+ device->mt.hysteresis_margin.x = device->abs.absinfo_x->fuzz/2;
+ device->mt.hysteresis_margin.y = device->abs.absinfo_y->fuzz/2;
+ }
+
return 0;
}
diff --git a/src/evdev.h b/src/evdev.h
index 4171c8a4..1e38b5e6 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -120,6 +120,7 @@ enum evdev_device_model {
struct mt_slot {
int32_t seat_slot;
struct device_coords point;
+ struct device_coords hysteresis_center;
};
struct evdev_device {
@@ -153,6 +154,8 @@ struct evdev_device {
int slot;
struct mt_slot *slots;
size_t slots_len;
+ bool want_hysteresis;
+ struct device_coords hysteresis_margin;
} mt;
struct mtdev *mtdev;