From 02cf9e8a64fb822524d74b57b8c23b5f1460c22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 11 Aug 2016 16:02:26 +0200 Subject: [PATCH] [libinput] Add support for tap and drag From libinput documentation: A tap immediately followed by a finger down and that finger being held down emulates a button press. Moving the finger around can thus drag the selected item on the screen. --- autotests/libinput/device_test.cpp | 58 ++++++++++++++++++++++++++++ autotests/libinput/mock_libinput.cpp | 27 +++++++++++++ autotests/libinput/mock_libinput.h | 3 ++ libinput/device.cpp | 3 ++ libinput/device.h | 12 ++++++ 5 files changed, 103 insertions(+) diff --git a/autotests/libinput/device_test.cpp b/autotests/libinput/device_test.cpp index af2eb97f16..b455556b49 100644 --- a/autotests/libinput/device_test.cpp +++ b/autotests/libinput/device_test.cpp @@ -69,6 +69,10 @@ private Q_SLOTS: void testEnabled(); void testTapToClick_data(); void testTapToClick(); + void testTapAndDragEnabledByDefault_data(); + void testTapAndDragEnabledByDefault(); + void testTapAndDrag_data(); + void testTapAndDrag(); }; void TestLibinputDevice::testStaticGetter() @@ -648,5 +652,59 @@ void TestLibinputDevice::testTapToClick() QCOMPARE(tapToClickChangedSpy.isEmpty(), initValue == expectedValue); } +void TestLibinputDevice::testTapAndDragEnabledByDefault_data() +{ + QTest::addColumn("enabled"); + + QTest::newRow("enabled") << true; + QTest::newRow("disabled") << false; +} + +void TestLibinputDevice::testTapAndDragEnabledByDefault() +{ + QFETCH(bool, enabled); + libinput_device device; + device.tapAndDragEnabledByDefault = enabled; + + Device d(&device); + QCOMPARE(d.tapAndDragEnabledByDefault(), enabled); + QCOMPARE(d.property("tapAndDragEnabledByDefault").toBool(), enabled); +} + +void TestLibinputDevice::testTapAndDrag_data() +{ + QTest::addColumn("initValue"); + QTest::addColumn("setValue"); + QTest::addColumn("setShouldFail"); + QTest::addColumn("expectedValue"); + + QTest::newRow("true -> false") << true << false << false << false; + QTest::newRow("false -> true") << false << true << false << true; + QTest::newRow("set fails") << true << false << true << true; + QTest::newRow("true -> true") << true << true << false << true; + QTest::newRow("false -> false") << false << false << false << false; +} + +void TestLibinputDevice::testTapAndDrag() +{ + libinput_device device; + QFETCH(bool, initValue); + QFETCH(bool, setShouldFail); + device.tapAndDrag = initValue; + device.setTapAndDragReturnValue = setShouldFail; + + Device d(&device); + QCOMPARE(d.isTapAndDrag(), initValue); + QCOMPARE(d.property("tapAndDrag").toBool(), initValue); + + QSignalSpy tapAndDragChangedSpy(&d, &Device::tapAndDragChanged); + QVERIFY(tapAndDragChangedSpy.isValid()); + QFETCH(bool, setValue); + d.setTapAndDrag(setValue); + QFETCH(bool, expectedValue); + QCOMPARE(d.isTapAndDrag(), expectedValue); + QCOMPARE(tapAndDragChangedSpy.isEmpty(), initValue == expectedValue); +} + QTEST_GUILESS_MAIN(TestLibinputDevice) #include "device_test.moc" diff --git a/autotests/libinput/mock_libinput.cpp b/autotests/libinput/mock_libinput.cpp index ebfe1eff37..fb3cdbd186 100644 --- a/autotests/libinput/mock_libinput.cpp +++ b/autotests/libinput/mock_libinput.cpp @@ -103,6 +103,33 @@ enum libinput_config_tap_state libinput_device_config_tap_get_default_enabled(st } } +enum libinput_config_drag_state libinput_device_config_tap_get_default_drag_enabled(struct libinput_device *device) +{ + if (device->tapAndDragEnabledByDefault) { + return LIBINPUT_CONFIG_DRAG_ENABLED; + } else { + return LIBINPUT_CONFIG_DRAG_DISABLED; + } +} + +enum libinput_config_drag_state libinput_device_config_tap_get_drag_enabled(struct libinput_device *device) +{ + if (device->tapAndDrag) { + return LIBINPUT_CONFIG_DRAG_ENABLED; + } else { + return LIBINPUT_CONFIG_DRAG_DISABLED; + } +} + +enum libinput_config_status libinput_device_config_tap_set_drag_enabled(struct libinput_device *device, enum libinput_config_drag_state enable) +{ + if (device->setTapAndDragReturnValue == 0) { + device->tapAndDrag = (enable == LIBINPUT_CONFIG_DRAG_ENABLED); + return LIBINPUT_CONFIG_STATUS_SUCCESS; + } + return LIBINPUT_CONFIG_STATUS_INVALID; +} + int libinput_device_config_dwt_is_available(struct libinput_device *device) { return device->supportsDisableWhileTyping; diff --git a/autotests/libinput/mock_libinput.h b/autotests/libinput/mock_libinput.h index 9c4415c8d4..5380fc042e 100644 --- a/autotests/libinput/mock_libinput.h +++ b/autotests/libinput/mock_libinput.h @@ -42,6 +42,8 @@ struct libinput_device { int deviceSizeReturnValue = 0; bool tapEnabledByDefault = false; bool tapToClick = false; + bool tapAndDragEnabledByDefault = false; + bool tapAndDrag = false; bool supportsDisableWhileTyping = false; bool supportsPointerAcceleration = false; bool supportsLeftHanded = false; @@ -57,6 +59,7 @@ struct libinput_device { bool enabled = true; int setEnableModeReturnValue = 0; int setTapToClickReturnValue = 0; + int setTapAndDragReturnValue = 0; }; struct libinput_event { diff --git a/libinput/device.cpp b/libinput/device.cpp index b2be1a3533..db9928aa21 100644 --- a/libinput/device.cpp +++ b/libinput/device.cpp @@ -91,6 +91,8 @@ Device::Device(libinput_device *device, QObject *parent) , m_tapFingerCount(libinput_device_config_tap_get_finger_count(m_device)) , m_tapToClickEnabledByDefault(libinput_device_config_tap_get_default_enabled(m_device) == LIBINPUT_CONFIG_TAP_ENABLED) , m_tapToClick(libinput_device_config_tap_get_enabled(m_device)) + , m_tapAndDragEnabledByDefault(libinput_device_config_tap_get_default_drag_enabled(m_device)) + , m_tapAndDrag(libinput_device_config_tap_get_drag_enabled(m_device)) , m_supportsDisableWhileTyping(libinput_device_config_dwt_is_available(m_device)) , m_supportsPointerAcceleration(libinput_device_config_accel_is_available(m_device)) , m_supportsLeftHanded(libinput_device_config_left_handed_is_available(m_device)) @@ -190,6 +192,7 @@ void Device::method(bool set) \ CONFIG(setEnabled, !m_supportsDisableEvents, send_events_set_mode, SEND_EVENTS, enabled) CONFIG(setTapToClick, m_tapFingerCount == 0, tap_set_enabled, TAP, tapToClick) +CONFIG(setTapAndDrag, false, tap_set_drag_enabled, DRAG, tapAndDrag) #undef CONFIG diff --git a/libinput/device.h b/libinput/device.h index 872bc618f2..7cd2c1469d 100644 --- a/libinput/device.h +++ b/libinput/device.h @@ -59,6 +59,8 @@ class Device : public QObject Q_PROPERTY(bool leftHanded READ isLeftHanded WRITE setLeftHanded NOTIFY leftHandedChanged) Q_PROPERTY(qreal pointerAcceleration READ pointerAcceleration WRITE setPointerAcceleration NOTIFY pointerAccelerationChanged) Q_PROPERTY(bool tapToClick READ isTapToClick WRITE setTapToClick NOTIFY tapToClickChanged) + Q_PROPERTY(bool tapAndDragEnabledByDefault READ tapAndDragEnabledByDefault CONSTANT) + Q_PROPERTY(bool tapAndDrag READ isTapAndDrag WRITE setTapAndDrag NOTIFY tapAndDragChanged) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) public: explicit Device(libinput_device *device, QObject *parent = nullptr); @@ -119,6 +121,13 @@ public: * Set the Device to tap to click if @p set is @c true. **/ void setTapToClick(bool set); + bool tapAndDragEnabledByDefault() const { + return m_tapAndDragEnabledByDefault; + } + bool isTapAndDrag() const { + return m_tapAndDrag; + } + void setTapAndDrag(bool set); bool supportsDisableWhileTyping() const { return m_supportsDisableWhileTyping; } @@ -180,6 +189,7 @@ Q_SIGNALS: void pointerAccelerationChanged(); void enabledChanged(); void tapToClickChanged(); + void tapAndDragChanged(); private: libinput_device *m_device; @@ -200,6 +210,8 @@ private: int m_tapFingerCount; bool m_tapToClickEnabledByDefault; bool m_tapToClick; + bool m_tapAndDragEnabledByDefault; + bool m_tapAndDrag; bool m_supportsDisableWhileTyping; bool m_supportsPointerAcceleration; bool m_supportsLeftHanded;