diff --git a/quirks/50-system-apple.quirks b/quirks/50-system-apple.quirks index fbbb1be0..f643ccc6 100644 --- a/quirks/50-system-apple.quirks +++ b/quirks/50-system-apple.quirks @@ -34,6 +34,7 @@ MatchProduct=0x030E AttrSizeHint=130x110 AttrTouchSizeRange=20:10 AttrPalmSizeThreshold=900 +AttrThumbSizeThreshold=800 [Apple Touchpad OneButton] MatchUdevType=touchpad diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index f939971f..64041752 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1135,6 +1135,10 @@ tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) if (tp->thumb.use_pressure && t->pressure > tp->thumb.pressure_threshold) t->thumb.state = THUMB_STATE_YES; + else if (tp->thumb.use_size && + (t->major > tp->thumb.size_threshold || + t->minor > tp->thumb.size_threshold)) + t->thumb.state = THUMB_STATE_YES; else if (t->point.y > tp->thumb.lower_thumb_line && tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE && t->thumb.first_touch_time + THUMB_MOVE_TIMEOUT < time) @@ -3126,11 +3130,21 @@ tp_init_thumb(struct tp_dispatch *tp) } } + if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_TOUCH_MAJOR)) { + if (quirks_get_uint32(q, + QUIRK_ATTR_THUMB_SIZE_THRESHOLD, + &threshold)) { + tp->thumb.use_size = true; + tp->thumb.size_threshold = threshold; + } + } + quirks_unref(q); evdev_log_debug(device, - "thumb: enabled thumb detection%s\n", - tp->thumb.use_pressure ? " (+pressure)" : ""); + "thumb: enabled thumb detection%s%s\n", + tp->thumb.use_pressure ? " (+pressure)" : "", + tp->thumb.use_size ? " (+size)" : ""); } static bool diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index f0f6145a..c155029b 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -446,6 +446,9 @@ struct tp_dispatch { bool use_pressure; int pressure_threshold; + + bool use_size; + int size_threshold; } thumb; struct { diff --git a/src/quirks.c b/src/quirks.c index 54b207d1..7ac5b34b 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -268,6 +268,7 @@ quirk_get_name(enum quirk q) case QUIRK_ATTR_TRACKPOINT_MULTIPLIER: return "AttrTrackpointMultiplier"; case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: return "AttrThumbPressureThreshold"; case QUIRK_ATTR_USE_VELOCITY_AVERAGING: return "AttrUseVelocityAveraging"; + case QUIRK_ATTR_THUMB_SIZE_THRESHOLD: return "AttrThumbSizeThreshold"; default: abort(); } @@ -736,6 +737,13 @@ parse_attr(struct quirks_context *ctx, p->type = PT_UINT; p->value.u = v; rc = true; + } else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_SIZE_THRESHOLD))) { + p->id = QUIRK_ATTR_THUMB_SIZE_THRESHOLD; + if (!safe_atou(value, &v)) + goto out; + p->type = PT_UINT; + p->value.u = v; + rc = true; } else { qlog_error(ctx, "Unknown key %s in %s\n", key, s->name); } diff --git a/src/quirks.h b/src/quirks.h index 051ce7b6..51bdc40a 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -96,6 +96,7 @@ enum quirk { QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, QUIRK_ATTR_USE_VELOCITY_AVERAGING, + QUIRK_ATTR_THUMB_SIZE_THRESHOLD, }; /** diff --git a/tools/libinput-measure-touch-size.py b/tools/libinput-measure-touch-size.py index 2bf900b7..3997c038 100755 --- a/tools/libinput-measure-touch-size.py +++ b/tools/libinput-measure-touch-size.py @@ -108,6 +108,8 @@ class TouchSequence(object): self.was_down = False self.is_palm = False self.was_palm = False + self.is_thumb = False + self.was_thumb = False self.major_range = Range() self.minor_range = Range() @@ -130,6 +132,10 @@ class TouchSequence(object): if self.is_palm: self.was_palm = True + self.is_thumb = self.device.thumb != 0 and touch.major > self.device.thumb + if self.is_thumb: + self.was_thumb = True + def finalize(self): """Mark the TouchSequence as complete (finger is up)""" self.is_active = False @@ -152,15 +158,18 @@ class TouchSequence(object): s += " down" if self.was_palm: s += " palm" + if self.was_thumb: + s += " thumb" return s def _str_state(self): touch = self.points[-1] - s = "{}, tags: {} {}".format( + s = "{}, tags: {} {} {}".format( touch, "down" if self.is_down else " ", - "palm" if self.is_palm else " " + "palm" if self.is_palm else " ", + "thumb" if self.is_thumb else " " ) return s @@ -199,6 +208,7 @@ class Device(object): self.up = 0 self.down = 0 self.palm = 0 + self.thumb = 0 self._init_thresholds_from_quirks() self.sequences = [] @@ -235,6 +245,8 @@ class Device(object): self.palm = int(q[1]) elif q[0] == 'AttrTouchSizeRange': self.down, self.up = colon_tuple(q[1]) + elif q[0] == 'AttrThumbSizeThreshold': + self.thumb = int(q[1]) def start_new_sequence(self, tracking_id): self.sequences.append(TouchSequence(self, tracking_id)) @@ -286,6 +298,7 @@ class Device(object): print("Ready for recording data.") print("Touch sizes used: {}:{}".format(self.down, self.up)) print("Palm size used: {}".format(self.palm)) + print("Thumb size used: {}".format(self.thumb)) print("Place a single finger on the device to measure touch size.\n" "Ctrl+C to exit\n") diff --git a/tools/shared.c b/tools/shared.c index 7b3b8de2..c9ca9809 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -640,6 +640,7 @@ tools_list_device_quirks(struct quirks_context *ctx, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, QUIRK_ATTR_USE_VELOCITY_AVERAGING, + QUIRK_ATTR_THUMB_SIZE_THRESHOLD, }; enum quirk *q; @@ -707,6 +708,7 @@ tools_list_device_quirks(struct quirks_context *ctx, case QUIRK_ATTR_PALM_SIZE_THRESHOLD: case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: + case QUIRK_ATTR_THUMB_SIZE_THRESHOLD: quirks_get_uint32(quirks, *q, &v); snprintf(buf, sizeof(buf), "%s=%u", name, v); callback(userdata, buf);