File indexing completed on 2024-05-12 05:30:50

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