tp_keyboard_timeout, tp);
}
+static int
+tp_read_thumb_pressure_prop(struct tp_dispatch *tp,
+ const struct evdev_device *device)
+{
+ struct udev_device *udev_device = device->udev_device;
+ const char *prop;
+ int threshold;
+ const int default_thumb_threshold = 0;
+
+ prop = udev_device_get_property_value(udev_device,
+ "LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD");
+ if (!prop)
+ return default_thumb_threshold;
+
+ threshold = parse_thumb_pressure_property(prop);
+
+ return threshold > 0 ? threshold : default_thumb_threshold;
+}
+
static void
tp_init_thumb(struct tp_dispatch *tp)
{
double w = 0.0, h = 0.0;
struct device_coords edges;
struct phys_coords mm = { 0.0, 0.0 };
- int xres, yres;
- double threshold;
+ int threshold;
if (!tp->buttons.is_clickpad)
return;
if (!abs)
goto out;
- if (abs->maximum - abs->minimum < 255)
+ threshold = tp_read_thumb_pressure_prop(tp, device);
+ if (threshold == 0)
goto out;
- /* Our reference touchpad is the T440s with 42x42 resolution.
- * Higher-res touchpads exhibit higher pressure for the same
- * interaction. On the T440s, the threshold value is 100, you don't
- * reach that with a normal finger interaction.
- * Note: "thumb" means massive touch that should not interact, not
- * "using the tip of my thumb for a pinch gestures".
- */
- xres = tp->device->abs.absinfo_x->resolution;
- yres = tp->device->abs.absinfo_y->resolution;
- threshold = 100.0 * hypot(xres, yres)/hypot(42, 42);
- tp->thumb.threshold = max(100, threshold);
+ tp->thumb.threshold = threshold;
out:
evdev_log_debug(device,
return thr;
}
+/**
+ * Helper function to parse the LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD
+ * property from udev. Property is of the form:
+ * LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD=<integer>
+ * Where the number indicates the minimum threshold to consider a touch to
+ * be a thumb.
+ *
+ * @param prop The value of the udev property (without the
+ * LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD=)
+ * @return The pressure threshold or 0 on error
+ */
+int
+parse_thumb_pressure_property(const char *prop)
+{
+ int threshold = 0;
+
+ if (!prop)
+ return 0;
+
+ if (!safe_atoi(prop, &threshold) || threshold < 0)
+ return 0;
+
+ return threshold;
+}
+
/**
* Return the next word in a string pointed to by state before the first
* separator character. Call repeatedly to tokenize a whole string.
bool parse_range_property(const char *prop, int *hi, int *lo);
int parse_palm_pressure_property(const char *prop);
int parse_palm_size_property(const char *prop);
+int parse_thumb_pressure_property(const char *prop);
enum tpkbcombo_layout {
TPKBCOMBO_LAYOUT_UNKNOWN,
LIBINPUT_MODEL_LENOVO_T450_TOUCHPAD=1
LIBINPUT_ATTR_PALM_PRESSURE_THRESHOLD=150
+# Lenovo ThinkPad series
+libinput:name:*Synaptics*:dmi:*svnLENOVO:*:pvrThinkPad*:*
+ LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD=100
+
# Lenovo ThinkPad Compact USB Keyboard with TrackPoint
libinput:keyboard:input:b0003v17EFp6047*
LIBINPUT_ATTR_KEYBOARD_INTEGRATION=external
Or(('reliable', 'write_open'))),
('LIBINPUT_ATTR_KEYBOARD_INTEGRATION', Or(('internal', 'external'))),
('LIBINPUT_ATTR_TRACKPOINT_RANGE', INTEGER('Y')),
+ ('LIBINPUT_ATTR_THUMB_PRESSURE_THRESHOLD', INTEGER('Y')),
)
value_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') for
name, val in vprops]