summaryrefslogtreecommitdiff
path: root/test/test-touchpad.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2018-05-16 09:40:50 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2018-05-18 12:05:02 +1000
commit6adb336829951d8d3acd5498d53ef1d505db3373 (patch)
tree8b10617cea5a68ff1b982aacec89ea77cd710477 /test/test-touchpad.c
parenta9d78e99ea854a212dd46e361683b0cda4bfc229 (diff)
downloadlibinput-6adb336829951d8d3acd5498d53ef1d505db3373.tar.gz
touchpad: remember the suspend reason
There are 4 possible cases why a touchpad suspends right now: lid switch, tablet mode switch, sendevents disabled and sendevents disabled when an external mouse is present. But these reasons can stack up, e.g. a lid switch may happen while send events is disabled, disabling one should not re-enable the touchpad. This patch adds a bitmask to remember the reasons we're current suspended, resuming only happens once all reasons are back to 0. https://bugs.freedesktop.org/show_bug.cgi?id=106498 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'test/test-touchpad.c')
-rw-r--r--test/test-touchpad.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index 8341e209..2294bb88 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -5968,8 +5968,322 @@ START_TEST(touchpad_speed_ignore_finger_edgescroll)
}
END_TEST
+enum suspend {
+ SUSPEND_EXT_MOUSE = 1,
+ SUSPEND_SENDEVENTS,
+ SUSPEND_LID,
+ SUSPEND_TABLETMODE,
+ SUSPEND_COUNT,
+};
+
+static void
+assert_touchpad_moves(struct litest_device *tp)
+{
+ struct libinput *li = tp->libinput;
+
+ litest_touch_down(tp, 0, 50, 50);
+ litest_touch_move_to(tp, 0, 50, 50, 60, 80, 20, 0);
+ litest_touch_up(tp, 0);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+}
+
+static void
+assert_touchpad_does_not_move(struct litest_device *tp)
+{
+ struct libinput *li = tp->libinput;
+
+ litest_touch_down(tp, 0, 20, 20);
+ litest_touch_move_to(tp, 0, 20, 20, 60, 80, 20, 0);
+ litest_touch_up(tp, 0);
+ litest_assert_empty_queue(li);
+}
+
+START_TEST(touchpad_suspend_abba)
+{
+ struct litest_device *tp = litest_current_device();
+ struct litest_device *lid, *tabletmode, *extmouse;
+ struct libinput *li = tp->libinput;
+ enum suspend first = _i; /* ranged test */
+ enum suspend other;
+
+ if (first == SUSPEND_EXT_MOUSE && litest_touchpad_is_external(tp))
+ return;
+
+ lid = litest_add_device(li, LITEST_LID_SWITCH);
+ tabletmode = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
+ extmouse = litest_add_device(li, LITEST_MOUSE);
+
+ litest_disable_tap(tp->libinput_device);
+
+ /* ABBA test for touchpad internal suspend:
+ * reason A on
+ * reason B on
+ * reason B off
+ * reason A off
+ */
+ for (other = SUSPEND_EXT_MOUSE; other < SUSPEND_COUNT; other++) {
+ if (other == first)
+ continue;
+
+ if (other == SUSPEND_EXT_MOUSE && litest_touchpad_is_external(tp))
+ return;
+
+ /* That transition is tested elsewhere and has a different
+ * behavior */
+ if ((other == SUSPEND_SENDEVENTS && first == SUSPEND_EXT_MOUSE) ||
+ (first == SUSPEND_SENDEVENTS && other == SUSPEND_EXT_MOUSE))
+ continue;
+
+ litest_drain_events(li);
+ assert_touchpad_moves(tp);
+
+ /* First reason for suspend: on */
+ switch (first) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_ext_mouse(tp);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_ON);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_ON);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_off(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ litest_drain_events(li);
+
+ assert_touchpad_does_not_move(tp);
+
+ /* Second reason to suspend: on/off while first reason remains */
+ switch (other) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_ext_mouse(tp);
+ litest_sendevents_on(tp);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_ON);
+ litest_drain_events(li);
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_OFF);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_ON);
+ litest_drain_events(li);
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_OFF);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_off(tp);
+ litest_sendevents_on(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ assert_touchpad_does_not_move(tp);
+
+ /* First reason for suspend: off */
+ switch (first) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_on(tp);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_OFF);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_OFF);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_on(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ litest_drain_events(li);
+ assert_touchpad_moves(tp);
+ }
+
+ litest_delete_device(lid);
+ litest_delete_device(tabletmode);
+ litest_delete_device(extmouse);
+}
+END_TEST
+
+START_TEST(touchpad_suspend_abab)
+{
+ struct litest_device *tp = litest_current_device();
+ struct litest_device *lid, *tabletmode, *extmouse;
+ struct libinput *li = tp->libinput;
+ enum suspend first = _i; /* ranged test */
+ enum suspend other;
+
+ if (first == SUSPEND_EXT_MOUSE && litest_touchpad_is_external(tp))
+ return;
+
+ lid = litest_add_device(li, LITEST_LID_SWITCH);
+ tabletmode = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
+ extmouse = litest_add_device(li, LITEST_MOUSE);
+
+ litest_disable_tap(tp->libinput_device);
+
+ /* ABAB test for touchpad internal suspend:
+ * reason A on
+ * reason B on
+ * reason A off
+ * reason B off
+ */
+ for (other = SUSPEND_EXT_MOUSE; other < SUSPEND_COUNT; other++) {
+ if (other == first)
+ continue;
+
+ if (other == SUSPEND_EXT_MOUSE && litest_touchpad_is_external(tp))
+ return;
+
+ /* That transition is tested elsewhere and has a different
+ * behavior */
+ if ((other == SUSPEND_SENDEVENTS && first == SUSPEND_EXT_MOUSE) ||
+ (first == SUSPEND_SENDEVENTS && other == SUSPEND_EXT_MOUSE))
+ continue;
+
+ litest_drain_events(li);
+ assert_touchpad_moves(tp);
+
+ /* First reason for suspend: on */
+ switch (first) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_ext_mouse(tp);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_ON);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_ON);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_off(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ litest_drain_events(li);
+
+ assert_touchpad_does_not_move(tp);
+
+ /* Second reason to suspend: on */
+ switch (other) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_ext_mouse(tp);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_ON);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_ON);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_off(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ assert_touchpad_does_not_move(tp);
+
+ /* First reason for suspend: off */
+ switch (first) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_on(tp);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_OFF);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_OFF);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_on(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ litest_drain_events(li);
+ assert_touchpad_does_not_move(tp);
+
+ /* Second reason to suspend: off */
+ switch (other) {
+ case SUSPEND_EXT_MOUSE:
+ litest_sendevents_on(tp);
+ break;
+ case SUSPEND_LID:
+ litest_switch_action(lid,
+ LIBINPUT_SWITCH_LID,
+ LIBINPUT_SWITCH_STATE_OFF);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_TABLETMODE:
+ litest_switch_action(tabletmode,
+ LIBINPUT_SWITCH_TABLET_MODE,
+ LIBINPUT_SWITCH_STATE_OFF);
+ litest_drain_events(li);
+ break;
+ case SUSPEND_SENDEVENTS:
+ litest_sendevents_on(tp);
+ break;
+ default:
+ ck_abort();
+ }
+
+ litest_drain_events(li);
+ assert_touchpad_moves(tp);
+ }
+
+ litest_delete_device(lid);
+ litest_delete_device(tabletmode);
+ litest_delete_device(extmouse);
+}
+END_TEST
+
TEST_COLLECTION(touchpad)
{
+ struct range suspends = { SUSPEND_EXT_MOUSE, SUSPEND_COUNT };
struct range axis_range = {ABS_X, ABS_Y + 1};
struct range twice = {0, 2 };
@@ -6150,4 +6464,7 @@ TEST_COLLECTION(touchpad)
litest_add("touchpad:speed", touchpad_speed_ignore_finger, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:speed", touchpad_speed_allow_nearby_finger, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:speed", touchpad_speed_ignore_finger_edgescroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+
+ litest_add_ranged("touchpad:suspend", touchpad_suspend_abba, LITEST_TOUCHPAD, LITEST_ANY, &suspends);
+ litest_add_ranged("touchpad:suspend", touchpad_suspend_abab, LITEST_TOUCHPAD, LITEST_ANY, &suspends);
}