On touchpads without physical buttons, the number of fingers on the touchpad at the time the physical click happens decides the button type. 1/2/3 fingers is handled left/right/middle.
We also swallow the motion event on the actual click event, this reduces erroneous motion events by a bit. More processing is needed here though. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- src/evdev-mt-touchpad.c | 67 +++++++++++++++++++++++++++++++++++++++++++------ src/evdev-mt-touchpad.h | 1 + test/pointer.c | 2 +- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index d0864fe..154df85 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -461,14 +461,42 @@ tp_post_scroll_events(struct tp_dispatch *tp, uint32_t time) return 0; } -static void -tp_post_button_events(struct tp_dispatch *tp, uint32_t time) +static int +tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint32_t time) { uint32_t current, old, button; + enum libinput_pointer_button_state state; - if ((tp->queued & - (TOUCHPAD_EVENT_BUTTON_PRESS|TOUCHPAD_EVENT_BUTTON_RELEASE)) == 0) - return; + current = tp->buttons.state; + old = tp->buttons.old_state; + + if (current == old) + return 0; + + switch (tp->nfingers_down) { + case 1: button = BTN_LEFT; break; + case 2: button = BTN_RIGHT; break; + case 3: button = BTN_MIDDLE; break; + default: + return 0; + } + + if (current) + state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED; + else + state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED; + + pointer_notify_button(&tp->device->base, + time, + button, + state); + return 1; +} + +static int +tp_post_physical_buttons(struct tp_dispatch *tp, uint32_t time) +{ + uint32_t current, old, button; current = tp->buttons.state; old = tp->buttons.old_state; @@ -493,6 +521,25 @@ tp_post_button_events(struct tp_dispatch *tp, uint32_t time) current >>= 1; old >>= 1; } + + return 0; +} + +static int +tp_post_button_events(struct tp_dispatch *tp, uint32_t time) +{ + int rc; + + if ((tp->queued & + (TOUCHPAD_EVENT_BUTTON_PRESS|TOUCHPAD_EVENT_BUTTON_RELEASE)) == 0) + return 0; + + if (tp->buttons.has_buttons) + rc = tp_post_physical_buttons(tp, time); + else + rc = tp_post_clickfinger_buttons(tp, time); + + return rc; } static void @@ -501,6 +548,9 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time) struct tp_touch *t = tp_current_touch(tp); double dx, dy; + if (tp_post_button_events(tp, time) != 0) + return; + if (tp_tap_handle_state(tp, time) != 0) return; @@ -519,8 +569,6 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time) li_fixed_from_double(dx), li_fixed_from_double(dy)); } - - tp_post_button_events(tp, time); } static void @@ -622,6 +670,7 @@ tp_init(struct tp_dispatch *tp, { int width, height; double diagonal; + unsigned long key_bits[NBITS(KEY_MAX)]; tp->base.interface = &tp_interface; tp->device = device; @@ -638,6 +687,10 @@ tp_init(struct tp_dispatch *tp, tp->hysteresis.margin_y = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; + ioctl(device->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits); + if (TEST_BIT(key_bits, BTN_RIGHT) || TEST_BIT(key_bits, BTN_MIDDLE)) + tp->buttons.has_buttons = true; + if (tp_init_scroll(tp) != 0) return -1; diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 84d8cec..327ce11 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -117,6 +117,7 @@ struct tp_dispatch { } accel; struct { + bool has_buttons; /* true for physical LMR buttons */ uint32_t state; uint32_t old_state; } buttons; /* physical buttons */ diff --git a/test/pointer.c b/test/pointer.c index e864169..59fe818 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -186,7 +186,7 @@ END_TEST int main (int argc, char **argv) { litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY); - litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_ANY); + litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD); litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY); return litest_run(argc, argv); -- 1.8.4.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel