diff --git a/doc/touchpad-softbutton-state-machine.svg b/doc/touchpad-softbutton-state-machine.svg index 1838e354..11423435 100644 --- a/doc/touchpad-softbutton-state-machine.svg +++ b/doc/touchpad-softbutton-state-machine.svg @@ -1,173 +1,390 @@ - + - - - + + + - + NONE - + on-entry: - + curr = none - + - + BOTTOM_NEW - + on-entry: - + curr = button - + start inner timeout - + - + AREA - + on-entry: - + curr =area - + - + finger in - + area - + - + BOTTOM - + - + finger - + up - + - + phys - + button - + press - - - + + + - + inner - + timeout - - - - - + + + + + - + finger in - + AREA - - - + + + - + BOTTOM_TO_AREA - + on-entry: - + start outer timeout - - - + + + - + outer - + timeout - - - - - + + + + + - + finger in - + bottom - - - - - + + + + + - + finger in - + area - - - - - + + + + + - + finger in - + bottom - + button != curr - - - - - + + + + + + + + + - -ANY - - - - - - - - - - - - + finger in - + bottom - + button == curr - - - - - - - - + + + + + + + + + + + + + + + + + + + + + +Check state of + +all touches + + + + + + + + + +tp_post_softbutton_buttons() + + + + +!buttons.click_pend + +&& current == old + + + + + + +yes + + + + + + +no + + + + + + +current = buttons.state & 0x01 + +old = buttons.old_state & 0x01 + +button = 0 + + + + + + +All touches are in state none + + + + + + +no + + + + + + +yes + + + + +buttons.click_pend = 1 + + + + + + +(Some touches are in right) && + +(Some touches are in left) + + + + + + +yes + + + + +button = BTN_MIDDLE + + + + + + +current + + + + + + +no + + + + + + +yes + + + + +Some touches are in right + + + + + + +yes + + + + + + +no + + + + +button = BTN_RIGHT + + + + +button = BTN_LEFT + + + + + + +no + + + + +buttons.active = button + +state = BUTTON_PRESSED + + + + + + + + + + +button = buttons.active + +buttons.active = 0 + +state = BUTTON_RELEASED + + + + +buttons.click_pend = 0 + + + + + + + + +button + + + + + + +no + + + + + + +yes + + + + +pointer_notify_button( + +button, state) + + + + + + + diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index f278eadc..de3f36c4 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -545,51 +545,68 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint32_t time) { uint32_t current, old, button; enum libinput_pointer_button_state state; + enum { AREA = 0x01, LEFT = 0x02, RIGHT = 0x04 }; current = tp->buttons.state; old = tp->buttons.old_state; + button = 0; - if (current == old) - return 0; - - if (tp->nfingers_down == 0 || tp->nfingers_down > 2) + if (!tp->buttons.click_pending && current == old) return 0; if (current) { struct tp_touch *t; - button = 0; tp_for_each_touch(tp, t) { - if (t->button.curr == BUTTON_EVENT_IN_BOTTOM_R) - button |= 0x2; - else if (t->button.curr == BUTTON_EVENT_IN_BOTTOM_L) - button |= 0x1; + switch (t->button.curr) { + case BUTTON_EVENT_IN_AREA: + button |= AREA; + break; + case BUTTON_EVENT_IN_BOTTOM_L: + button |= LEFT; + break; + case BUTTON_EVENT_IN_BOTTOM_R: + button |= RIGHT; + break; + default: + break; + } } switch (button) { - case 0: /* only in area */ - case 1: /* only left area */ - button = BTN_LEFT; - break; - case 2: /* only right area */ + case 0: + /* No touches, wait for a touch before processing */ + tp->buttons.click_pending = true; + return 0; + case RIGHT: + case RIGHT | AREA: + /* Some touches in right, no touches in left */ button = BTN_RIGHT; break; - case 3: /* left + right area */ + case LEFT | RIGHT: + case LEFT | RIGHT | AREA: + /* Some touches in left and some in right */ button = BTN_MIDDLE; break; + default: + button = BTN_LEFT; } tp->buttons.active = button; state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED; } else { - state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED; button = tp->buttons.active; + tp->buttons.active = 0; + state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED; } - pointer_notify_button(&tp->device->base, - time, - button, - state); + tp->buttons.click_pending = false; + + if (button) + pointer_notify_button(&tp->device->base, + time, + button, + state); return 1; } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 78a74dfe..41f9daf7 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -156,6 +156,7 @@ struct tp_dispatch { struct { bool is_clickpad; /* true for clickpads */ bool use_clickfinger; /* number of fingers decides button number */ + bool click_pending; uint32_t state; uint32_t old_state; uint32_t motion_dist; /* for pinned touches */