Refine disable-while-typing (#1209753)

This commit is contained in:
Peter Hutterer 2015-05-27 14:32:52 +10:00
parent 3a8be7cb5d
commit 9418372b5d
11 changed files with 1086 additions and 1 deletions

View File

@ -0,0 +1,148 @@
From 09c597a3a782d1eb82f5e911f91114eb7ef44002 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 25 May 2015 10:07:51 +1000
Subject: [PATCH libinput 01/10] touchpad: move disable-while-typing into its
own struct
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 34 +++++++++++++++++-----------------
src/evdev-mt-touchpad.h | 4 +++-
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 821e645..89d24f3 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -486,7 +486,7 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
struct device_float_coords delta;
int dirs;
- if (tp->sendevents.keyboard_active &&
+ if (tp->dwt.keyboard_active &&
t->state == TOUCH_BEGIN) {
t->palm.state = PALM_TYPING;
t->palm.time = time;
@@ -682,7 +682,7 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
if (filter_motion ||
tp->sendevents.trackpoint_active ||
- tp->sendevents.keyboard_active) {
+ tp->dwt.keyboard_active) {
tp_edge_scroll_stop_events(tp, time);
tp_gesture_stop(tp, time);
return;
@@ -732,15 +732,15 @@ static void
tp_remove_sendevents(struct tp_dispatch *tp)
{
libinput_timer_cancel(&tp->sendevents.trackpoint_timer);
- libinput_timer_cancel(&tp->sendevents.keyboard_timer);
+ libinput_timer_cancel(&tp->dwt.keyboard_timer);
if (tp->buttons.trackpoint)
libinput_device_remove_event_listener(
&tp->sendevents.trackpoint_listener);
- if (tp->sendevents.keyboard)
+ if (tp->dwt.keyboard)
libinput_device_remove_event_listener(
- &tp->sendevents.keyboard_listener);
+ &tp->dwt.keyboard_listener);
}
static void
@@ -868,7 +868,7 @@ tp_keyboard_timeout(uint64_t now, void *data)
struct tp_dispatch *tp = data;
tp_tap_resume(tp, now);
- tp->sendevents.keyboard_active = false;
+ tp->dwt.keyboard_active = false;
}
static void
@@ -903,17 +903,17 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
break;
}
- if (!tp->sendevents.keyboard_active) {
+ if (!tp->dwt.keyboard_active) {
tp_edge_scroll_stop_events(tp, time);
tp_gesture_stop(tp, time);
tp_tap_suspend(tp, time);
- tp->sendevents.keyboard_active = true;
+ tp->dwt.keyboard_active = true;
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1;
} else {
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
}
- libinput_timer_set(&tp->sendevents.keyboard_timer,
+ libinput_timer_set(&tp->dwt.keyboard_timer,
time + timeout);
}
@@ -945,12 +945,12 @@ tp_device_added(struct evdev_device *device,
kbd_is_internal = bus_tp != BUS_BLUETOOTH &&
bus_kbd == bus_tp;
if (tp_is_internal && kbd_is_internal &&
- tp->sendevents.keyboard == NULL) {
+ tp->dwt.keyboard == NULL) {
libinput_device_add_event_listener(&added_device->base,
- &tp->sendevents.keyboard_listener,
+ &tp->dwt.keyboard_listener,
tp_keyboard_event, tp);
- tp->sendevents.keyboard = added_device;
- tp->sendevents.keyboard_active = false;
+ tp->dwt.keyboard = added_device;
+ tp->dwt.keyboard_active = false;
}
if (tp->sendevents.current_mode !=
@@ -979,10 +979,10 @@ tp_device_removed(struct evdev_device *device,
tp->buttons.trackpoint = NULL;
}
- if (removed_device == tp->sendevents.keyboard) {
+ if (removed_device == tp->dwt.keyboard) {
libinput_device_remove_event_listener(
- &tp->sendevents.keyboard_listener);
- tp->sendevents.keyboard = NULL;
+ &tp->dwt.keyboard_listener);
+ tp->dwt.keyboard = NULL;
}
if (tp->sendevents.current_mode !=
@@ -1261,7 +1261,7 @@ tp_init_sendevents(struct tp_dispatch *tp,
tp->device->base.seat->libinput,
tp_trackpoint_timeout, tp);
- libinput_timer_init(&tp->sendevents.keyboard_timer,
+ libinput_timer_init(&tp->dwt.keyboard_timer,
tp->device->base.seat->libinput,
tp_keyboard_timeout, tp);
return 0;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 1413945..70b35f4 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -279,12 +279,14 @@ struct tp_dispatch {
bool trackpoint_active;
struct libinput_event_listener trackpoint_listener;
struct libinput_timer trackpoint_timer;
+ } sendevents;
+ struct {
bool keyboard_active;
struct libinput_event_listener keyboard_listener;
struct libinput_timer keyboard_timer;
struct evdev_device *keyboard;
- } sendevents;
+ } dwt;
};
#define tp_for_each_touch(_tp, _t) \
--
2.4.1

View File

@ -0,0 +1,84 @@
From 640c17cb8102a1833e0366eaf3f7bd5325147741 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 25 May 2015 08:48:25 +1000
Subject: [PATCH libinput 02/10] touchpad: extend the key blacklist for
disable-while-typing
Alt-tab should not trigger the disable-while-typing timeout, likewise with the
F-keys, multimedia keys, the windows and menu key, etc.
https://bugs.freedesktop.org/show_bug.cgi?id=90613
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 45 +++++++++++++++++++++++++++++++++------------
1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 89d24f3..26edcb4 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -871,6 +871,37 @@ tp_keyboard_timeout(uint64_t now, void *data)
tp->dwt.keyboard_active = false;
}
+static inline bool
+tp_key_ignore_for_dwt(unsigned int keycode)
+{
+ switch (keycode) {
+ /* Ignore modifiers to be responsive to ctrl-click, alt-tab, etc. */
+ case KEY_LEFTCTRL:
+ case KEY_RIGHTCTRL:
+ case KEY_LEFTALT:
+ case KEY_RIGHTALT:
+ case KEY_LEFTSHIFT:
+ case KEY_RIGHTSHIFT:
+ case KEY_FN:
+ case KEY_CAPSLOCK:
+ case KEY_TAB:
+ case KEY_COMPOSE:
+ case KEY_RIGHTMETA:
+ case KEY_LEFTMETA:
+ return true;
+ default:
+ break;
+ }
+
+ /* Ignore keys not part of the "typewriter set", i.e. F-keys,
+ * multimedia keys, numpad, etc.
+ */
+ if (keycode >= KEY_F1)
+ return true;
+
+ return false;
+}
+
static void
tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
{
@@ -890,18 +921,8 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
/* modifier keys don't trigger disable-while-typing so things like
* ctrl+zoom or ctrl+click are possible */
- switch (libinput_event_keyboard_get_key(kbdev)) {
- case KEY_LEFTCTRL:
- case KEY_RIGHTCTRL:
- case KEY_LEFTALT:
- case KEY_RIGHTALT:
- case KEY_LEFTSHIFT:
- case KEY_RIGHTSHIFT:
- case KEY_FN:
- return;
- default:
- break;
- }
+ if (tp_key_ignore_for_dwt(libinput_event_keyboard_get_key(kbdev)))
+ return;
if (!tp->dwt.keyboard_active) {
tp_edge_scroll_stop_events(tp, time);
--
2.4.1

View File

@ -0,0 +1,220 @@
From c007b9aa435bb04066874fada4e5ef35147a3f4d Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 22 May 2015 15:16:31 +1000
Subject: [PATCH libinput 03/10] touchpad: add helper function to get from tp
to the libinput context
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad-buttons.c | 8 ++++----
src/evdev-mt-touchpad-edge-scroll.c | 12 ++++++------
src/evdev-mt-touchpad-tap.c | 10 +++++-----
src/evdev-mt-touchpad.c | 8 ++++----
src/evdev-mt-touchpad.h | 6 ++++++
5 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index d6acbf0..2f24ee6 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -392,7 +392,7 @@ tp_button_handle_event(struct tp_dispatch *tp,
enum button_event event,
uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
enum button_state current = t->button.state;
switch(t->button.state) {
@@ -478,7 +478,7 @@ tp_process_button(struct tp_dispatch *tp,
const struct input_event *e,
uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
uint32_t mask = 1 << (e->code - BTN_LEFT);
/* Ignore other buttons on clickpads */
@@ -680,7 +680,7 @@ int
tp_init_buttons(struct tp_dispatch *tp,
struct evdev_device *device)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
struct tp_touch *t;
int width, height;
double diagonal;
@@ -731,7 +731,7 @@ tp_init_buttons(struct tp_dispatch *tp,
tp_for_each_touch(tp, t) {
t->button.state = BUTTON_STATE_NONE;
libinput_timer_init(&t->button.timer,
- tp->device->base.seat->libinput,
+ tp_libinput_context(tp),
tp_button_handle_timeout, t);
}
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index 369fded..9bf3f0c 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -121,7 +121,7 @@ tp_edge_scroll_handle_none(struct tp_dispatch *tp,
struct tp_touch *t,
enum scroll_event event)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -149,7 +149,7 @@ tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
struct tp_touch *t,
enum scroll_event event)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -178,7 +178,7 @@ tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
struct tp_touch *t,
enum scroll_event event)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -209,7 +209,7 @@ tp_edge_scroll_handle_area(struct tp_dispatch *tp,
struct tp_touch *t,
enum scroll_event event)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -232,7 +232,7 @@ tp_edge_scroll_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum scroll_event event)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
enum tp_edge_scroll_touch_state current = t->scroll.edge_state;
switch (current) {
@@ -301,7 +301,7 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
tp_for_each_touch(tp, t) {
t->scroll.direction = -1;
libinput_timer_init(&t->scroll.timer,
- device->base.seat->libinput,
+ tp_libinput_context(tp),
tp_edge_scroll_handle_timeout, t);
}
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 61f94e5..21b2e29 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -146,7 +146,7 @@ tp_tap_idle_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case TAP_EVENT_TOUCH:
@@ -222,7 +222,7 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case TAP_EVENT_MOTION:
@@ -456,7 +456,7 @@ tp_tap_multitap_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
switch (event) {
case TAP_EVENT_RELEASE:
@@ -549,7 +549,7 @@ tp_tap_handle_event(struct tp_dispatch *tp,
enum tap_event event,
uint64_t time)
{
- struct libinput *libinput = tp->device->base.seat->libinput;
+ struct libinput *libinput = tp_libinput_context(tp);
enum tp_tap_state current;
current = tp->tap.state;
@@ -826,7 +826,7 @@ tp_init_tap(struct tp_dispatch *tp)
tp->tap.enabled = tp_tap_default(tp->device);
libinput_timer_init(&tp->tap.timer,
- tp->device->base.seat->libinput,
+ tp_libinput_context(tp),
tp_tap_handle_timeout, tp);
return 0;
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 26edcb4..6c0daf0 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -775,7 +775,7 @@ tp_release_fake_touches(struct tp_dispatch *tp)
static void
tp_clear_state(struct tp_dispatch *tp)
{
- uint64_t now = libinput_now(tp->device->base.seat->libinput);
+ uint64_t now = libinput_now(tp_libinput_context(tp));
struct tp_touch *t;
/* Unroll the touchpad state.
@@ -1178,7 +1178,7 @@ tp_scroll_config_scroll_method_set_method(struct libinput_device *device,
{
struct evdev_device *evdev = (struct evdev_device*)device;
struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
- uint64_t time = libinput_now(device->seat->libinput);
+ uint64_t time = libinput_now(tp_libinput_context(tp));
if (method == tp->scroll.method)
return LIBINPUT_CONFIG_STATUS_SUCCESS;
@@ -1279,11 +1279,11 @@ tp_init_sendevents(struct tp_dispatch *tp,
struct evdev_device *device)
{
libinput_timer_init(&tp->sendevents.trackpoint_timer,
- tp->device->base.seat->libinput,
+ tp_libinput_context(tp),
tp_trackpoint_timeout, tp);
libinput_timer_init(&tp->dwt.keyboard_timer,
- tp->device->base.seat->libinput,
+ tp_libinput_context(tp),
tp_keyboard_timeout, tp);
return 0;
}
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 70b35f4..f8c837d 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -292,6 +292,12 @@ struct tp_dispatch {
#define tp_for_each_touch(_tp, _t) \
for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)
+static inline struct libinput*
+tp_libinput_context(struct tp_dispatch *tp)
+{
+ return tp->device->base.seat->libinput;
+}
+
static inline struct normalized_coords
tp_normalize_delta(struct tp_dispatch *tp, struct device_float_coords delta)
{
--
2.4.1

View File

@ -0,0 +1,104 @@
From 5a18344bbc0a47f13752d8e39a22450f89624980 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 22 May 2015 15:51:18 +1000
Subject: [PATCH libinput 04/10] touchpad: only check keyboards for
disable-while-typing
The keyboard test is a simple one, if we have the first row of alphabetic
keys, we assume it's a full keyboard.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 22 ++++++++++++----------
src/evdev.c | 20 ++++++++++++++++++++
src/evdev.h | 1 +
3 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 6c0daf0..5a05129 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -962,16 +962,18 @@ tp_device_added(struct evdev_device *device,
tp_trackpoint_event, tp);
}
- /* FIXME: detect external keyboard better */
- kbd_is_internal = bus_tp != BUS_BLUETOOTH &&
- bus_kbd == bus_tp;
- if (tp_is_internal && kbd_is_internal &&
- tp->dwt.keyboard == NULL) {
- libinput_device_add_event_listener(&added_device->base,
- &tp->dwt.keyboard_listener,
- tp_keyboard_event, tp);
- tp->dwt.keyboard = added_device;
- tp->dwt.keyboard_active = false;
+ if (added_device->tags & EVDEV_TAG_KEYBOARD) {
+ /* FIXME: detect external keyboard better */
+ kbd_is_internal = bus_tp != BUS_BLUETOOTH &&
+ bus_kbd == bus_tp;
+ if (tp_is_internal && kbd_is_internal &&
+ tp->dwt.keyboard == NULL) {
+ libinput_device_add_event_listener(&added_device->base,
+ &tp->dwt.keyboard_listener,
+ tp_keyboard_event, tp);
+ tp->dwt.keyboard = added_device;
+ tp->dwt.keyboard_active = false;
+ }
}
if (tp->sendevents.current_mode !=
diff --git a/src/evdev.c b/src/evdev.c
index 4ce9250..a98e801 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -734,6 +734,25 @@ evdev_tag_trackpoint(struct evdev_device *device,
}
static void
+evdev_tag_keyboard(struct evdev_device *device,
+ struct udev_device *udev_device)
+{
+ int code;
+
+ if (!libevdev_has_event_type(device->evdev, EV_KEY))
+ return;
+
+ for (code = KEY_Q; code <= KEY_P; code++) {
+ if (!libevdev_has_event_code(device->evdev,
+ EV_KEY,
+ code))
+ return;
+ }
+
+ device->tags |= EVDEV_TAG_KEYBOARD;
+}
+
+static void
fallback_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct input_event *event,
@@ -772,6 +791,7 @@ fallback_tag_device(struct evdev_device *device,
{
evdev_tag_external_mouse(device, udev_device);
evdev_tag_trackpoint(device, udev_device);
+ evdev_tag_keyboard(device, udev_device);
}
static int
diff --git a/src/evdev.h b/src/evdev.h
index 20c0b55..bd398de 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -68,6 +68,7 @@ enum evdev_device_tags {
EVDEV_TAG_INTERNAL_TOUCHPAD = (1 << 1),
EVDEV_TAG_TRACKPOINT = (1 << 2),
EVDEV_TAG_TOUCHPAD_TRACKPOINT = (1 << 3),
+ EVDEV_TAG_KEYBOARD = (1 << 4),
};
enum evdev_middlebutton_state {
--
2.4.1

View File

@ -0,0 +1,154 @@
From f1a89760aa814787f0e1df43658b95bf88195592 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 22 May 2015 16:07:10 +1000
Subject: [PATCH libinput 05/10] touchpad: be finer-grained about when to pair
touchpads/keyboard for DWT
Check a couple of easy yes/no definitives that cover most Lenovo laptops,
and avoid false positives on Wacoms.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 54 +++++++++++++++++++++++++++++++++++--------------
src/evdev-mt-touchpad.h | 2 --
src/libinput-util.h | 3 +++
test/device.c | 2 +-
test/touchpad.c | 2 +-
5 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 5a05129..3a0985d 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -938,15 +938,43 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
time + timeout);
}
+static bool
+tp_want_dwt(struct evdev_device *touchpad,
+ struct evdev_device *keyboard)
+{
+ unsigned int bus_tp = libevdev_get_id_bustype(touchpad->evdev),
+ bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
+
+ if (bus_tp == BUS_BLUETOOTH || bus_kbd == BUS_BLUETOOTH)
+ return false;
+
+ /* evemu will set the right bus type */
+ if (bus_tp == BUS_VIRTUAL || bus_kbd == BUS_VIRTUAL)
+ return false;
+
+ /* If the touchpad is on serio, the keyboard is too, so ignore any
+ other devices */
+ if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
+ return false;
+
+ /* Wacom makes touchpads, but not internal ones */
+ if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_WACOM)
+ return false;
+
+ /* everything else we don't really know, so we have to assume
+ they go together */
+
+ return true;
+}
+
static void
tp_device_added(struct evdev_device *device,
struct evdev_device *added_device)
{
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
unsigned int bus_tp = libevdev_get_id_bustype(device->evdev),
- bus_trp = libevdev_get_id_bustype(added_device->evdev),
- bus_kbd = libevdev_get_id_bustype(added_device->evdev);
- bool tp_is_internal, trp_is_internal, kbd_is_internal;
+ bus_trp = libevdev_get_id_bustype(added_device->evdev);
+ bool tp_is_internal, trp_is_internal;
tp_is_internal = bus_tp != BUS_USB && bus_tp != BUS_BLUETOOTH;
trp_is_internal = bus_trp != BUS_USB && bus_trp != BUS_BLUETOOTH;
@@ -962,18 +990,14 @@ tp_device_added(struct evdev_device *device,
tp_trackpoint_event, tp);
}
- if (added_device->tags & EVDEV_TAG_KEYBOARD) {
- /* FIXME: detect external keyboard better */
- kbd_is_internal = bus_tp != BUS_BLUETOOTH &&
- bus_kbd == bus_tp;
- if (tp_is_internal && kbd_is_internal &&
- tp->dwt.keyboard == NULL) {
- libinput_device_add_event_listener(&added_device->base,
- &tp->dwt.keyboard_listener,
- tp_keyboard_event, tp);
- tp->dwt.keyboard = added_device;
- tp->dwt.keyboard_active = false;
- }
+ if (added_device->tags & EVDEV_TAG_KEYBOARD &&
+ tp->dwt.keyboard == NULL &&
+ tp_want_dwt(device, added_device)) {
+ libinput_device_add_event_listener(&added_device->base,
+ &tp->dwt.keyboard_listener,
+ tp_keyboard_event, tp);
+ tp->dwt.keyboard = added_device;
+ tp->dwt.keyboard_active = false;
}
if (tp->sendevents.current_mode !=
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index f8c837d..db877c7 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -32,8 +32,6 @@
#define TOUCHPAD_HISTORY_LENGTH 4
#define TOUCHPAD_MIN_SAMPLES 4
-#define VENDOR_ID_APPLE 0x5ac
-
/* Convert mm to a distance normalized to DEFAULT_MOUSE_DPI */
#define TP_MM_TO_DPI_NORMALIZED(mm) (DEFAULT_MOUSE_DPI/25.4 * mm)
diff --git a/src/libinput-util.h b/src/libinput-util.h
index 74226b9..89f5230 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -30,6 +30,9 @@
#include "libinput.h"
+#define VENDOR_ID_APPLE 0x5ac
+#define VENDOR_ID_WACOM 0x56a
+
void
set_logging_enabled(int enabled);
diff --git a/test/device.c b/test/device.c
index 1c277ba..0e494c4 100644
--- a/test/device.c
+++ b/test/device.c
@@ -69,7 +69,7 @@ START_TEST(device_sendevents_config_touchpad)
expected = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
/* The wacom devices in the test suite are external */
- if (libevdev_get_id_vendor(dev->evdev) != 0x56a) /* wacom */
+ if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM)
expected |=
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
diff --git a/test/touchpad.c b/test/touchpad.c
index 576b2bd..2624dda 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -2951,7 +2951,7 @@ touchpad_has_palm_detect_size(struct litest_device *dev)
double width, height;
int rc;
- if (libinput_device_get_id_vendor(dev->libinput_device) == 0x5ac) /* Apple */
+ if (libinput_device_get_id_vendor(dev->libinput_device) == ID_VENDOR_APPLE)
return 1;
rc = libinput_device_get_size(dev->libinput_device, &width, &height);
--
2.4.1

View File

@ -0,0 +1,59 @@
From c98229492ce59faf402f446da200658454ace9d5 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Thu, 21 May 2015 13:30:24 +1000
Subject: [PATCH libinput 06/10] touchpad: split disable-while-typing handling
into a helper function
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 3a0985d..ad20fb9 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -478,6 +478,22 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
return false;
}
+static int
+tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
+{
+ if (!tp->dwt.keyboard_active)
+ return 0;
+
+ if (t->state == TOUCH_BEGIN) {
+ t->palm.state = PALM_TYPING;
+ t->palm.time = time;
+ t->palm.first = t->point;
+ return 1;
+ }
+
+ return 0;
+}
+
static void
tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
@@ -486,13 +502,8 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
struct device_float_coords delta;
int dirs;
- if (tp->dwt.keyboard_active &&
- t->state == TOUCH_BEGIN) {
- t->palm.state = PALM_TYPING;
- t->palm.time = time;
- t->palm.first = t->point;
- return;
- }
+ if (tp_palm_detect_dwt(tp, t, time))
+ return;
/* If labelled a touch as palm, we unlabel as palm when
we move out of the palm edge zone within the timeout, provided
--
2.4.1

View File

@ -0,0 +1,85 @@
From 09a79656a27c42699f4a9c8d97df171938e009ef Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 22 May 2015 15:14:04 +1000
Subject: [PATCH libinput 07/10] touchpad: add palm state debugging
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index ad20fb9..56a70cc 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -472,8 +472,11 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
/* We're inside the left/right palm edge and in the northern half of
* the touchpad - this tap is a palm */
- if (t->point.y < tp->palm.vert_center)
+ if (t->point.y < tp->palm.vert_center) {
+ log_debug(tp_libinput_context(tp),
+ "palm: palm-tap detected\n");
return true;
+ }
return false;
}
@@ -503,7 +506,7 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
int dirs;
if (tp_palm_detect_dwt(tp, t, time))
- return;
+ goto out;
/* If labelled a touch as palm, we unlabel as palm when
we move out of the palm edge zone within the timeout, provided
@@ -517,6 +520,8 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
tp_normalize_delta(tp, delta));
if ((dirs & DIRECTIONS) && !(dirs & ~DIRECTIONS)) {
t->palm.state = PALM_NONE;
+ log_debug(tp_libinput_context(tp),
+ "palm: touch released, out of edge zone\n");
}
}
return;
@@ -538,6 +543,11 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->palm.state = PALM_EDGE;
t->palm.time = time;
t->palm.first = t->point;
+
+out:
+ log_debug(tp_libinput_context(tp),
+ "palm: palm detected (%s)\n",
+ t->palm.state == PALM_EDGE ? "edge" : "typing");
}
static void
@@ -879,7 +889,10 @@ tp_keyboard_timeout(uint64_t now, void *data)
struct tp_dispatch *tp = data;
tp_tap_resume(tp, now);
+
tp->dwt.keyboard_active = false;
+
+ log_debug(tp_libinput_context(tp), "palm: keyboard timeout\n");
}
static inline bool
@@ -1004,6 +1017,11 @@ tp_device_added(struct evdev_device *device,
if (added_device->tags & EVDEV_TAG_KEYBOARD &&
tp->dwt.keyboard == NULL &&
tp_want_dwt(device, added_device)) {
+ log_debug(tp_libinput_context(tp),
+ "palm: dwt activated with %s<->%s\n",
+ device->devname,
+ added_device->devname);
+
libinput_device_add_event_listener(&added_device->base,
&tp->dwt.keyboard_listener,
tp_keyboard_event, tp);
--
2.4.1

View File

@ -0,0 +1,31 @@
From 46bb2e4d7583fe7d6b07a3f9fd2270d1e54e2129 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 25 May 2015 11:36:34 +1000
Subject: [PATCH libinput 08/10] touchpad: reset the touch state when edge
scrolling is stopped
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad-edge-scroll.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index 9bf3f0c..f7eae9e 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -438,6 +438,10 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
&zero,
&zero_discrete);
t->scroll.direction = -1;
+ /* reset touch to area state, avoids loading the
+ * state machine with special case handling */
+ t->scroll.edge = EDGE_NONE;
+ t->scroll.edge_state = EDGE_SCROLL_TOUCH_STATE_AREA;
}
}
}
--
2.4.1

View File

@ -0,0 +1,64 @@
From 322d7f2302c61def6deb6c7cc7a406b4f85b880d Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 25 May 2015 16:02:56 +1000
Subject: [PATCH libinput 09/10] touchpad: don't enable edge palm detection on
Wacom touchpads
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
src/evdev-mt-touchpad.c | 10 ++++++++--
test/touchpad.c | 6 +++++-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 56a70cc..9a04893 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1299,6 +1299,7 @@ tp_init_palmdetect(struct tp_dispatch *tp,
struct evdev_device *device)
{
int width, height;
+ unsigned int vendor_id;
tp->palm.right_edge = INT_MAX;
tp->palm.left_edge = INT_MIN;
@@ -1309,8 +1310,13 @@ tp_init_palmdetect(struct tp_dispatch *tp,
height = abs(device->abs.absinfo_y->maximum -
device->abs.absinfo_y->minimum);
- /* Apple touchpads are always big enough to warrant palm detection */
- if (evdev_device_get_id_vendor(device) != VENDOR_ID_APPLE) {
+ vendor_id = evdev_device_get_id_vendor(device);
+
+ /* Wacom doesn't have internal touchpads,
+ * Apple touchpads are always big enough to warrant palm detection */
+ if (vendor_id == VENDOR_ID_WACOM) {
+ return 0;
+ } else if (vendor_id != VENDOR_ID_APPLE) {
/* We don't know how big the touchpad is */
if (device->abs.absinfo_x->resolution == 1)
return 0;
diff --git a/test/touchpad.c b/test/touchpad.c
index 2624dda..e33d0e1 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -2949,9 +2949,13 @@ static int
touchpad_has_palm_detect_size(struct litest_device *dev)
{
double width, height;
+ unsigned int vendor;
int rc;
- if (libinput_device_get_id_vendor(dev->libinput_device) == ID_VENDOR_APPLE)
+ vendor = libinput_device_get_id_vendor(dev->libinput_device);
+ if (vendor == VENDOR_ID_WACOM)
+ return 0;
+ if (vendor == VENDOR_ID_APPLE)
return 1;
rc = libinput_device_get_size(dev->libinput_device, &width, &height);
--
2.4.1

View File

@ -0,0 +1,122 @@
From 1c02bc3dc932c1df2dada0cb814e7401a23c65e8 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Thu, 21 May 2015 16:32:42 +1000
Subject: [PATCH libinput 10/10] touchpad: touches after the last key press can
be released
The current code labels a touch as palm if it started within the typing
timeouts. To move the pointer even after the timeout expires, a user has to
lift the finger which is quite annoying and different to the old synaptics
driver behaviour (which had a simple on/off toggle on whether to let events
through or not).
Be smarter about this: if a touch starts _after_ the last key press event,
release it for pointer motion once the timeout expires. Touches started before
the last key press remain labelled as palms. This makes it possible to rest
the palm on the touchpad while typing without getting interference but also
provides a more responsive UI when moving from typing to using the touchpad
normally.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
doc/palm-detection.dox | 1 -
src/evdev-mt-touchpad-edge-scroll.c | 3 +++
src/evdev-mt-touchpad.c | 24 ++++++++++++++++++++----
src/evdev-mt-touchpad.h | 2 ++
4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/doc/palm-detection.dox b/doc/palm-detection.dox
index a5b578b..7c848e3 100644
--- a/doc/palm-detection.dox
+++ b/doc/palm-detection.dox
@@ -57,5 +57,4 @@ the palm on the touchpad while using the trackstick).
If the touchpad is disabled, the @ref t440_support "top software buttons"
remain enabled.
-
*/
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index f7eae9e..8a4d892 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -361,6 +361,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
if (!t->dirty)
continue;
+ if (t->palm.state != PALM_NONE)
+ continue;
+
switch (t->scroll.edge) {
case EDGE_NONE:
if (t->scroll.direction != -1) {
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 9a04893..94a3376 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -237,6 +237,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->state = TOUCH_END;
t->pinned.is_pinned = false;
t->millis = time;
+ t->palm.time = 0;
assert(tp->nfingers_down >= 1);
tp->nfingers_down--;
tp->queued |= TOUCHPAD_EVENT_MOTION;
@@ -484,14 +485,28 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
static int
tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
- if (!tp->dwt.keyboard_active)
- return 0;
-
- if (t->state == TOUCH_BEGIN) {
+ if (tp->dwt.keyboard_active &&
+ t->state == TOUCH_BEGIN) {
t->palm.state = PALM_TYPING;
t->palm.time = time;
t->palm.first = t->point;
return 1;
+ } else if (!tp->dwt.keyboard_active &&
+ t->state == TOUCH_UPDATE &&
+ t->palm.state == PALM_TYPING)
+ {
+ /* If a touch has started before the first or after the last
+ key press, release it on timeout. Benefit: a palm rested
+ while typing on the touchpad will be ignored, but a touch
+ started once we stop typing will be able to control the
+ pointer (alas not tap, etc.).
+ */
+ if (t->palm.time == 0 ||
+ t->palm.time > tp->dwt.keyboard_last_press_time) {
+ t->palm.state = PALM_NONE;
+ log_debug(tp_libinput_context(tp),
+ "palm: touch released, timeout after typing\n");
+ }
}
return 0;
@@ -958,6 +973,7 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
}
+ tp->dwt.keyboard_last_press_time = time;
libinput_timer_set(&tp->dwt.keyboard_timer,
time + timeout);
}
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index db877c7..d086192 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -284,6 +284,8 @@ struct tp_dispatch {
struct libinput_event_listener keyboard_listener;
struct libinput_timer keyboard_timer;
struct evdev_device *keyboard;
+
+ uint64_t keyboard_last_press_time;
} dwt;
};
--
2.4.1

View File

@ -5,7 +5,7 @@
Name: libinput
Version: 0.15.0
Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Release: 3%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Summary: Input device library
License: MIT
@ -22,6 +22,17 @@ Patch01: 0001-touchpad-switch-from-is_palm-to-an-enum.patch
Patch02: 0002-touchpad-add-timeout-based-disable-while-typing.patch
Patch03: 0003-touchpad-use-a-two-stage-timeout-for-disable-while-t.patch
Patch04: 0001-touchpad-move-disable-while-typing-into-its-own-stru.patch
Patch05: 0002-touchpad-extend-the-key-blacklist-for-disable-while-.patch
Patch06: 0003-touchpad-add-helper-function-to-get-from-tp-to-the-l.patch
Patch07: 0004-touchpad-only-check-keyboards-for-disable-while-typi.patch
Patch08: 0005-touchpad-be-finer-grained-about-when-to-pair-touchpa.patch
Patch09: 0006-touchpad-split-disable-while-typing-handling-into-a-.patch
Patch10: 0007-touchpad-add-palm-state-debugging.patch
Patch11: 0008-touchpad-reset-the-touch-state-when-edge-scrolling-i.patch
Patch12: 0009-touchpad-don-t-enable-edge-palm-detection-on-Wacom-t.patch
Patch13: 0010-touchpad-touches-after-the-last-key-press-can-be-rel.patch
BuildRequires: git
BuildRequires: autoconf automake libtool pkgconfig
BuildRequires: libevdev-devel
@ -97,6 +108,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
%changelog
* Wed May 27 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.15.0-3
- Refine disable-while-typing (#1209753)
* Mon May 18 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.15.0-2
- Add disable-while-typing feature (#1209753)