File indexing completed on 2024-05-12 17:01:42

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include <config-kwin.h>
0010 
0011 #include "backends/libinput/device.h"
0012 #include "mock_libinput.h"
0013 
0014 #include <KSharedConfig>
0015 
0016 #include <QDBusConnection>
0017 #include <QDBusInterface>
0018 #include <QtTest>
0019 
0020 #include <linux/input.h>
0021 
0022 using namespace KWin::LibInput;
0023 
0024 class TestLibinputDevice : public QObject
0025 {
0026     Q_OBJECT
0027 private Q_SLOTS:
0028     void initTestCase();
0029     void testDeviceType_data();
0030     void testDeviceType();
0031     void testGestureSupport_data();
0032     void testGestureSupport();
0033     void testNames_data();
0034     void testNames();
0035     void testProduct();
0036     void testVendor();
0037     void testTapFingerCount();
0038     void testSize_data();
0039     void testSize();
0040     void testDefaultPointerAcceleration_data();
0041     void testDefaultPointerAcceleration();
0042     void testDefaultPointerAccelerationProfileFlat_data();
0043     void testDefaultPointerAccelerationProfileFlat();
0044     void testDefaultPointerAccelerationProfileAdaptive_data();
0045     void testDefaultPointerAccelerationProfileAdaptive();
0046     void testDefaultClickMethodAreas_data();
0047     void testDefaultClickMethodAreas();
0048     void testDefaultClickMethodClickfinger_data();
0049     void testDefaultClickMethodClickfinger();
0050     void testLeftHandedEnabledByDefault_data();
0051     void testLeftHandedEnabledByDefault();
0052     void testTapEnabledByDefault_data();
0053     void testTapEnabledByDefault();
0054     void testMiddleEmulationEnabledByDefault_data();
0055     void testMiddleEmulationEnabledByDefault();
0056     void testNaturalScrollEnabledByDefault_data();
0057     void testNaturalScrollEnabledByDefault();
0058     void testScrollTwoFingerEnabledByDefault_data();
0059     void testScrollTwoFingerEnabledByDefault();
0060     void testScrollEdgeEnabledByDefault_data();
0061     void testScrollEdgeEnabledByDefault();
0062     void testScrollOnButtonDownEnabledByDefault_data();
0063     void testScrollOnButtonDownEnabledByDefault();
0064     void testDisableWhileTypingEnabledByDefault_data();
0065     void testDisableWhileTypingEnabledByDefault();
0066     void testLmrTapButtonMapEnabledByDefault_data();
0067     void testLmrTapButtonMapEnabledByDefault();
0068     void testSupportsDisableWhileTyping_data();
0069     void testSupportsDisableWhileTyping();
0070     void testSupportsPointerAcceleration_data();
0071     void testSupportsPointerAcceleration();
0072     void testSupportsLeftHanded_data();
0073     void testSupportsLeftHanded();
0074     void testSupportsCalibrationMatrix_data();
0075     void testSupportsCalibrationMatrix();
0076     void testSupportsDisableEvents_data();
0077     void testSupportsDisableEvents();
0078     void testSupportsDisableEventsOnExternalMouse_data();
0079     void testSupportsDisableEventsOnExternalMouse();
0080     void testSupportsMiddleEmulation_data();
0081     void testSupportsMiddleEmulation();
0082     void testSupportsNaturalScroll_data();
0083     void testSupportsNaturalScroll();
0084     void testSupportsScrollTwoFinger_data();
0085     void testSupportsScrollTwoFinger();
0086     void testSupportsScrollEdge_data();
0087     void testSupportsScrollEdge();
0088     void testSupportsScrollOnButtonDown_data();
0089     void testSupportsScrollOnButtonDown();
0090     void testDefaultScrollButton_data();
0091     void testDefaultScrollButton();
0092     void testPointerAcceleration_data();
0093     void testPointerAcceleration();
0094     void testLeftHanded_data();
0095     void testLeftHanded();
0096     void testSupportedButtons_data();
0097     void testSupportedButtons();
0098     void testAlphaNumericKeyboard_data();
0099     void testAlphaNumericKeyboard();
0100     void testEnabled_data();
0101     void testEnabled();
0102     void testTapToClick_data();
0103     void testTapToClick();
0104     void testTapAndDragEnabledByDefault_data();
0105     void testTapAndDragEnabledByDefault();
0106     void testTapAndDrag_data();
0107     void testTapAndDrag();
0108     void testTapDragLockEnabledByDefault_data();
0109     void testTapDragLockEnabledByDefault();
0110     void testTapDragLock_data();
0111     void testTapDragLock();
0112     void testMiddleEmulation_data();
0113     void testMiddleEmulation();
0114     void testNaturalScroll_data();
0115     void testNaturalScroll();
0116     void testScrollFactor();
0117     void testScrollTwoFinger_data();
0118     void testScrollTwoFinger();
0119     void testScrollEdge_data();
0120     void testScrollEdge();
0121     void testScrollButtonDown_data();
0122     void testScrollButtonDown();
0123     void testScrollButton_data();
0124     void testScrollButton();
0125     void testDisableWhileTyping_data();
0126     void testDisableWhileTyping();
0127     void testLmrTapButtonMap_data();
0128     void testLmrTapButtonMap();
0129     void testLoadEnabled_data();
0130     void testLoadEnabled();
0131     void testLoadPointerAcceleration_data();
0132     void testLoadPointerAcceleration();
0133     void testLoadPointerAccelerationProfile_data();
0134     void testLoadPointerAccelerationProfile();
0135     void testLoadClickMethod_data();
0136     void testLoadClickMethod();
0137     void testLoadTapToClick_data();
0138     void testLoadTapToClick();
0139     void testLoadTapAndDrag_data();
0140     void testLoadTapAndDrag();
0141     void testLoadTapDragLock_data();
0142     void testLoadTapDragLock();
0143     void testLoadMiddleButtonEmulation_data();
0144     void testLoadMiddleButtonEmulation();
0145     void testLoadNaturalScroll_data();
0146     void testLoadNaturalScroll();
0147     void testLoadScrollMethod_data();
0148     void testLoadScrollMethod();
0149     void testLoadScrollButton_data();
0150     void testLoadScrollButton();
0151     void testLoadDisableWhileTyping_data();
0152     void testLoadDisableWhileTyping();
0153     void testLoadLmrTapButtonMap_data();
0154     void testLoadLmrTapButtonMap();
0155     void testLoadLeftHanded_data();
0156     void testLoadLeftHanded();
0157     void testOrientation_data();
0158     void testOrientation();
0159     void testCalibrationWithDefault();
0160     void testSwitch_data();
0161     void testSwitch();
0162 };
0163 
0164 namespace
0165 {
0166 template<typename T>
0167 T dbusProperty(const QString &name, const char *property)
0168 {
0169     QDBusInterface interface {
0170         QStringLiteral("org.kde.kwin.tests.libinputdevice"),
0171             QStringLiteral("/org/kde/KWin/InputDevice/") + name,
0172             QStringLiteral("org.kde.KWin.InputDevice")
0173     };
0174     return interface.property(property).value<T>();
0175 }
0176 }
0177 
0178 void TestLibinputDevice::initTestCase()
0179 {
0180     QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kwin.tests.libinputdevice"));
0181 }
0182 
0183 void TestLibinputDevice::testDeviceType_data()
0184 {
0185     QTest::addColumn<bool>("keyboard");
0186     QTest::addColumn<bool>("pointer");
0187     QTest::addColumn<bool>("touch");
0188     QTest::addColumn<bool>("tabletTool");
0189     QTest::addColumn<bool>("switchDevice");
0190 
0191     QTest::newRow("keyboard") << true << false << false << false << false;
0192     QTest::newRow("pointer") << false << true << false << false << false;
0193     QTest::newRow("touch") << false << false << true << false << false;
0194     QTest::newRow("keyboard/pointer") << true << true << false << false << false;
0195     QTest::newRow("keyboard/touch") << true << false << true << false << false;
0196     QTest::newRow("pointer/touch") << false << true << true << false << false;
0197     QTest::newRow("keyboard/pointer/touch") << true << true << true << false << false;
0198     QTest::newRow("tabletTool") << false << false << false << true << false;
0199     QTest::newRow("switch") << false << false << false << false << true;
0200 }
0201 
0202 void TestLibinputDevice::testDeviceType()
0203 {
0204     // this test verifies that the device type is recognized correctly
0205     QFETCH(bool, keyboard);
0206     QFETCH(bool, pointer);
0207     QFETCH(bool, touch);
0208     QFETCH(bool, tabletTool);
0209     QFETCH(bool, switchDevice);
0210 
0211     libinput_device device;
0212     device.keyboard = keyboard;
0213     device.pointer = pointer;
0214     device.touch = touch;
0215     device.tabletTool = tabletTool;
0216     device.switchDevice = switchDevice;
0217 
0218     Device d(&device);
0219     QCOMPARE(d.isKeyboard(), keyboard);
0220     QCOMPARE(d.property("keyboard").toBool(), keyboard);
0221     QCOMPARE(dbusProperty<bool>(d.sysName(), "keyboard"), keyboard);
0222     QCOMPARE(d.isPointer(), pointer);
0223     QCOMPARE(d.property("pointer").toBool(), pointer);
0224     QCOMPARE(dbusProperty<bool>(d.sysName(), "pointer"), pointer);
0225     QCOMPARE(d.isTouch(), touch);
0226     QCOMPARE(d.property("touch").toBool(), touch);
0227     QCOMPARE(dbusProperty<bool>(d.sysName(), "touch"), touch);
0228     QCOMPARE(d.isTabletPad(), false);
0229     QCOMPARE(d.property("tabletPad").toBool(), false);
0230     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletPad"), false);
0231     QCOMPARE(d.isTabletTool(), tabletTool);
0232     QCOMPARE(d.property("tabletTool").toBool(), tabletTool);
0233     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletTool"), tabletTool);
0234     QCOMPARE(d.isSwitch(), switchDevice);
0235     QCOMPARE(d.property("switchDevice").toBool(), switchDevice);
0236     QCOMPARE(dbusProperty<bool>(d.sysName(), "switchDevice"), switchDevice);
0237 
0238     QCOMPARE(d.device(), &device);
0239 }
0240 
0241 void TestLibinputDevice::testGestureSupport_data()
0242 {
0243     QTest::addColumn<bool>("supported");
0244 
0245     QTest::newRow("supported") << true;
0246     QTest::newRow("not supported") << false;
0247 }
0248 
0249 void TestLibinputDevice::testGestureSupport()
0250 {
0251     // this test verifies whether the Device supports gestures
0252     QFETCH(bool, supported);
0253     libinput_device device;
0254     device.gestureSupported = supported;
0255 
0256     Device d(&device);
0257     QCOMPARE(d.supportsGesture(), supported);
0258     QCOMPARE(d.property("gestureSupport").toBool(), supported);
0259     QCOMPARE(dbusProperty<bool>(d.sysName(), "gestureSupport"), supported);
0260 }
0261 
0262 void TestLibinputDevice::testNames_data()
0263 {
0264     QTest::addColumn<QByteArray>("name");
0265     QTest::addColumn<QByteArray>("sysName");
0266     QTest::addColumn<QByteArray>("outputName");
0267 
0268     QTest::newRow("empty") << QByteArray() << QByteArrayLiteral("event1") << QByteArray();
0269     QTest::newRow("set") << QByteArrayLiteral("awesome test device") << QByteArrayLiteral("event0") << QByteArrayLiteral("hdmi0");
0270 }
0271 
0272 void TestLibinputDevice::testNames()
0273 {
0274     // this test verifies the various name properties of the Device
0275     QFETCH(QByteArray, name);
0276     QFETCH(QByteArray, sysName);
0277     QFETCH(QByteArray, outputName);
0278     libinput_device device;
0279     device.name = name;
0280     device.sysName = sysName;
0281     device.outputName = outputName;
0282 
0283     Device d(&device);
0284     QCOMPARE(d.name().toUtf8(), name);
0285     QCOMPARE(d.property("name").toString().toUtf8(), name);
0286     QCOMPARE(dbusProperty<QString>(d.sysName(), "name"), name);
0287     QCOMPARE(d.sysName().toUtf8(), sysName);
0288     QCOMPARE(d.property("sysName").toString().toUtf8(), sysName);
0289     QCOMPARE(dbusProperty<QString>(d.sysName(), "sysName"), sysName);
0290     QCOMPARE(d.outputName().toUtf8(), outputName);
0291     QCOMPARE(d.property("outputName").toString().toUtf8(), outputName);
0292     QCOMPARE(dbusProperty<QString>(d.sysName(), "outputName"), outputName);
0293 }
0294 
0295 void TestLibinputDevice::testProduct()
0296 {
0297     // this test verifies the product property
0298     libinput_device device;
0299     device.product = 100u;
0300     Device d(&device);
0301     QCOMPARE(d.product(), 100u);
0302     QCOMPARE(d.property("product").toUInt(), 100u);
0303     QCOMPARE(dbusProperty<quint32>(d.sysName(), "product"), 100u);
0304 }
0305 
0306 void TestLibinputDevice::testVendor()
0307 {
0308     // this test verifies the vendor property
0309     libinput_device device;
0310     device.vendor = 200u;
0311     Device d(&device);
0312     QCOMPARE(d.vendor(), 200u);
0313     QCOMPARE(d.property("vendor").toUInt(), 200u);
0314     QCOMPARE(dbusProperty<quint32>(d.sysName(), "vendor"), 200u);
0315 }
0316 
0317 void TestLibinputDevice::testTapFingerCount()
0318 {
0319     // this test verifies the tap finger count property
0320     libinput_device device;
0321     device.tapFingerCount = 3;
0322     Device d(&device);
0323     QCOMPARE(d.tapFingerCount(), 3);
0324     QCOMPARE(d.property("tapFingerCount").toInt(), 3);
0325     QCOMPARE(dbusProperty<int>(d.sysName(), "tapFingerCount"), 3);
0326 }
0327 
0328 void TestLibinputDevice::testSize_data()
0329 {
0330     QTest::addColumn<QSizeF>("setSize");
0331     QTest::addColumn<int>("returnValue");
0332     QTest::addColumn<QSizeF>("expectedSize");
0333 
0334     QTest::newRow("10/20") << QSizeF(10.5, 20.2) << 0 << QSizeF(10.5, 20.2);
0335     QTest::newRow("failure") << QSizeF(10, 20) << 1 << QSizeF();
0336 }
0337 
0338 void TestLibinputDevice::testSize()
0339 {
0340     // this test verifies that getting the size works correctly including failures
0341     QFETCH(QSizeF, setSize);
0342     QFETCH(int, returnValue);
0343     libinput_device device;
0344     device.deviceSize = setSize;
0345     device.deviceSizeReturnValue = returnValue;
0346 
0347     Device d(&device);
0348     QTEST(d.size(), "expectedSize");
0349     QTEST(d.property("size").toSizeF(), "expectedSize");
0350     QTEST(dbusProperty<QSizeF>(d.sysName(), "size"), "expectedSize");
0351 }
0352 
0353 void TestLibinputDevice::testLeftHandedEnabledByDefault_data()
0354 {
0355     QTest::addColumn<bool>("enabled");
0356 
0357     QTest::newRow("enabled") << true;
0358     QTest::newRow("disabled") << false;
0359 }
0360 
0361 void TestLibinputDevice::testLeftHandedEnabledByDefault()
0362 {
0363     QFETCH(bool, enabled);
0364     libinput_device device;
0365     device.leftHandedEnabledByDefault = enabled;
0366 
0367     Device d(&device);
0368     QCOMPARE(d.leftHandedEnabledByDefault(), enabled);
0369     QCOMPARE(d.property("leftHandedEnabledByDefault").toBool(), enabled);
0370     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHandedEnabledByDefault"), enabled);
0371 }
0372 
0373 void TestLibinputDevice::testTapEnabledByDefault_data()
0374 {
0375     QTest::addColumn<bool>("enabled");
0376 
0377     QTest::newRow("enabled") << true;
0378     QTest::newRow("disabled") << false;
0379 }
0380 
0381 void TestLibinputDevice::testTapEnabledByDefault()
0382 {
0383     QFETCH(bool, enabled);
0384     libinput_device device;
0385     device.tapEnabledByDefault = enabled;
0386 
0387     Device d(&device);
0388     QCOMPARE(d.tapToClickEnabledByDefault(), enabled);
0389     QCOMPARE(d.property("tapToClickEnabledByDefault").toBool(), enabled);
0390     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClickEnabledByDefault"), enabled);
0391 }
0392 
0393 void TestLibinputDevice::testMiddleEmulationEnabledByDefault_data()
0394 {
0395     QTest::addColumn<bool>("enabled");
0396 
0397     QTest::newRow("enabled") << true;
0398     QTest::newRow("disabled") << false;
0399 }
0400 
0401 void TestLibinputDevice::testMiddleEmulationEnabledByDefault()
0402 {
0403     QFETCH(bool, enabled);
0404     libinput_device device;
0405     device.middleEmulationEnabledByDefault = enabled;
0406 
0407     Device d(&device);
0408     QCOMPARE(d.middleEmulationEnabledByDefault(), enabled);
0409     QCOMPARE(d.property("middleEmulationEnabledByDefault").toBool(), enabled);
0410     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulationEnabledByDefault"), enabled);
0411 }
0412 
0413 void TestLibinputDevice::testNaturalScrollEnabledByDefault_data()
0414 {
0415     QTest::addColumn<bool>("enabled");
0416 
0417     QTest::newRow("enabled") << true;
0418     QTest::newRow("disabled") << false;
0419 }
0420 
0421 void TestLibinputDevice::testNaturalScrollEnabledByDefault()
0422 {
0423     QFETCH(bool, enabled);
0424     libinput_device device;
0425     device.naturalScrollEnabledByDefault = enabled;
0426 
0427     Device d(&device);
0428     QCOMPARE(d.naturalScrollEnabledByDefault(), enabled);
0429     QCOMPARE(d.property("naturalScrollEnabledByDefault").toBool(), enabled);
0430     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScrollEnabledByDefault"), enabled);
0431 }
0432 
0433 void TestLibinputDevice::testScrollTwoFingerEnabledByDefault_data()
0434 {
0435     QTest::addColumn<bool>("enabled");
0436 
0437     QTest::newRow("enabled") << true;
0438     QTest::newRow("disabled") << false;
0439 }
0440 
0441 void TestLibinputDevice::testScrollTwoFingerEnabledByDefault()
0442 {
0443     QFETCH(bool, enabled);
0444     libinput_device device;
0445     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0446 
0447     Device d(&device);
0448     QCOMPARE(d.scrollTwoFingerEnabledByDefault(), enabled);
0449     QCOMPARE(d.property("scrollTwoFingerEnabledByDefault").toBool(), enabled);
0450     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFingerEnabledByDefault"), enabled);
0451 }
0452 
0453 void TestLibinputDevice::testScrollEdgeEnabledByDefault_data()
0454 {
0455     QTest::addColumn<bool>("enabled");
0456 
0457     QTest::newRow("enabled") << true;
0458     QTest::newRow("disabled") << false;
0459 }
0460 
0461 void TestLibinputDevice::testScrollEdgeEnabledByDefault()
0462 {
0463     QFETCH(bool, enabled);
0464     libinput_device device;
0465     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0466 
0467     Device d(&device);
0468     QCOMPARE(d.scrollEdgeEnabledByDefault(), enabled);
0469     QCOMPARE(d.property("scrollEdgeEnabledByDefault").toBool(), enabled);
0470     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdgeEnabledByDefault"), enabled);
0471 }
0472 
0473 void TestLibinputDevice::testDefaultPointerAccelerationProfileFlat_data()
0474 {
0475     QTest::addColumn<bool>("enabled");
0476 
0477     QTest::newRow("enabled") << true;
0478     QTest::newRow("disabled") << false;
0479 }
0480 
0481 void TestLibinputDevice::testDefaultPointerAccelerationProfileFlat()
0482 {
0483     QFETCH(bool, enabled);
0484     libinput_device device;
0485     device.defaultPointerAccelerationProfile = enabled ? LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT : LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
0486 
0487     Device d(&device);
0488     QCOMPARE(d.defaultPointerAccelerationProfileFlat(), enabled);
0489     QCOMPARE(d.property("defaultPointerAccelerationProfileFlat").toBool(), enabled);
0490     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultPointerAccelerationProfileFlat"), enabled);
0491 }
0492 
0493 void TestLibinputDevice::testDefaultPointerAccelerationProfileAdaptive_data()
0494 {
0495     QTest::addColumn<bool>("enabled");
0496 
0497     QTest::newRow("enabled") << true;
0498     QTest::newRow("disabled") << false;
0499 }
0500 
0501 void TestLibinputDevice::testDefaultPointerAccelerationProfileAdaptive()
0502 {
0503     QFETCH(bool, enabled);
0504     libinput_device device;
0505     device.defaultPointerAccelerationProfile = enabled ? LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE : LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
0506 
0507     Device d(&device);
0508     QCOMPARE(d.defaultPointerAccelerationProfileAdaptive(), enabled);
0509     QCOMPARE(d.property("defaultPointerAccelerationProfileAdaptive").toBool(), enabled);
0510     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultPointerAccelerationProfileAdaptive"), enabled);
0511 }
0512 
0513 void TestLibinputDevice::testDefaultClickMethodAreas_data()
0514 {
0515     QTest::addColumn<bool>("enabled");
0516 
0517     QTest::addRow("enabled") << true;
0518     QTest::addRow("disabled") << false;
0519 }
0520 
0521 void TestLibinputDevice::testDefaultClickMethodAreas()
0522 {
0523     QFETCH(bool, enabled);
0524     libinput_device device;
0525     device.defaultClickMethod = enabled ? LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS : LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
0526 
0527     Device d(&device);
0528     QCOMPARE(d.defaultClickMethodAreas(), enabled);
0529     QCOMPARE(d.property("defaultClickMethodAreas").toBool(), enabled);
0530     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultClickMethodAreas"), enabled);
0531 }
0532 
0533 void TestLibinputDevice::testDefaultClickMethodClickfinger_data()
0534 {
0535     QTest::addColumn<bool>("enabled");
0536 
0537     QTest::addRow("enabled") << true;
0538     QTest::addRow("disabled") << false;
0539 }
0540 
0541 void TestLibinputDevice::testDefaultClickMethodClickfinger()
0542 {
0543     QFETCH(bool, enabled);
0544     libinput_device device;
0545     device.defaultClickMethod = enabled ? LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER : LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
0546 
0547     Device d(&device);
0548     QCOMPARE(d.defaultClickMethodClickfinger(), enabled);
0549     QCOMPARE(d.property("defaultClickMethodClickfinger").toBool(), enabled);
0550     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultClickMethodClickfinger"), enabled);
0551 }
0552 
0553 void TestLibinputDevice::testScrollOnButtonDownEnabledByDefault_data()
0554 {
0555     QTest::addColumn<bool>("enabled");
0556 
0557     QTest::newRow("enabled") << true;
0558     QTest::newRow("disabled") << false;
0559 }
0560 
0561 void TestLibinputDevice::testScrollOnButtonDownEnabledByDefault()
0562 {
0563     QFETCH(bool, enabled);
0564     libinput_device device;
0565     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0566 
0567     Device d(&device);
0568     QCOMPARE(d.scrollOnButtonDownEnabledByDefault(), enabled);
0569     QCOMPARE(d.property("scrollOnButtonDownEnabledByDefault").toBool(), enabled);
0570     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDownEnabledByDefault"), enabled);
0571 }
0572 
0573 void TestLibinputDevice::testDefaultScrollButton_data()
0574 {
0575     QTest::addColumn<quint32>("button");
0576 
0577     QTest::newRow("0") << 0u;
0578     QTest::newRow("BTN_LEFT") << quint32(BTN_LEFT);
0579     QTest::newRow("BTN_RIGHT") << quint32(BTN_RIGHT);
0580     QTest::newRow("BTN_MIDDLE") << quint32(BTN_MIDDLE);
0581     QTest::newRow("BTN_SIDE") << quint32(BTN_SIDE);
0582     QTest::newRow("BTN_EXTRA") << quint32(BTN_EXTRA);
0583     QTest::newRow("BTN_FORWARD") << quint32(BTN_FORWARD);
0584     QTest::newRow("BTN_BACK") << quint32(BTN_BACK);
0585     QTest::newRow("BTN_TASK") << quint32(BTN_TASK);
0586 }
0587 
0588 void TestLibinputDevice::testDefaultScrollButton()
0589 {
0590     libinput_device device;
0591     QFETCH(quint32, button);
0592     device.defaultScrollButton = button;
0593 
0594     Device d(&device);
0595     QCOMPARE(d.defaultScrollButton(), button);
0596     QCOMPARE(d.property("defaultScrollButton").value<quint32>(), button);
0597     QCOMPARE(dbusProperty<quint32>(d.sysName(), "defaultScrollButton"), button);
0598 }
0599 
0600 void TestLibinputDevice::testSupportsDisableWhileTyping_data()
0601 {
0602     QTest::addColumn<bool>("enabled");
0603 
0604     QTest::newRow("enabled") << true;
0605     QTest::newRow("disabled") << false;
0606 }
0607 
0608 void TestLibinputDevice::testSupportsDisableWhileTyping()
0609 {
0610     QFETCH(bool, enabled);
0611     libinput_device device;
0612     device.supportsDisableWhileTyping = enabled;
0613 
0614     Device d(&device);
0615     QCOMPARE(d.supportsDisableWhileTyping(), enabled);
0616     QCOMPARE(d.property("supportsDisableWhileTyping").toBool(), enabled);
0617     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableWhileTyping"), enabled);
0618 }
0619 
0620 void TestLibinputDevice::testSupportsPointerAcceleration_data()
0621 {
0622     QTest::addColumn<bool>("enabled");
0623 
0624     QTest::newRow("enabled") << true;
0625     QTest::newRow("disabled") << false;
0626 }
0627 
0628 void TestLibinputDevice::testSupportsPointerAcceleration()
0629 {
0630     QFETCH(bool, enabled);
0631     libinput_device device;
0632     device.supportsPointerAcceleration = enabled;
0633 
0634     Device d(&device);
0635     QCOMPARE(d.supportsPointerAcceleration(), enabled);
0636     QCOMPARE(d.property("supportsPointerAcceleration").toBool(), enabled);
0637     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsPointerAcceleration"), enabled);
0638 }
0639 
0640 void TestLibinputDevice::testSupportsLeftHanded_data()
0641 {
0642     QTest::addColumn<bool>("enabled");
0643 
0644     QTest::newRow("enabled") << true;
0645     QTest::newRow("disabled") << false;
0646 }
0647 
0648 void TestLibinputDevice::testSupportsLeftHanded()
0649 {
0650     QFETCH(bool, enabled);
0651     libinput_device device;
0652     device.supportsLeftHanded = enabled;
0653 
0654     Device d(&device);
0655     QCOMPARE(d.supportsLeftHanded(), enabled);
0656     QCOMPARE(d.property("supportsLeftHanded").toBool(), enabled);
0657     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsLeftHanded"), enabled);
0658 }
0659 
0660 void TestLibinputDevice::testSupportsCalibrationMatrix_data()
0661 {
0662     QTest::addColumn<bool>("enabled");
0663 
0664     QTest::newRow("enabled") << true;
0665     QTest::newRow("disabled") << false;
0666 }
0667 
0668 void TestLibinputDevice::testSupportsCalibrationMatrix()
0669 {
0670     QFETCH(bool, enabled);
0671     libinput_device device;
0672     device.supportsCalibrationMatrix = enabled;
0673 
0674     Device d(&device);
0675     QCOMPARE(d.supportsCalibrationMatrix(), enabled);
0676     QCOMPARE(d.property("supportsCalibrationMatrix").toBool(), enabled);
0677     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsCalibrationMatrix"), enabled);
0678 }
0679 
0680 void TestLibinputDevice::testSupportsDisableEvents_data()
0681 {
0682     QTest::addColumn<bool>("enabled");
0683 
0684     QTest::newRow("enabled") << true;
0685     QTest::newRow("disabled") << false;
0686 }
0687 
0688 void TestLibinputDevice::testSupportsDisableEvents()
0689 {
0690     QFETCH(bool, enabled);
0691     libinput_device device;
0692     device.supportsDisableEvents = enabled;
0693 
0694     Device d(&device);
0695     QCOMPARE(d.supportsDisableEvents(), enabled);
0696     QCOMPARE(d.property("supportsDisableEvents").toBool(), enabled);
0697     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableEvents"), enabled);
0698 }
0699 
0700 void TestLibinputDevice::testSupportsDisableEventsOnExternalMouse_data()
0701 {
0702     QTest::addColumn<bool>("enabled");
0703 
0704     QTest::newRow("enabled") << true;
0705     QTest::newRow("disabled") << false;
0706 }
0707 
0708 void TestLibinputDevice::testSupportsDisableEventsOnExternalMouse()
0709 {
0710     QFETCH(bool, enabled);
0711     libinput_device device;
0712     device.supportsDisableEventsOnExternalMouse = enabled;
0713 
0714     Device d(&device);
0715     QCOMPARE(d.supportsDisableEventsOnExternalMouse(), enabled);
0716     QCOMPARE(d.property("supportsDisableEventsOnExternalMouse").toBool(), enabled);
0717     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableEventsOnExternalMouse"), enabled);
0718 }
0719 
0720 void TestLibinputDevice::testSupportsMiddleEmulation_data()
0721 {
0722     QTest::addColumn<bool>("enabled");
0723 
0724     QTest::newRow("enabled") << true;
0725     QTest::newRow("disabled") << false;
0726 }
0727 
0728 void TestLibinputDevice::testSupportsMiddleEmulation()
0729 {
0730     QFETCH(bool, enabled);
0731     libinput_device device;
0732     device.supportsMiddleEmulation = enabled;
0733 
0734     Device d(&device);
0735     QCOMPARE(d.supportsMiddleEmulation(), enabled);
0736     QCOMPARE(d.property("supportsMiddleEmulation").toBool(), enabled);
0737     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsMiddleEmulation"), enabled);
0738 }
0739 
0740 void TestLibinputDevice::testSupportsNaturalScroll_data()
0741 {
0742     QTest::addColumn<bool>("enabled");
0743 
0744     QTest::newRow("enabled") << true;
0745     QTest::newRow("disabled") << false;
0746 }
0747 
0748 void TestLibinputDevice::testSupportsNaturalScroll()
0749 {
0750     QFETCH(bool, enabled);
0751     libinput_device device;
0752     device.supportsNaturalScroll = enabled;
0753 
0754     Device d(&device);
0755     QCOMPARE(d.supportsNaturalScroll(), enabled);
0756     QCOMPARE(d.property("supportsNaturalScroll").toBool(), enabled);
0757     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsNaturalScroll"), enabled);
0758 }
0759 
0760 void TestLibinputDevice::testSupportsScrollTwoFinger_data()
0761 {
0762     QTest::addColumn<bool>("enabled");
0763 
0764     QTest::newRow("enabled") << true;
0765     QTest::newRow("disabled") << false;
0766 }
0767 
0768 void TestLibinputDevice::testSupportsScrollTwoFinger()
0769 {
0770     QFETCH(bool, enabled);
0771     libinput_device device;
0772     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0773 
0774     Device d(&device);
0775     QCOMPARE(d.supportsScrollTwoFinger(), enabled);
0776     QCOMPARE(d.property("supportsScrollTwoFinger").toBool(), enabled);
0777     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollTwoFinger"), enabled);
0778 }
0779 
0780 void TestLibinputDevice::testSupportsScrollEdge_data()
0781 {
0782     QTest::addColumn<bool>("enabled");
0783 
0784     QTest::newRow("enabled") << true;
0785     QTest::newRow("disabled") << false;
0786 }
0787 
0788 void TestLibinputDevice::testSupportsScrollEdge()
0789 {
0790     QFETCH(bool, enabled);
0791     libinput_device device;
0792     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0793 
0794     Device d(&device);
0795     QCOMPARE(d.supportsScrollEdge(), enabled);
0796     QCOMPARE(d.property("supportsScrollEdge").toBool(), enabled);
0797     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollEdge"), enabled);
0798 }
0799 
0800 void TestLibinputDevice::testSupportsScrollOnButtonDown_data()
0801 {
0802     QTest::addColumn<bool>("enabled");
0803 
0804     QTest::newRow("enabled") << true;
0805     QTest::newRow("disabled") << false;
0806 }
0807 
0808 void TestLibinputDevice::testSupportsScrollOnButtonDown()
0809 {
0810     QFETCH(bool, enabled);
0811     libinput_device device;
0812     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
0813 
0814     Device d(&device);
0815     QCOMPARE(d.supportsScrollOnButtonDown(), enabled);
0816     QCOMPARE(d.property("supportsScrollOnButtonDown").toBool(), enabled);
0817     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollOnButtonDown"), enabled);
0818 }
0819 
0820 void TestLibinputDevice::testDefaultPointerAcceleration_data()
0821 {
0822     QTest::addColumn<qreal>("accel");
0823 
0824     QTest::newRow("-1.0") << -1.0;
0825     QTest::newRow("-0.5") << -0.5;
0826     QTest::newRow("0.0") << 0.0;
0827     QTest::newRow("0.3") << 0.3;
0828     QTest::newRow("1.0") << 1.0;
0829 }
0830 
0831 void TestLibinputDevice::testDefaultPointerAcceleration()
0832 {
0833     QFETCH(qreal, accel);
0834     libinput_device device;
0835     device.defaultPointerAcceleration = accel;
0836 
0837     Device d(&device);
0838     QCOMPARE(d.defaultPointerAcceleration(), accel);
0839     QCOMPARE(d.property("defaultPointerAcceleration").toReal(), accel);
0840     QCOMPARE(dbusProperty<qreal>(d.sysName(), "defaultPointerAcceleration"), accel);
0841 }
0842 
0843 void TestLibinputDevice::testPointerAcceleration_data()
0844 {
0845     QTest::addColumn<bool>("supported");
0846     QTest::addColumn<bool>("setShouldFail");
0847     QTest::addColumn<qreal>("accel");
0848     QTest::addColumn<qreal>("setAccel");
0849     QTest::addColumn<qreal>("expectedAccel");
0850     QTest::addColumn<bool>("expectedChanged");
0851 
0852     QTest::newRow("-1 -> 2.0") << true << false << -1.0 << 2.0 << 1.0 << true;
0853     QTest::newRow("0 -> -1.0") << true << false << 0.0 << -1.0 << -1.0 << true;
0854     QTest::newRow("1 -> 1") << true << false << 1.0 << 1.0 << 1.0 << false;
0855     QTest::newRow("unsupported") << false << false << 0.0 << 1.0 << 0.0 << false;
0856     QTest::newRow("set fails") << true << true << -1.0 << 1.0 << -1.0 << false;
0857 }
0858 
0859 void TestLibinputDevice::testPointerAcceleration()
0860 {
0861     QFETCH(bool, supported);
0862     QFETCH(bool, setShouldFail);
0863     QFETCH(qreal, accel);
0864     libinput_device device;
0865     device.supportsPointerAcceleration = supported;
0866     device.pointerAcceleration = accel;
0867     device.setPointerAccelerationReturnValue = setShouldFail;
0868 
0869     Device d(&device);
0870     QCOMPARE(d.pointerAcceleration(), accel);
0871     QCOMPARE(d.property("pointerAcceleration").toReal(), accel);
0872     QCOMPARE(dbusProperty<qreal>(d.sysName(), "pointerAcceleration"), accel);
0873 
0874     QSignalSpy pointerAccelChangedSpy(&d, &Device::pointerAccelerationChanged);
0875     QFETCH(qreal, setAccel);
0876     d.setPointerAcceleration(setAccel);
0877     QTEST(d.pointerAcceleration(), "expectedAccel");
0878     QTEST(!pointerAccelChangedSpy.isEmpty(), "expectedChanged");
0879     QTEST(dbusProperty<qreal>(d.sysName(), "pointerAcceleration"), "expectedAccel");
0880 }
0881 
0882 void TestLibinputDevice::testLeftHanded_data()
0883 {
0884     QTest::addColumn<bool>("supported");
0885     QTest::addColumn<bool>("setShouldFail");
0886     QTest::addColumn<bool>("initValue");
0887     QTest::addColumn<bool>("setValue");
0888     QTest::addColumn<bool>("expectedValue");
0889 
0890     QTest::newRow("unsupported/true") << false << false << true << false << false;
0891     QTest::newRow("unsupported/false") << false << false << false << true << false;
0892     QTest::newRow("true -> false") << true << false << true << false << false;
0893     QTest::newRow("false -> true") << true << false << false << true << true;
0894     QTest::newRow("set fails") << true << true << true << false << true;
0895     QTest::newRow("true -> true") << true << false << true << true << true;
0896     QTest::newRow("false -> false") << true << false << false << false << false;
0897 }
0898 
0899 void TestLibinputDevice::testLeftHanded()
0900 {
0901     QFETCH(bool, supported);
0902     QFETCH(bool, setShouldFail);
0903     QFETCH(bool, initValue);
0904     libinput_device device;
0905     device.supportsLeftHanded = supported;
0906     device.leftHanded = initValue;
0907     device.setLeftHandedReturnValue = setShouldFail;
0908 
0909     Device d(&device);
0910     QCOMPARE(d.isLeftHanded(), supported && initValue);
0911     QCOMPARE(d.property("leftHanded").toBool(), supported && initValue);
0912     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHanded"), supported && initValue);
0913 
0914     QSignalSpy leftHandedChangedSpy(&d, &Device::leftHandedChanged);
0915     QFETCH(bool, setValue);
0916     d.setLeftHanded(setValue);
0917     QFETCH(bool, expectedValue);
0918     QCOMPARE(d.isLeftHanded(), expectedValue);
0919     QCOMPARE(leftHandedChangedSpy.isEmpty(), (supported && initValue) == expectedValue);
0920     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHanded"), expectedValue);
0921 }
0922 
0923 void TestLibinputDevice::testSupportedButtons_data()
0924 {
0925     QTest::addColumn<bool>("isPointer");
0926     QTest::addColumn<Qt::MouseButtons>("setButtons");
0927     QTest::addColumn<Qt::MouseButtons>("expectedButtons");
0928 
0929     QTest::newRow("left") << true << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons(Qt::LeftButton);
0930     QTest::newRow("right") << true << Qt::MouseButtons(Qt::RightButton) << Qt::MouseButtons(Qt::RightButton);
0931     QTest::newRow("middle") << true << Qt::MouseButtons(Qt::MiddleButton) << Qt::MouseButtons(Qt::MiddleButton);
0932     QTest::newRow("extra1") << true << Qt::MouseButtons(Qt::ExtraButton1) << Qt::MouseButtons(Qt::ExtraButton1);
0933     QTest::newRow("extra2") << true << Qt::MouseButtons(Qt::ExtraButton2) << Qt::MouseButtons(Qt::ExtraButton2);
0934     QTest::newRow("back") << true << Qt::MouseButtons(Qt::BackButton) << Qt::MouseButtons(Qt::BackButton);
0935     QTest::newRow("forward") << true << Qt::MouseButtons(Qt::ForwardButton) << Qt::MouseButtons(Qt::ForwardButton);
0936     QTest::newRow("task") << true << Qt::MouseButtons(Qt::TaskButton) << Qt::MouseButtons(Qt::TaskButton);
0937 
0938     QTest::newRow("no pointer/left") << false << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons();
0939     QTest::newRow("no pointer/right") << false << Qt::MouseButtons(Qt::RightButton) << Qt::MouseButtons();
0940     QTest::newRow("no pointer/middle") << false << Qt::MouseButtons(Qt::MiddleButton) << Qt::MouseButtons();
0941     QTest::newRow("no pointer/extra1") << false << Qt::MouseButtons(Qt::ExtraButton1) << Qt::MouseButtons();
0942     QTest::newRow("no pointer/extra2") << false << Qt::MouseButtons(Qt::ExtraButton2) << Qt::MouseButtons();
0943     QTest::newRow("no pointer/back") << false << Qt::MouseButtons(Qt::BackButton) << Qt::MouseButtons();
0944     QTest::newRow("no pointer/forward") << false << Qt::MouseButtons(Qt::ForwardButton) << Qt::MouseButtons();
0945     QTest::newRow("no pointer/task") << false << Qt::MouseButtons(Qt::TaskButton) << Qt::MouseButtons();
0946 
0947     QTest::newRow("all") << true
0948                          << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton | Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::BackButton | Qt::ForwardButton | Qt::TaskButton)
0949                          << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton | Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::BackButton | Qt::ForwardButton | Qt::TaskButton);
0950 }
0951 
0952 void TestLibinputDevice::testSupportedButtons()
0953 {
0954     libinput_device device;
0955     QFETCH(bool, isPointer);
0956     device.pointer = isPointer;
0957     QFETCH(Qt::MouseButtons, setButtons);
0958     device.supportedButtons = setButtons;
0959 
0960     Device d(&device);
0961     QCOMPARE(d.isPointer(), isPointer);
0962     QTEST(d.supportedButtons(), "expectedButtons");
0963     QTEST(Qt::MouseButtons(dbusProperty<int>(d.sysName(), "supportedButtons")), "expectedButtons");
0964 }
0965 
0966 void TestLibinputDevice::testAlphaNumericKeyboard_data()
0967 {
0968     QTest::addColumn<QVector<quint32>>("supportedKeys");
0969     QTest::addColumn<bool>("isAlpha");
0970 
0971     QVector<quint32> keys;
0972 
0973     for (int i = KEY_1; i <= KEY_0; i++) {
0974         keys << i;
0975         QByteArray row = QByteArrayLiteral("number");
0976         row.append(QByteArray::number(i));
0977         QTest::newRow(row.constData()) << keys << false;
0978     }
0979     for (int i = KEY_Q; i <= KEY_P; i++) {
0980         keys << i;
0981         QByteArray row = QByteArrayLiteral("alpha");
0982         row.append(QByteArray::number(i));
0983         QTest::newRow(row.constData()) << keys << false;
0984     }
0985     for (int i = KEY_A; i <= KEY_L; i++) {
0986         keys << i;
0987         QByteArray row = QByteArrayLiteral("alpha");
0988         row.append(QByteArray::number(i));
0989         QTest::newRow(row.constData()) << keys << false;
0990     }
0991     for (int i = KEY_Z; i < KEY_M; i++) {
0992         keys << i;
0993         QByteArray row = QByteArrayLiteral("alpha");
0994         row.append(QByteArray::number(i));
0995         QTest::newRow(row.constData()) << keys << false;
0996     }
0997     // adding a different key should not result in it becoming alphanumeric keyboard
0998     keys << KEY_SEMICOLON;
0999     QTest::newRow("semicolon") << keys << false;
1000 
1001     // last but not least the M which should turn everything on
1002     keys << KEY_M;
1003     QTest::newRow("alphanumeric") << keys << true;
1004 }
1005 
1006 void TestLibinputDevice::testAlphaNumericKeyboard()
1007 {
1008     QFETCH(QVector<quint32>, supportedKeys);
1009     libinput_device device;
1010     device.keyboard = true;
1011     device.keys = supportedKeys;
1012 
1013     Device d(&device);
1014     QCOMPARE(d.isKeyboard(), true);
1015     QTEST(d.isAlphaNumericKeyboard(), "isAlpha");
1016     QTEST(dbusProperty<bool>(d.sysName(), "alphaNumericKeyboard"), "isAlpha");
1017 }
1018 
1019 void TestLibinputDevice::testEnabled_data()
1020 {
1021     QTest::addColumn<bool>("supported");
1022     QTest::addColumn<bool>("setShouldFail");
1023     QTest::addColumn<bool>("initValue");
1024     QTest::addColumn<bool>("setValue");
1025     QTest::addColumn<bool>("expectedValue");
1026 
1027     QTest::newRow("unsupported/true") << false << false << true << false << true;
1028     QTest::newRow("unsupported/false") << false << false << false << true << true;
1029     QTest::newRow("true -> false") << true << false << true << false << false;
1030     QTest::newRow("false -> true") << true << false << false << true << true;
1031     QTest::newRow("set fails") << true << true << true << false << true;
1032     QTest::newRow("true -> true") << true << false << true << true << true;
1033     QTest::newRow("false -> false") << true << false << false << false << false;
1034 }
1035 
1036 void TestLibinputDevice::testEnabled()
1037 {
1038     libinput_device device;
1039     QFETCH(bool, supported);
1040     QFETCH(bool, setShouldFail);
1041     QFETCH(bool, initValue);
1042     device.supportsDisableEvents = supported;
1043     device.enabled = initValue;
1044     device.setEnableModeReturnValue = setShouldFail;
1045 
1046     Device d(&device);
1047     QCOMPARE(d.isEnabled(), !supported || initValue);
1048     QCOMPARE(d.property("enabled").toBool(), !supported || initValue);
1049     QCOMPARE(dbusProperty<bool>(d.sysName(), "enabled"), !supported || initValue);
1050 
1051     QSignalSpy enabledChangedSpy(&d, &Device::enabledChanged);
1052     QFETCH(bool, setValue);
1053     d.setEnabled(setValue);
1054     QFETCH(bool, expectedValue);
1055     QCOMPARE(d.isEnabled(), expectedValue);
1056 
1057     QCOMPARE(dbusProperty<bool>(d.sysName(), "enabled"), expectedValue);
1058 }
1059 
1060 void TestLibinputDevice::testTapToClick_data()
1061 {
1062     QTest::addColumn<int>("fingerCount");
1063     QTest::addColumn<bool>("initValue");
1064     QTest::addColumn<bool>("setValue");
1065     QTest::addColumn<bool>("setShouldFail");
1066     QTest::addColumn<bool>("expectedValue");
1067 
1068     QTest::newRow("unsupported") << 0 << false << true << true << false;
1069     QTest::newRow("true -> false") << 1 << true << false << false << false;
1070     QTest::newRow("false -> true") << 2 << false << true << false << true;
1071     QTest::newRow("set fails") << 3 << true << false << true << true;
1072     QTest::newRow("true -> true") << 2 << true << true << false << true;
1073     QTest::newRow("false -> false") << 1 << false << false << false << false;
1074 }
1075 
1076 void TestLibinputDevice::testTapToClick()
1077 {
1078     libinput_device device;
1079     QFETCH(int, fingerCount);
1080     QFETCH(bool, initValue);
1081     QFETCH(bool, setShouldFail);
1082     device.tapFingerCount = fingerCount;
1083     device.tapToClick = initValue;
1084     device.setTapToClickReturnValue = setShouldFail;
1085 
1086     Device d(&device);
1087     QCOMPARE(d.tapFingerCount(), fingerCount);
1088     QCOMPARE(d.isTapToClick(), initValue);
1089     QCOMPARE(d.property("tapToClick").toBool(), initValue);
1090     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClick"), initValue);
1091 
1092     QSignalSpy tapToClickChangedSpy(&d, &Device::tapToClickChanged);
1093     QFETCH(bool, setValue);
1094     d.setTapToClick(setValue);
1095     QFETCH(bool, expectedValue);
1096     QCOMPARE(d.isTapToClick(), expectedValue);
1097     QCOMPARE(tapToClickChangedSpy.isEmpty(), initValue == expectedValue);
1098     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClick"), expectedValue);
1099 }
1100 
1101 void TestLibinputDevice::testTapAndDragEnabledByDefault_data()
1102 {
1103     QTest::addColumn<bool>("enabled");
1104 
1105     QTest::newRow("enabled") << true;
1106     QTest::newRow("disabled") << false;
1107 }
1108 
1109 void TestLibinputDevice::testTapAndDragEnabledByDefault()
1110 {
1111     QFETCH(bool, enabled);
1112     libinput_device device;
1113     device.tapAndDragEnabledByDefault = enabled;
1114 
1115     Device d(&device);
1116     QCOMPARE(d.tapAndDragEnabledByDefault(), enabled);
1117     QCOMPARE(d.property("tapAndDragEnabledByDefault").toBool(), enabled);
1118     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDragEnabledByDefault"), enabled);
1119 }
1120 
1121 void TestLibinputDevice::testTapAndDrag_data()
1122 {
1123     QTest::addColumn<bool>("initValue");
1124     QTest::addColumn<bool>("setValue");
1125     QTest::addColumn<bool>("setShouldFail");
1126     QTest::addColumn<bool>("expectedValue");
1127 
1128     QTest::newRow("true -> false") << true << false << false << false;
1129     QTest::newRow("false -> true") << false << true << false << true;
1130     QTest::newRow("set fails") << true << false << true << true;
1131     QTest::newRow("true -> true") << true << true << false << true;
1132     QTest::newRow("false -> false") << false << false << false << false;
1133 }
1134 
1135 void TestLibinputDevice::testTapAndDrag()
1136 {
1137     libinput_device device;
1138     QFETCH(bool, initValue);
1139     QFETCH(bool, setShouldFail);
1140     device.tapAndDrag = initValue;
1141     device.setTapAndDragReturnValue = setShouldFail;
1142 
1143     Device d(&device);
1144     QCOMPARE(d.isTapAndDrag(), initValue);
1145     QCOMPARE(d.property("tapAndDrag").toBool(), initValue);
1146     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDrag"), initValue);
1147 
1148     QSignalSpy tapAndDragChangedSpy(&d, &Device::tapAndDragChanged);
1149     QFETCH(bool, setValue);
1150     d.setTapAndDrag(setValue);
1151     QFETCH(bool, expectedValue);
1152     QCOMPARE(d.isTapAndDrag(), expectedValue);
1153     QCOMPARE(tapAndDragChangedSpy.isEmpty(), initValue == expectedValue);
1154     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDrag"), expectedValue);
1155 }
1156 
1157 void TestLibinputDevice::testTapDragLockEnabledByDefault_data()
1158 {
1159     QTest::addColumn<bool>("enabled");
1160 
1161     QTest::newRow("enabled") << true;
1162     QTest::newRow("disabled") << false;
1163 }
1164 
1165 void TestLibinputDevice::testTapDragLockEnabledByDefault()
1166 {
1167     QFETCH(bool, enabled);
1168     libinput_device device;
1169     device.tapDragLockEnabledByDefault = enabled;
1170 
1171     Device d(&device);
1172     QCOMPARE(d.tapDragLockEnabledByDefault(), enabled);
1173     QCOMPARE(d.property("tapDragLockEnabledByDefault").toBool(), enabled);
1174     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLockEnabledByDefault"), enabled);
1175 }
1176 
1177 void TestLibinputDevice::testTapDragLock_data()
1178 {
1179     QTest::addColumn<bool>("initValue");
1180     QTest::addColumn<bool>("setValue");
1181     QTest::addColumn<bool>("setShouldFail");
1182     QTest::addColumn<bool>("expectedValue");
1183 
1184     QTest::newRow("true -> false") << true << false << false << false;
1185     QTest::newRow("false -> true") << false << true << false << true;
1186     QTest::newRow("set fails") << true << false << true << true;
1187     QTest::newRow("true -> true") << true << true << false << true;
1188     QTest::newRow("false -> false") << false << false << false << false;
1189 }
1190 
1191 void TestLibinputDevice::testTapDragLock()
1192 {
1193     libinput_device device;
1194     QFETCH(bool, initValue);
1195     QFETCH(bool, setShouldFail);
1196     device.tapDragLock = initValue;
1197     device.setTapDragLockReturnValue = setShouldFail;
1198 
1199     Device d(&device);
1200     QCOMPARE(d.isTapDragLock(), initValue);
1201     QCOMPARE(d.property("tapDragLock").toBool(), initValue);
1202     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLock"), initValue);
1203 
1204     QSignalSpy tapDragLockChangedSpy(&d, &Device::tapDragLockChanged);
1205     QFETCH(bool, setValue);
1206     d.setTapDragLock(setValue);
1207     QFETCH(bool, expectedValue);
1208     QCOMPARE(d.isTapDragLock(), expectedValue);
1209     QCOMPARE(tapDragLockChangedSpy.isEmpty(), initValue == expectedValue);
1210     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLock"), expectedValue);
1211 }
1212 
1213 void TestLibinputDevice::testMiddleEmulation_data()
1214 {
1215     QTest::addColumn<bool>("initValue");
1216     QTest::addColumn<bool>("setValue");
1217     QTest::addColumn<bool>("setShouldFail");
1218     QTest::addColumn<bool>("expectedValue");
1219     QTest::addColumn<bool>("supportsMiddleButton");
1220 
1221     QTest::newRow("true -> false") << true << false << false << false << true;
1222     QTest::newRow("false -> true") << false << true << false << true << true;
1223     QTest::newRow("set fails") << true << false << true << true << true;
1224     QTest::newRow("true -> true") << true << true << false << true << true;
1225     QTest::newRow("false -> false") << false << false << false << false << true;
1226 
1227     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1228 }
1229 
1230 void TestLibinputDevice::testMiddleEmulation()
1231 {
1232     libinput_device device;
1233     QFETCH(bool, initValue);
1234     QFETCH(bool, setShouldFail);
1235     QFETCH(bool, supportsMiddleButton);
1236     device.supportsMiddleEmulation = supportsMiddleButton;
1237     device.middleEmulation = initValue;
1238     device.setMiddleEmulationReturnValue = setShouldFail;
1239 
1240     Device d(&device);
1241     QCOMPARE(d.isMiddleEmulation(), initValue);
1242     QCOMPARE(d.property("middleEmulation").toBool(), initValue);
1243     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulation"), initValue);
1244 
1245     QSignalSpy middleEmulationChangedSpy(&d, &Device::middleEmulationChanged);
1246     QFETCH(bool, setValue);
1247     d.setMiddleEmulation(setValue);
1248     QFETCH(bool, expectedValue);
1249     QCOMPARE(d.isMiddleEmulation(), expectedValue);
1250     QCOMPARE(d.property("middleEmulation").toBool(), expectedValue);
1251     QCOMPARE(middleEmulationChangedSpy.isEmpty(), initValue == expectedValue);
1252     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulation"), expectedValue);
1253 }
1254 
1255 void TestLibinputDevice::testNaturalScroll_data()
1256 {
1257     QTest::addColumn<bool>("initValue");
1258     QTest::addColumn<bool>("setValue");
1259     QTest::addColumn<bool>("setShouldFail");
1260     QTest::addColumn<bool>("expectedValue");
1261     QTest::addColumn<bool>("supportsNaturalScroll");
1262 
1263     QTest::newRow("true -> false") << true << false << false << false << true;
1264     QTest::newRow("false -> true") << false << true << false << true << true;
1265     QTest::newRow("set fails") << true << false << true << true << true;
1266     QTest::newRow("true -> true") << true << true << false << true << true;
1267     QTest::newRow("false -> false") << false << false << false << false << true;
1268 
1269     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1270 }
1271 
1272 void TestLibinputDevice::testNaturalScroll()
1273 {
1274     libinput_device device;
1275     QFETCH(bool, initValue);
1276     QFETCH(bool, setShouldFail);
1277     QFETCH(bool, supportsNaturalScroll);
1278     device.supportsNaturalScroll = supportsNaturalScroll;
1279     device.naturalScroll = initValue;
1280     device.setNaturalScrollReturnValue = setShouldFail;
1281 
1282     Device d(&device);
1283     QCOMPARE(d.isNaturalScroll(), initValue);
1284     QCOMPARE(d.property("naturalScroll").toBool(), initValue);
1285     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScroll"), initValue);
1286 
1287     QSignalSpy naturalScrollChangedSpy(&d, &Device::naturalScrollChanged);
1288     QFETCH(bool, setValue);
1289     d.setNaturalScroll(setValue);
1290     QFETCH(bool, expectedValue);
1291     QCOMPARE(d.isNaturalScroll(), expectedValue);
1292     QCOMPARE(d.property("naturalScroll").toBool(), expectedValue);
1293     QCOMPARE(naturalScrollChangedSpy.isEmpty(), initValue == expectedValue);
1294     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScroll"), expectedValue);
1295 }
1296 
1297 void TestLibinputDevice::testScrollFactor()
1298 {
1299     libinput_device device;
1300 
1301     qreal initValue = 1.0;
1302 
1303     Device d(&device);
1304     QCOMPARE(d.scrollFactor(), initValue);
1305     QCOMPARE(d.property("scrollFactor").toReal(), initValue);
1306     QCOMPARE(dbusProperty<qreal>(d.sysName(), "scrollFactor"), initValue);
1307 
1308     QSignalSpy scrollFactorChangedSpy(&d, &Device::scrollFactorChanged);
1309 
1310     qreal expectedValue = 2.0;
1311 
1312     d.setScrollFactor(expectedValue);
1313     QCOMPARE(d.scrollFactor(), expectedValue);
1314     QCOMPARE(d.property("scrollFactor").toReal(), expectedValue);
1315     QCOMPARE(scrollFactorChangedSpy.isEmpty(), false);
1316     QCOMPARE(dbusProperty<qreal>(d.sysName(), "scrollFactor"), expectedValue);
1317 }
1318 
1319 void TestLibinputDevice::testScrollTwoFinger_data()
1320 {
1321     QTest::addColumn<bool>("initValue");
1322     QTest::addColumn<bool>("otherValue");
1323     QTest::addColumn<bool>("setValue");
1324     QTest::addColumn<bool>("setShouldFail");
1325     QTest::addColumn<bool>("expectedValue");
1326     QTest::addColumn<bool>("supportsScrollTwoFinger");
1327 
1328     QTest::newRow("true -> false") << true << false << false << false << false << true;
1329     QTest::newRow("other -> false") << false << true << false << false << false << true;
1330     QTest::newRow("false -> true") << false << false << true << false << true << true;
1331     QTest::newRow("set fails") << true << false << false << true << true << true;
1332     QTest::newRow("true -> true") << true << false << true << false << true << true;
1333     QTest::newRow("false -> false") << false << false << false << false << false << true;
1334 
1335     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1336 }
1337 
1338 void TestLibinputDevice::testScrollTwoFinger()
1339 {
1340     libinput_device device;
1341     QFETCH(bool, initValue);
1342     QFETCH(bool, otherValue);
1343     QFETCH(bool, setShouldFail);
1344     QFETCH(bool, supportsScrollTwoFinger);
1345     device.supportedScrollMethods = (supportsScrollTwoFinger ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_EDGE;
1346     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_2FG : otherValue ? LIBINPUT_CONFIG_SCROLL_EDGE
1347                                                                               : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1348     device.setScrollMethodReturnValue = setShouldFail;
1349 
1350     Device d(&device);
1351     QCOMPARE(d.isScrollTwoFinger(), initValue);
1352     QCOMPARE(d.property("scrollTwoFinger").toBool(), initValue);
1353     QCOMPARE(d.property("scrollEdge").toBool(), otherValue);
1354     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), initValue);
1355     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), otherValue);
1356 
1357     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1358     QFETCH(bool, setValue);
1359     d.setScrollTwoFinger(setValue);
1360     QFETCH(bool, expectedValue);
1361     QCOMPARE(d.isScrollTwoFinger(), expectedValue);
1362     QCOMPARE(d.property("scrollTwoFinger").toBool(), expectedValue);
1363     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1364     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), expectedValue);
1365 }
1366 
1367 void TestLibinputDevice::testScrollEdge_data()
1368 {
1369     QTest::addColumn<bool>("initValue");
1370     QTest::addColumn<bool>("otherValue");
1371     QTest::addColumn<bool>("setValue");
1372     QTest::addColumn<bool>("setShouldFail");
1373     QTest::addColumn<bool>("expectedValue");
1374     QTest::addColumn<bool>("supportsScrollEdge");
1375 
1376     QTest::newRow("true -> false") << true << false << false << false << false << true;
1377     QTest::newRow("other -> false") << false << true << false << false << false << true;
1378     QTest::newRow("false -> true") << false << false << true << false << true << true;
1379     QTest::newRow("set fails") << true << false << false << true << true << true;
1380     QTest::newRow("true -> true") << true << false << true << false << true << true;
1381     QTest::newRow("false -> false") << false << false << false << false << false << true;
1382 
1383     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1384 }
1385 
1386 void TestLibinputDevice::testScrollEdge()
1387 {
1388     libinput_device device;
1389     QFETCH(bool, initValue);
1390     QFETCH(bool, otherValue);
1391     QFETCH(bool, setShouldFail);
1392     QFETCH(bool, supportsScrollEdge);
1393     device.supportedScrollMethods = (supportsScrollEdge ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_2FG;
1394     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_EDGE : otherValue ? LIBINPUT_CONFIG_SCROLL_2FG
1395                                                                                : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1396     device.setScrollMethodReturnValue = setShouldFail;
1397 
1398     Device d(&device);
1399     QCOMPARE(d.isScrollEdge(), initValue);
1400     QCOMPARE(d.property("scrollEdge").toBool(), initValue);
1401     QCOMPARE(d.property("scrollTwoFinger").toBool(), otherValue);
1402     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), initValue);
1403     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), otherValue);
1404 
1405     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1406     QFETCH(bool, setValue);
1407     d.setScrollEdge(setValue);
1408     QFETCH(bool, expectedValue);
1409     QCOMPARE(d.isScrollEdge(), expectedValue);
1410     QCOMPARE(d.property("scrollEdge").toBool(), expectedValue);
1411     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1412     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), expectedValue);
1413 }
1414 
1415 void TestLibinputDevice::testScrollButtonDown_data()
1416 {
1417     QTest::addColumn<bool>("initValue");
1418     QTest::addColumn<bool>("otherValue");
1419     QTest::addColumn<bool>("setValue");
1420     QTest::addColumn<bool>("setShouldFail");
1421     QTest::addColumn<bool>("expectedValue");
1422     QTest::addColumn<bool>("supportsScrollButtonDown");
1423 
1424     QTest::newRow("true -> false") << true << false << false << false << false << true;
1425     QTest::newRow("other -> false") << false << true << false << false << false << true;
1426     QTest::newRow("false -> true") << false << false << true << false << true << true;
1427     QTest::newRow("set fails") << true << false << false << true << true << true;
1428     QTest::newRow("true -> true") << true << false << true << false << true << true;
1429     QTest::newRow("false -> false") << false << false << false << false << false << true;
1430 
1431     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1432 }
1433 
1434 void TestLibinputDevice::testScrollButtonDown()
1435 {
1436     libinput_device device;
1437     QFETCH(bool, initValue);
1438     QFETCH(bool, otherValue);
1439     QFETCH(bool, setShouldFail);
1440     QFETCH(bool, supportsScrollButtonDown);
1441     device.supportedScrollMethods = (supportsScrollButtonDown ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_2FG;
1442     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : otherValue ? LIBINPUT_CONFIG_SCROLL_2FG
1443                                                                                          : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1444     device.setScrollMethodReturnValue = setShouldFail;
1445 
1446     Device d(&device);
1447     QCOMPARE(d.isScrollOnButtonDown(), initValue);
1448     QCOMPARE(d.property("scrollOnButtonDown").toBool(), initValue);
1449     QCOMPARE(d.property("scrollTwoFinger").toBool(), otherValue);
1450     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDown"), initValue);
1451     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), otherValue);
1452 
1453     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1454     QFETCH(bool, setValue);
1455     d.setScrollOnButtonDown(setValue);
1456     QFETCH(bool, expectedValue);
1457     QCOMPARE(d.isScrollOnButtonDown(), expectedValue);
1458     QCOMPARE(d.property("scrollOnButtonDown").toBool(), expectedValue);
1459     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1460     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDown"), expectedValue);
1461 }
1462 
1463 void TestLibinputDevice::testScrollButton_data()
1464 {
1465     QTest::addColumn<quint32>("initValue");
1466     QTest::addColumn<quint32>("setValue");
1467     QTest::addColumn<quint32>("expectedValue");
1468     QTest::addColumn<bool>("setShouldFail");
1469     QTest::addColumn<bool>("scrollOnButton");
1470 
1471     QTest::newRow("BTN_LEFT -> BTN_RIGHT") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_RIGHT) << false << true;
1472     QTest::newRow("BTN_LEFT -> BTN_LEFT") << quint32(BTN_LEFT) << quint32(BTN_LEFT) << quint32(BTN_LEFT) << false << true;
1473     QTest::newRow("set should fail") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_LEFT) << true << true;
1474     QTest::newRow("not scroll on button") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_LEFT) << false << false;
1475 }
1476 
1477 void TestLibinputDevice::testScrollButton()
1478 {
1479     libinput_device device;
1480     QFETCH(quint32, initValue);
1481     QFETCH(bool, setShouldFail);
1482     QFETCH(bool, scrollOnButton);
1483     device.scrollButton = initValue;
1484     device.supportedScrollMethods = scrollOnButton ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1485     device.setScrollButtonReturnValue = setShouldFail;
1486 
1487     Device d(&device);
1488     QCOMPARE(d.scrollButton(), initValue);
1489     QCOMPARE(d.property("scrollButton").value<quint32>(), initValue);
1490     QCOMPARE(dbusProperty<quint32>(d.sysName(), "scrollButton"), initValue);
1491 
1492     QSignalSpy scrollButtonChangedSpy(&d, &Device::scrollButtonChanged);
1493     QFETCH(quint32, setValue);
1494     d.setScrollButton(setValue);
1495     QFETCH(quint32, expectedValue);
1496     QCOMPARE(d.scrollButton(), expectedValue);
1497     QCOMPARE(d.property("scrollButton").value<quint32>(), expectedValue);
1498     QCOMPARE(scrollButtonChangedSpy.isEmpty(), initValue == expectedValue);
1499     QCOMPARE(dbusProperty<quint32>(d.sysName(), "scrollButton"), expectedValue);
1500 }
1501 
1502 void TestLibinputDevice::testDisableWhileTypingEnabledByDefault_data()
1503 {
1504     QTest::addColumn<bool>("enabled");
1505 
1506     QTest::newRow("enabled") << true;
1507     QTest::newRow("disabled") << false;
1508 }
1509 
1510 void TestLibinputDevice::testDisableWhileTypingEnabledByDefault()
1511 {
1512     QFETCH(bool, enabled);
1513     libinput_device device;
1514     device.disableWhileTypingEnabledByDefault = enabled ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
1515 
1516     Device d(&device);
1517     QCOMPARE(d.disableWhileTypingEnabledByDefault(), enabled);
1518     QCOMPARE(d.property("disableWhileTypingEnabledByDefault").toBool(), enabled);
1519     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTypingEnabledByDefault"), enabled);
1520 }
1521 
1522 void TestLibinputDevice::testLmrTapButtonMapEnabledByDefault_data()
1523 {
1524     QTest::addColumn<bool>("enabled");
1525 
1526     QTest::newRow("enabled") << true;
1527     QTest::newRow("disabled") << false;
1528 }
1529 
1530 void TestLibinputDevice::testLmrTapButtonMapEnabledByDefault()
1531 {
1532     QFETCH(bool, enabled);
1533     libinput_device device;
1534     device.defaultTapButtonMap = enabled ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
1535 
1536     Device d(&device);
1537     QCOMPARE(d.lmrTapButtonMapEnabledByDefault(), enabled);
1538     QCOMPARE(d.property("lmrTapButtonMapEnabledByDefault").toBool(), enabled);
1539     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMapEnabledByDefault"), enabled);
1540 }
1541 
1542 void TestLibinputDevice::testLmrTapButtonMap_data()
1543 {
1544     QTest::addColumn<bool>("initValue");
1545     QTest::addColumn<bool>("setValue");
1546     QTest::addColumn<bool>("setShouldFail");
1547     QTest::addColumn<bool>("expectedValue");
1548     QTest::addColumn<int>("fingerCount");
1549 
1550     QTest::newRow("true -> false") << true << false << false << false << 3;
1551     QTest::newRow("false -> true") << false << true << false << true << 3;
1552     QTest::newRow("true -> false") << true << false << false << false << 2;
1553     QTest::newRow("false -> true") << false << true << false << true << 2;
1554 
1555     QTest::newRow("set fails") << true << false << true << true << 3;
1556 
1557     QTest::newRow("true -> true") << true << true << false << true << 3;
1558     QTest::newRow("false -> false") << false << false << false << false << 3;
1559     QTest::newRow("true -> true") << true << true << false << true << 2;
1560     QTest::newRow("false -> false") << false << false << false << false << 2;
1561 
1562     QTest::newRow("false -> true, fingerCount 0") << false << true << true << false << 0;
1563 
1564     // TODO: is this a fail in libinput?
1565     // QTest::newRow("false -> true, fingerCount 1") << false << true << true << false << 1;
1566 }
1567 
1568 void TestLibinputDevice::testLmrTapButtonMap()
1569 {
1570     libinput_device device;
1571     QFETCH(bool, initValue);
1572     QFETCH(bool, setShouldFail);
1573     QFETCH(int, fingerCount);
1574     device.tapFingerCount = fingerCount;
1575     device.tapButtonMap = initValue ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
1576     device.setTapButtonMapReturnValue = setShouldFail;
1577 
1578     Device d(&device);
1579     QCOMPARE(d.lmrTapButtonMap(), initValue);
1580     QCOMPARE(d.property("lmrTapButtonMap").toBool(), initValue);
1581 
1582     QSignalSpy tapButtonMapChangedSpy(&d, &Device::tapButtonMapChanged);
1583     QFETCH(bool, setValue);
1584     d.setLmrTapButtonMap(setValue);
1585     QFETCH(bool, expectedValue);
1586     QCOMPARE(d.lmrTapButtonMap(), expectedValue);
1587     QCOMPARE(d.property("lmrTapButtonMap").toBool(), expectedValue);
1588     QCOMPARE(tapButtonMapChangedSpy.isEmpty(), initValue == expectedValue);
1589 }
1590 
1591 void TestLibinputDevice::testDisableWhileTyping_data()
1592 {
1593     QTest::addColumn<bool>("initValue");
1594     QTest::addColumn<bool>("setValue");
1595     QTest::addColumn<bool>("setShouldFail");
1596     QTest::addColumn<bool>("expectedValue");
1597     QTest::addColumn<bool>("supportsDisableWhileTyping");
1598 
1599     QTest::newRow("true -> false") << true << false << false << false << true;
1600     QTest::newRow("false -> true") << false << true << false << true << true;
1601     QTest::newRow("set fails") << true << false << true << true << true;
1602     QTest::newRow("true -> true") << true << true << false << true << true;
1603     QTest::newRow("false -> false") << false << false << false << false << true;
1604 
1605     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1606 }
1607 
1608 void TestLibinputDevice::testDisableWhileTyping()
1609 {
1610     libinput_device device;
1611     QFETCH(bool, initValue);
1612     QFETCH(bool, setShouldFail);
1613     QFETCH(bool, supportsDisableWhileTyping);
1614     device.supportsDisableWhileTyping = supportsDisableWhileTyping;
1615     device.disableWhileTyping = initValue ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
1616     device.setDisableWhileTypingReturnValue = setShouldFail;
1617 
1618     Device d(&device);
1619     QCOMPARE(d.isDisableWhileTyping(), initValue);
1620     QCOMPARE(d.property("disableWhileTyping").toBool(), initValue);
1621     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTyping"), initValue);
1622 
1623     QSignalSpy disableWhileTypingChangedSpy(&d, &Device::disableWhileTypingChanged);
1624     QFETCH(bool, setValue);
1625     d.setDisableWhileTyping(setValue);
1626     QFETCH(bool, expectedValue);
1627     QCOMPARE(d.isDisableWhileTyping(), expectedValue);
1628     QCOMPARE(d.property("disableWhileTyping").toBool(), expectedValue);
1629     QCOMPARE(disableWhileTypingChangedSpy.isEmpty(), initValue == expectedValue);
1630     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTyping"), expectedValue);
1631 }
1632 
1633 void TestLibinputDevice::testLoadEnabled_data()
1634 {
1635     QTest::addColumn<bool>("initValue");
1636     QTest::addColumn<bool>("configValue");
1637 
1638     QTest::newRow("false -> true") << false << true;
1639     QTest::newRow("true -> false") << true << false;
1640     QTest::newRow("true -> true") << true << true;
1641     QTest::newRow("false -> false") << false << false;
1642 }
1643 
1644 void TestLibinputDevice::testLoadEnabled()
1645 {
1646     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1647     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1648     QFETCH(bool, configValue);
1649     QFETCH(bool, initValue);
1650     inputConfig.writeEntry("Enabled", configValue);
1651 
1652     libinput_device device;
1653     device.supportsDisableEvents = true;
1654     device.enabled = initValue;
1655     device.setEnableModeReturnValue = false;
1656 
1657     Device d(&device);
1658     QCOMPARE(d.isEnabled(), initValue);
1659     // no config group set, should not change
1660     d.loadConfiguration();
1661     QCOMPARE(d.isEnabled(), initValue);
1662 
1663     // set the group
1664     d.setConfig(inputConfig);
1665     d.loadConfiguration();
1666     QCOMPARE(d.isEnabled(), configValue);
1667 
1668     // and try to store
1669     if (configValue != initValue) {
1670         d.setEnabled(initValue);
1671         QCOMPARE(inputConfig.readEntry("Enabled", configValue), initValue);
1672     }
1673 }
1674 
1675 void TestLibinputDevice::testLoadPointerAcceleration_data()
1676 {
1677     QTest::addColumn<qreal>("initValue");
1678     QTest::addColumn<qreal>("configValue");
1679 
1680     QTest::newRow("-0.2 -> 0.9") << -0.2 << 0.9;
1681     QTest::newRow("0.0 -> -1.0") << 0.0 << -1.0;
1682     QTest::newRow("0.123 -> -0.456") << 0.123 << -0.456;
1683     QTest::newRow("0.7 -> 0.7") << 0.7 << 0.7;
1684 }
1685 
1686 void TestLibinputDevice::testLoadPointerAcceleration()
1687 {
1688     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1689     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1690     QFETCH(qreal, configValue);
1691     QFETCH(qreal, initValue);
1692     inputConfig.writeEntry("PointerAcceleration", configValue);
1693 
1694     libinput_device device;
1695     device.supportsPointerAcceleration = true;
1696     device.pointerAcceleration = initValue;
1697     device.setPointerAccelerationReturnValue = false;
1698 
1699     Device d(&device);
1700     QCOMPARE(d.pointerAcceleration(), initValue);
1701     QCOMPARE(d.property("pointerAcceleration").toReal(), initValue);
1702     // no config group set, should not change
1703     d.loadConfiguration();
1704     QCOMPARE(d.pointerAcceleration(), initValue);
1705     QCOMPARE(d.property("pointerAcceleration").toReal(), initValue);
1706 
1707     // set the group
1708     d.setConfig(inputConfig);
1709     d.loadConfiguration();
1710     QCOMPARE(d.pointerAcceleration(), configValue);
1711     QCOMPARE(d.property("pointerAcceleration").toReal(), configValue);
1712 
1713     // and try to store
1714     if (configValue != initValue) {
1715         d.setPointerAcceleration(initValue);
1716         QCOMPARE(inputConfig.readEntry("PointerAcceleration", configValue), initValue);
1717     }
1718 }
1719 
1720 void TestLibinputDevice::testLoadPointerAccelerationProfile_data()
1721 {
1722     QTest::addColumn<quint32>("initValue");
1723     QTest::addColumn<QString>("initValuePropNameString");
1724     QTest::addColumn<quint32>("configValue");
1725     QTest::addColumn<QString>("configValuePropNameString");
1726 
1727     QTest::newRow("pointerAccelerationProfileFlat -> pointerAccelerationProfileAdaptive")
1728         << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT << "pointerAccelerationProfileFlat"
1729         << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive";
1730     QTest::newRow("pointerAccelerationProfileAdaptive -> pointerAccelerationProfileFlat")
1731         << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive"
1732         << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT << "pointerAccelerationProfileFlat";
1733     QTest::newRow("pointerAccelerationProfileAdaptive -> pointerAccelerationProfileAdaptive")
1734         << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive" << (quint32)LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive";
1735 }
1736 
1737 void TestLibinputDevice::testLoadPointerAccelerationProfile()
1738 {
1739     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1740     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1741     QFETCH(quint32, initValue);
1742     QFETCH(quint32, configValue);
1743     QFETCH(QString, initValuePropNameString);
1744     QFETCH(QString, configValuePropNameString);
1745 
1746     QByteArray initValuePropName = initValuePropNameString.toLatin1();
1747     QByteArray configValuePropName = configValuePropNameString.toLatin1();
1748 
1749     inputConfig.writeEntry("PointerAccelerationProfile", configValue);
1750 
1751     libinput_device device;
1752     device.supportedPointerAccelerationProfiles = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT | LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
1753     device.pointerAccelerationProfile = (libinput_config_accel_profile)initValue;
1754     device.setPointerAccelerationProfileReturnValue = false;
1755 
1756     Device d(&device);
1757     QCOMPARE(d.property(initValuePropName).toBool(), true);
1758     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1759     // no config group set, should not change
1760     d.loadConfiguration();
1761     QCOMPARE(d.property(initValuePropName).toBool(), true);
1762     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1763 
1764     // set the group
1765     d.setConfig(inputConfig);
1766     d.loadConfiguration();
1767     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
1768     QCOMPARE(d.property(configValuePropName).toBool(), true);
1769     QCOMPARE(dbusProperty<bool>(d.sysName(), initValuePropName), initValue == configValue);
1770     QCOMPARE(dbusProperty<bool>(d.sysName(), configValuePropName), true);
1771 
1772     // and try to store
1773     if (configValue != initValue) {
1774         d.setProperty(initValuePropName, true);
1775         QCOMPARE(inputConfig.readEntry("PointerAccelerationProfile", configValue), initValue);
1776     }
1777 }
1778 
1779 void TestLibinputDevice::testLoadClickMethod_data()
1780 {
1781     QTest::addColumn<quint32>("initValue");
1782     QTest::addColumn<QString>("initValuePropNameString");
1783     QTest::addColumn<quint32>("configValue");
1784     QTest::addColumn<QString>("configValuePropNameString");
1785 
1786     QTest::newRow("clickMethodAreas -> clickMethodClickfinger")
1787         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas"
1788         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger";
1789     QTest::newRow("clickMethodClickfinger -> clickMethodAreas")
1790         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger"
1791         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas";
1792     QTest::newRow("clickMethodAreas -> clickMethodAreas")
1793         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas"
1794         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas";
1795     QTest::newRow("clickMethodClickfinger -> clickMethodClickfinger")
1796         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger"
1797         << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger";
1798 }
1799 
1800 void TestLibinputDevice::testLoadClickMethod()
1801 {
1802     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1803     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1804     QFETCH(quint32, initValue);
1805     QFETCH(quint32, configValue);
1806     QFETCH(QString, initValuePropNameString);
1807     QFETCH(QString, configValuePropNameString);
1808 
1809     QByteArray initValuePropName = initValuePropNameString.toLatin1();
1810     QByteArray configValuePropName = configValuePropNameString.toLatin1();
1811 
1812     inputConfig.writeEntry("ClickMethod", configValue);
1813 
1814     libinput_device device;
1815     device.supportedClickMethods = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS | LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
1816     device.clickMethod = (libinput_config_click_method)initValue;
1817     device.setClickMethodReturnValue = false;
1818 
1819     Device d(&device);
1820     QCOMPARE(d.property(initValuePropName).toBool(), true);
1821     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1822     // no config group set, should not change
1823     d.loadConfiguration();
1824     QCOMPARE(d.property(initValuePropName).toBool(), true);
1825     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1826 
1827     // set the group
1828     d.setConfig(inputConfig);
1829     d.loadConfiguration();
1830     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
1831     QCOMPARE(d.property(configValuePropName).toBool(), true);
1832     QCOMPARE(dbusProperty<bool>(d.sysName(), initValuePropName), initValue == configValue);
1833     QCOMPARE(dbusProperty<bool>(d.sysName(), configValuePropName), true);
1834 
1835     // and try to store
1836     if (configValue != initValue) {
1837         d.setProperty(initValuePropName, true);
1838         QCOMPARE(inputConfig.readEntry("ClickMethod", configValue), initValue);
1839     }
1840 }
1841 
1842 void TestLibinputDevice::testLoadTapToClick_data()
1843 {
1844     QTest::addColumn<bool>("initValue");
1845     QTest::addColumn<bool>("configValue");
1846 
1847     QTest::newRow("false -> true") << false << true;
1848     QTest::newRow("true -> false") << true << false;
1849     QTest::newRow("true -> true") << true << true;
1850     QTest::newRow("false -> false") << false << false;
1851 }
1852 
1853 void TestLibinputDevice::testLoadTapToClick()
1854 {
1855     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1856     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1857     QFETCH(bool, configValue);
1858     QFETCH(bool, initValue);
1859     inputConfig.writeEntry("TapToClick", configValue);
1860 
1861     libinput_device device;
1862     device.tapFingerCount = 2;
1863     device.tapToClick = initValue;
1864     device.setTapToClickReturnValue = false;
1865 
1866     Device d(&device);
1867     QCOMPARE(d.isTapToClick(), initValue);
1868     // no config group set, should not change
1869     d.loadConfiguration();
1870     QCOMPARE(d.isTapToClick(), initValue);
1871 
1872     // set the group
1873     d.setConfig(inputConfig);
1874     d.loadConfiguration();
1875     QCOMPARE(d.isTapToClick(), configValue);
1876 
1877     // and try to store
1878     if (configValue != initValue) {
1879         d.setTapToClick(initValue);
1880         QCOMPARE(inputConfig.readEntry("TapToClick", configValue), initValue);
1881     }
1882 }
1883 
1884 void TestLibinputDevice::testLoadTapAndDrag_data()
1885 {
1886     QTest::addColumn<bool>("initValue");
1887     QTest::addColumn<bool>("configValue");
1888 
1889     QTest::newRow("false -> true") << false << true;
1890     QTest::newRow("true -> false") << true << false;
1891     QTest::newRow("true -> true") << true << true;
1892     QTest::newRow("false -> false") << false << false;
1893 }
1894 
1895 void TestLibinputDevice::testLoadTapAndDrag()
1896 {
1897     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1898     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1899     QFETCH(bool, configValue);
1900     QFETCH(bool, initValue);
1901     inputConfig.writeEntry("TapAndDrag", configValue);
1902 
1903     libinput_device device;
1904     device.tapAndDrag = initValue;
1905     device.setTapAndDragReturnValue = false;
1906 
1907     Device d(&device);
1908     QCOMPARE(d.isTapAndDrag(), initValue);
1909     // no config group set, should not change
1910     d.loadConfiguration();
1911     QCOMPARE(d.isTapAndDrag(), initValue);
1912 
1913     // set the group
1914     d.setConfig(inputConfig);
1915     d.loadConfiguration();
1916     QCOMPARE(d.isTapAndDrag(), configValue);
1917 
1918     // and try to store
1919     if (configValue != initValue) {
1920         d.setTapAndDrag(initValue);
1921         QCOMPARE(inputConfig.readEntry("TapAndDrag", configValue), initValue);
1922     }
1923 }
1924 
1925 void TestLibinputDevice::testLoadTapDragLock_data()
1926 {
1927     QTest::addColumn<bool>("initValue");
1928     QTest::addColumn<bool>("configValue");
1929 
1930     QTest::newRow("false -> true") << false << true;
1931     QTest::newRow("true -> false") << true << false;
1932     QTest::newRow("true -> true") << true << true;
1933     QTest::newRow("false -> false") << false << false;
1934 }
1935 
1936 void TestLibinputDevice::testLoadTapDragLock()
1937 {
1938     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1939     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1940     QFETCH(bool, configValue);
1941     QFETCH(bool, initValue);
1942     inputConfig.writeEntry("TapDragLock", configValue);
1943 
1944     libinput_device device;
1945     device.tapDragLock = initValue;
1946     device.setTapDragLockReturnValue = false;
1947 
1948     Device d(&device);
1949     QCOMPARE(d.isTapDragLock(), initValue);
1950     // no config group set, should not change
1951     d.loadConfiguration();
1952     QCOMPARE(d.isTapDragLock(), initValue);
1953 
1954     // set the group
1955     d.setConfig(inputConfig);
1956     d.loadConfiguration();
1957     QCOMPARE(d.isTapDragLock(), configValue);
1958 
1959     // and try to store
1960     if (configValue != initValue) {
1961         d.setTapDragLock(initValue);
1962         QCOMPARE(inputConfig.readEntry("TapDragLock", configValue), initValue);
1963     }
1964 }
1965 
1966 void TestLibinputDevice::testLoadMiddleButtonEmulation_data()
1967 {
1968     QTest::addColumn<bool>("initValue");
1969     QTest::addColumn<bool>("configValue");
1970 
1971     QTest::newRow("false -> true") << false << true;
1972     QTest::newRow("true -> false") << true << false;
1973     QTest::newRow("true -> true") << true << true;
1974     QTest::newRow("false -> false") << false << false;
1975 }
1976 
1977 void TestLibinputDevice::testLoadMiddleButtonEmulation()
1978 {
1979     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1980     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1981     QFETCH(bool, configValue);
1982     QFETCH(bool, initValue);
1983     inputConfig.writeEntry("MiddleButtonEmulation", configValue);
1984 
1985     libinput_device device;
1986     device.supportsMiddleEmulation = true;
1987     device.middleEmulation = initValue;
1988     device.setMiddleEmulationReturnValue = false;
1989 
1990     Device d(&device);
1991     QCOMPARE(d.isMiddleEmulation(), initValue);
1992     // no config group set, should not change
1993     d.loadConfiguration();
1994     QCOMPARE(d.isMiddleEmulation(), initValue);
1995 
1996     // set the group
1997     d.setConfig(inputConfig);
1998     d.loadConfiguration();
1999     QCOMPARE(d.isMiddleEmulation(), configValue);
2000 
2001     // and try to store
2002     if (configValue != initValue) {
2003         d.setMiddleEmulation(initValue);
2004         QCOMPARE(inputConfig.readEntry("MiddleButtonEmulation", configValue), initValue);
2005     }
2006 }
2007 
2008 void TestLibinputDevice::testLoadNaturalScroll_data()
2009 {
2010     QTest::addColumn<bool>("initValue");
2011     QTest::addColumn<bool>("configValue");
2012 
2013     QTest::newRow("false -> true") << false << true;
2014     QTest::newRow("true -> false") << true << false;
2015     QTest::newRow("true -> true") << true << true;
2016     QTest::newRow("false -> false") << false << false;
2017 }
2018 
2019 void TestLibinputDevice::testLoadNaturalScroll()
2020 {
2021     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2022     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2023     QFETCH(bool, configValue);
2024     QFETCH(bool, initValue);
2025     inputConfig.writeEntry("NaturalScroll", configValue);
2026 
2027     libinput_device device;
2028     device.supportsNaturalScroll = true;
2029     device.naturalScroll = initValue;
2030     device.setNaturalScrollReturnValue = false;
2031 
2032     Device d(&device);
2033     QCOMPARE(d.isNaturalScroll(), initValue);
2034     // no config group set, should not change
2035     d.loadConfiguration();
2036     QCOMPARE(d.isNaturalScroll(), initValue);
2037 
2038     // set the group
2039     d.setConfig(inputConfig);
2040     d.loadConfiguration();
2041     QCOMPARE(d.isNaturalScroll(), configValue);
2042 
2043     // and try to store
2044     if (configValue != initValue) {
2045         d.setNaturalScroll(initValue);
2046         QCOMPARE(inputConfig.readEntry("NaturalScroll", configValue), initValue);
2047     }
2048 }
2049 
2050 void TestLibinputDevice::testLoadScrollMethod_data()
2051 {
2052     QTest::addColumn<quint32>("initValue");
2053     QTest::addColumn<QString>("initValuePropNameString");
2054     QTest::addColumn<quint32>("configValue");
2055     QTest::addColumn<QString>("configValuePropNameString");
2056 
2057     QTest::newRow("scrollTwoFinger -> scrollEdge") << (quint32)LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger" << (quint32)LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
2058     QTest::newRow("scrollOnButtonDown -> scrollTwoFinger") << (quint32)LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN << "scrollOnButtonDown" << (quint32)LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger";
2059     QTest::newRow("scrollEdge -> scrollEdge") << (quint32)LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge" << (quint32)LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
2060 }
2061 
2062 void TestLibinputDevice::testLoadScrollMethod()
2063 {
2064     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2065     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2066     QFETCH(quint32, initValue);
2067     QFETCH(quint32, configValue);
2068     QFETCH(QString, initValuePropNameString);
2069     QFETCH(QString, configValuePropNameString);
2070 
2071     QByteArray initValuePropName = initValuePropNameString.toLatin1();
2072     QByteArray configValuePropName = configValuePropNameString.toLatin1();
2073 
2074     inputConfig.writeEntry("ScrollMethod", configValue);
2075 
2076     libinput_device device;
2077     device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG | LIBINPUT_CONFIG_SCROLL_EDGE | LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2078     device.scrollMethod = (libinput_config_scroll_method)initValue;
2079     device.setScrollMethodReturnValue = false;
2080 
2081     Device d(&device);
2082     QCOMPARE(d.property(initValuePropName).toBool(), true);
2083     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
2084     // no config group set, should not change
2085     d.loadConfiguration();
2086     QCOMPARE(d.property(initValuePropName).toBool(), true);
2087     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
2088 
2089     // set the group
2090     d.setConfig(inputConfig);
2091     d.loadConfiguration();
2092     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
2093     QCOMPARE(d.property(configValuePropName).toBool(), true);
2094 
2095     // and try to store
2096     if (configValue != initValue) {
2097         d.setProperty(initValuePropName, true);
2098         QCOMPARE(inputConfig.readEntry("ScrollMethod", configValue), initValue);
2099     }
2100 }
2101 
2102 void TestLibinputDevice::testLoadScrollButton_data()
2103 {
2104     QTest::addColumn<quint32>("initValue");
2105     QTest::addColumn<quint32>("configValue");
2106 
2107     QTest::newRow("BTN_LEFT -> BTN_RIGHT") << quint32(BTN_LEFT) << quint32(BTN_RIGHT);
2108     QTest::newRow("BTN_LEFT -> BTN_LEFT") << quint32(BTN_LEFT) << quint32(BTN_LEFT);
2109 }
2110 
2111 void TestLibinputDevice::testLoadScrollButton()
2112 {
2113     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2114     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2115     QFETCH(quint32, configValue);
2116     QFETCH(quint32, initValue);
2117     inputConfig.writeEntry("ScrollButton", configValue);
2118 
2119     libinput_device device;
2120     device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2121     device.scrollMethod = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2122     device.scrollButton = initValue;
2123     device.setScrollButtonReturnValue = false;
2124 
2125     Device d(&device);
2126     QCOMPARE(d.isScrollOnButtonDown(), true);
2127     QCOMPARE(d.scrollButton(), initValue);
2128     // no config group set, should not change
2129     d.loadConfiguration();
2130     QCOMPARE(d.isScrollOnButtonDown(), true);
2131     QCOMPARE(d.scrollButton(), initValue);
2132 
2133     // set the group
2134     d.setConfig(inputConfig);
2135     d.loadConfiguration();
2136     QCOMPARE(d.isScrollOnButtonDown(), true);
2137     QCOMPARE(d.scrollButton(), configValue);
2138 
2139     // and try to store
2140     if (configValue != initValue) {
2141         d.setScrollButton(initValue);
2142         QCOMPARE(inputConfig.readEntry("ScrollButton", configValue), initValue);
2143     }
2144 }
2145 
2146 void TestLibinputDevice::testLoadLeftHanded_data()
2147 {
2148     QTest::addColumn<bool>("initValue");
2149     QTest::addColumn<bool>("configValue");
2150 
2151     QTest::newRow("false -> true") << false << true;
2152     QTest::newRow("true -> false") << true << false;
2153     QTest::newRow("true -> true") << true << true;
2154     QTest::newRow("false -> false") << false << false;
2155 }
2156 
2157 void TestLibinputDevice::testLoadLeftHanded()
2158 {
2159     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2160     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2161     QFETCH(bool, configValue);
2162     QFETCH(bool, initValue);
2163     inputConfig.writeEntry("LeftHanded", configValue);
2164 
2165     libinput_device device;
2166     device.supportsLeftHanded = true;
2167     device.leftHanded = initValue;
2168     device.setLeftHandedReturnValue = false;
2169 
2170     Device d(&device);
2171     QCOMPARE(d.isLeftHanded(), initValue);
2172     // no config group set, should not change
2173     d.loadConfiguration();
2174     QCOMPARE(d.isLeftHanded(), initValue);
2175 
2176     // set the group
2177     d.setConfig(inputConfig);
2178     d.loadConfiguration();
2179     QCOMPARE(d.isLeftHanded(), configValue);
2180 
2181     // and try to store
2182     if (configValue != initValue) {
2183         d.setLeftHanded(initValue);
2184         QCOMPARE(inputConfig.readEntry("LeftHanded", configValue), initValue);
2185     }
2186 }
2187 
2188 void TestLibinputDevice::testLoadDisableWhileTyping_data()
2189 {
2190     QTest::addColumn<bool>("initValue");
2191     QTest::addColumn<bool>("configValue");
2192 
2193     QTest::newRow("false -> true") << false << true;
2194     QTest::newRow("true -> false") << true << false;
2195     QTest::newRow("true -> true") << true << true;
2196     QTest::newRow("false -> false") << false << false;
2197 }
2198 
2199 void TestLibinputDevice::testLoadDisableWhileTyping()
2200 {
2201     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2202     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2203     QFETCH(bool, configValue);
2204     QFETCH(bool, initValue);
2205     inputConfig.writeEntry("DisableWhileTyping", configValue);
2206 
2207     libinput_device device;
2208     device.supportsDisableWhileTyping = true;
2209     device.disableWhileTyping = initValue ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
2210     device.setDisableWhileTypingReturnValue = false;
2211 
2212     Device d(&device);
2213     QCOMPARE(d.isDisableWhileTyping(), initValue);
2214     // no config group set, should not change
2215     d.loadConfiguration();
2216     QCOMPARE(d.isDisableWhileTyping(), initValue);
2217 
2218     // set the group
2219     d.setConfig(inputConfig);
2220     d.loadConfiguration();
2221     QCOMPARE(d.isDisableWhileTyping(), configValue);
2222 
2223     // and try to store
2224     if (configValue != initValue) {
2225         d.setDisableWhileTyping(initValue);
2226         QCOMPARE(inputConfig.readEntry("DisableWhileTyping", configValue), initValue);
2227     }
2228 }
2229 
2230 void TestLibinputDevice::testLoadLmrTapButtonMap_data()
2231 {
2232     QTest::addColumn<bool>("initValue");
2233     QTest::addColumn<bool>("configValue");
2234 
2235     QTest::newRow("false -> true") << false << true;
2236     QTest::newRow("true -> false") << true << false;
2237     QTest::newRow("true -> true") << true << true;
2238     QTest::newRow("false -> false") << false << false;
2239 }
2240 
2241 void TestLibinputDevice::testLoadLmrTapButtonMap()
2242 {
2243     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2244     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2245     QFETCH(bool, configValue);
2246     QFETCH(bool, initValue);
2247     inputConfig.writeEntry("LmrTapButtonMap", configValue);
2248 
2249     libinput_device device;
2250     device.tapFingerCount = 3;
2251     device.tapButtonMap = initValue ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
2252     device.setTapButtonMapReturnValue = false;
2253 
2254     Device d(&device);
2255     QCOMPARE(d.lmrTapButtonMap(), initValue);
2256     // no config group set, should not change
2257     d.loadConfiguration();
2258     QCOMPARE(d.lmrTapButtonMap(), initValue);
2259     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMap"), initValue);
2260 
2261     // set the group
2262     d.setConfig(inputConfig);
2263     d.loadConfiguration();
2264     QCOMPARE(d.lmrTapButtonMap(), configValue);
2265     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMap"), configValue);
2266 
2267     // and try to store
2268     if (configValue != initValue) {
2269         d.setLmrTapButtonMap(initValue);
2270         QCOMPARE(inputConfig.readEntry("LmrTapButtonMap", configValue), initValue);
2271     }
2272 }
2273 
2274 void TestLibinputDevice::testOrientation_data()
2275 {
2276     QTest::addColumn<Qt::ScreenOrientation>("orientation");
2277     QTest::addColumn<float>("m11");
2278     QTest::addColumn<float>("m12");
2279     QTest::addColumn<float>("m13");
2280     QTest::addColumn<float>("m21");
2281     QTest::addColumn<float>("m22");
2282     QTest::addColumn<float>("m23");
2283     QTest::addColumn<bool>("defaultIsIdentity");
2284 
2285     QTest::newRow("Primary") << Qt::PrimaryOrientation << 1.0f << 2.0f << 3.0f << 4.0f << 5.0f << 6.0f << false;
2286     QTest::newRow("Landscape") << Qt::LandscapeOrientation << 1.0f << 2.0f << 3.0f << 4.0f << 5.0f << 6.0f << false;
2287     QTest::newRow("Portrait") << Qt::PortraitOrientation << 0.0f << -1.0f << 1.0f << 1.0f << 0.0f << 0.0f << true;
2288     QTest::newRow("InvertedLandscape") << Qt::InvertedLandscapeOrientation << -1.0f << 0.0f << 1.0f << 0.0f << -1.0f << 1.0f << true;
2289     QTest::newRow("InvertedPortrait") << Qt::InvertedPortraitOrientation << 0.0f << 1.0f << 0.0f << -1.0f << 0.0f << 1.0f << true;
2290 }
2291 
2292 void TestLibinputDevice::testOrientation()
2293 {
2294     libinput_device device;
2295     device.supportsCalibrationMatrix = true;
2296     device.defaultCalibrationMatrix = std::array<float, 6>{{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}};
2297     QFETCH(bool, defaultIsIdentity);
2298     device.defaultCalibrationMatrixIsIdentity = defaultIsIdentity;
2299     Device d(&device);
2300     QFETCH(Qt::ScreenOrientation, orientation);
2301     d.setOrientation(orientation);
2302     QTEST(device.calibrationMatrix[0], "m11");
2303     QTEST(device.calibrationMatrix[1], "m12");
2304     QTEST(device.calibrationMatrix[2], "m13");
2305     QTEST(device.calibrationMatrix[3], "m21");
2306     QTEST(device.calibrationMatrix[4], "m22");
2307     QTEST(device.calibrationMatrix[5], "m23");
2308 }
2309 
2310 void TestLibinputDevice::testCalibrationWithDefault()
2311 {
2312     libinput_device device;
2313     device.supportsCalibrationMatrix = true;
2314     device.defaultCalibrationMatrix = std::array<float, 6>{{2.0, 3.0, 0.0, 4.0, 5.0, 0.0}};
2315     device.defaultCalibrationMatrixIsIdentity = false;
2316     Device d(&device);
2317     d.setOrientation(Qt::PortraitOrientation);
2318     QCOMPARE(device.calibrationMatrix[0], 3.0f);
2319     QCOMPARE(device.calibrationMatrix[1], -2.0f);
2320     QCOMPARE(device.calibrationMatrix[2], 2.0f);
2321     QCOMPARE(device.calibrationMatrix[3], 5.0f);
2322     QCOMPARE(device.calibrationMatrix[4], -4.0f);
2323     QCOMPARE(device.calibrationMatrix[5], 4.0f);
2324 }
2325 
2326 void TestLibinputDevice::testSwitch_data()
2327 {
2328     QTest::addColumn<bool>("lid");
2329     QTest::addColumn<bool>("tablet");
2330 
2331     QTest::newRow("lid") << true << false;
2332     QTest::newRow("tablet") << false << true;
2333 }
2334 
2335 void TestLibinputDevice::testSwitch()
2336 {
2337     libinput_device device;
2338     device.switchDevice = true;
2339     QFETCH(bool, lid);
2340     QFETCH(bool, tablet);
2341     device.lidSwitch = lid;
2342     device.tabletModeSwitch = tablet;
2343 
2344     Device d(&device);
2345     QCOMPARE(d.isSwitch(), true);
2346     QCOMPARE(d.isLidSwitch(), lid);
2347     QCOMPARE(d.property("lidSwitch").toBool(), lid);
2348     QCOMPARE(dbusProperty<bool>(d.sysName(), "lidSwitch"), lid);
2349     QCOMPARE(d.isTabletModeSwitch(), tablet);
2350     QCOMPARE(d.property("tabletModeSwitch").toBool(), tablet);
2351     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletModeSwitch"), tablet);
2352 }
2353 
2354 QTEST_GUILESS_MAIN(TestLibinputDevice)
2355 #include "device_test.moc"