1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #include "mock_libinput.h"
10 #include "libinput/device.h"
11 #include <config-kwin.h>
12 
13 #include <KSharedConfig>
14 
15 #include <QDBusInterface>
16 #include <QDBusConnection>
17 #include <QtTest>
18 
19 #include <linux/input.h>
20 
21 using namespace KWin::LibInput;
22 
23 class TestLibinputDevice : public QObject
24 {
25     Q_OBJECT
26 private Q_SLOTS:
27     void initTestCase();
28     void testStaticGetter();
29     void testDeviceType_data();
30     void testDeviceType();
31     void testGestureSupport_data();
32     void testGestureSupport();
33     void testNames_data();
34     void testNames();
35     void testProduct();
36     void testVendor();
37     void testTapFingerCount();
38     void testSize_data();
39     void testSize();
40     void testDefaultPointerAcceleration_data();
41     void testDefaultPointerAcceleration();
42     void testDefaultPointerAccelerationProfileFlat_data();
43     void testDefaultPointerAccelerationProfileFlat();
44     void testDefaultPointerAccelerationProfileAdaptive_data();
45     void testDefaultPointerAccelerationProfileAdaptive();
46     void testDefaultClickMethodAreas_data();
47     void testDefaultClickMethodAreas();
48     void testDefaultClickMethodClickfinger_data();
49     void testDefaultClickMethodClickfinger();
50     void testLeftHandedEnabledByDefault_data();
51     void testLeftHandedEnabledByDefault();
52     void testTapEnabledByDefault_data();
53     void testTapEnabledByDefault();
54     void testMiddleEmulationEnabledByDefault_data();
55     void testMiddleEmulationEnabledByDefault();
56     void testNaturalScrollEnabledByDefault_data();
57     void testNaturalScrollEnabledByDefault();
58     void testScrollTwoFingerEnabledByDefault_data();
59     void testScrollTwoFingerEnabledByDefault();
60     void testScrollEdgeEnabledByDefault_data();
61     void testScrollEdgeEnabledByDefault();
62     void testScrollOnButtonDownEnabledByDefault_data();
63     void testScrollOnButtonDownEnabledByDefault();
64     void testDisableWhileTypingEnabledByDefault_data();
65     void testDisableWhileTypingEnabledByDefault();
66     void testLmrTapButtonMapEnabledByDefault_data();
67     void testLmrTapButtonMapEnabledByDefault();
68     void testSupportsDisableWhileTyping_data();
69     void testSupportsDisableWhileTyping();
70     void testSupportsPointerAcceleration_data();
71     void testSupportsPointerAcceleration();
72     void testSupportsLeftHanded_data();
73     void testSupportsLeftHanded();
74     void testSupportsCalibrationMatrix_data();
75     void testSupportsCalibrationMatrix();
76     void testSupportsDisableEvents_data();
77     void testSupportsDisableEvents();
78     void testSupportsDisableEventsOnExternalMouse_data();
79     void testSupportsDisableEventsOnExternalMouse();
80     void testSupportsMiddleEmulation_data();
81     void testSupportsMiddleEmulation();
82     void testSupportsNaturalScroll_data();
83     void testSupportsNaturalScroll();
84     void testSupportsScrollTwoFinger_data();
85     void testSupportsScrollTwoFinger();
86     void testSupportsScrollEdge_data();
87     void testSupportsScrollEdge();
88     void testSupportsScrollOnButtonDown_data();
89     void testSupportsScrollOnButtonDown();
90     void testDefaultScrollButton_data();
91     void testDefaultScrollButton();
92     void testPointerAcceleration_data();
93     void testPointerAcceleration();
94     void testLeftHanded_data();
95     void testLeftHanded();
96     void testSupportedButtons_data();
97     void testSupportedButtons();
98     void testAlphaNumericKeyboard_data();
99     void testAlphaNumericKeyboard();
100     void testEnabled_data();
101     void testEnabled();
102     void testTapToClick_data();
103     void testTapToClick();
104     void testTapAndDragEnabledByDefault_data();
105     void testTapAndDragEnabledByDefault();
106     void testTapAndDrag_data();
107     void testTapAndDrag();
108     void testTapDragLockEnabledByDefault_data();
109     void testTapDragLockEnabledByDefault();
110     void testTapDragLock_data();
111     void testTapDragLock();
112     void testMiddleEmulation_data();
113     void testMiddleEmulation();
114     void testNaturalScroll_data();
115     void testNaturalScroll();
116     void testScrollFactor();
117     void testScrollTwoFinger_data();
118     void testScrollTwoFinger();
119     void testScrollEdge_data();
120     void testScrollEdge();
121     void testScrollButtonDown_data();
122     void testScrollButtonDown();
123     void testScrollButton_data();
124     void testScrollButton();
125     void testDisableWhileTyping_data();
126     void testDisableWhileTyping();
127     void testLmrTapButtonMap_data();
128     void testLmrTapButtonMap();
129     void testLoadEnabled_data();
130     void testLoadEnabled();
131     void testLoadPointerAcceleration_data();
132     void testLoadPointerAcceleration();
133     void testLoadPointerAccelerationProfile_data();
134     void testLoadPointerAccelerationProfile();
135     void testLoadClickMethod_data();
136     void testLoadClickMethod();
137     void testLoadTapToClick_data();
138     void testLoadTapToClick();
139     void testLoadTapAndDrag_data();
140     void testLoadTapAndDrag();
141     void testLoadTapDragLock_data();
142     void testLoadTapDragLock();
143     void testLoadMiddleButtonEmulation_data();
144     void testLoadMiddleButtonEmulation();
145     void testLoadNaturalScroll_data();
146     void testLoadNaturalScroll();
147     void testLoadScrollMethod_data();
148     void testLoadScrollMethod();
149     void testLoadScrollButton_data();
150     void testLoadScrollButton();
151     void testLoadDisableWhileTyping_data();
152     void testLoadDisableWhileTyping();
153     void testLoadLmrTapButtonMap_data();
154     void testLoadLmrTapButtonMap();
155     void testLoadLeftHanded_data();
156     void testLoadLeftHanded();
157     void testScreenId();
158     void testOrientation_data();
159     void testOrientation();
160     void testCalibrationWithDefault();
161     void testSwitch_data();
162     void testSwitch();
163 };
164 
165 namespace {
166 template <typename T>
dbusProperty(const QString & name,const char * property)167 T dbusProperty(const QString &name, const char *property)
168 {
169     QDBusInterface interface{QStringLiteral("org.kde.kwin.tests.libinputdevice"),
170                              QStringLiteral("/org/kde/KWin/InputDevice/") + name,
171                              QStringLiteral("org.kde.KWin.InputDevice")};
172     return interface.property(property).value<T>();
173 }
174 }
175 
initTestCase()176 void TestLibinputDevice::initTestCase()
177 {
178     QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kwin.tests.libinputdevice"));
179 }
180 
testStaticGetter()181 void TestLibinputDevice::testStaticGetter()
182 {
183     // this test verifies that the static getter for Device works as expected
184     QVERIFY(Device::devices().isEmpty());
185 
186     // create some device
187     libinput_device device1;
188     libinput_device device2;
189     // at the moment not yet known to Device
190     QVERIFY(!Device::getDevice(&device1));
191     QVERIFY(!Device::getDevice(&device2));
192     QVERIFY(Device::devices().isEmpty());
193 
194     // now create a Device for one
195     Device *d1 = new Device(&device1);
196     QCOMPARE(Device::devices().count(), 1);
197     QCOMPARE(Device::devices().first(), d1);
198     QCOMPARE(Device::getDevice(&device1), d1);
199     QVERIFY(!Device::getDevice(&device2));
200 
201     // and a second Device
202     Device *d2 = new Device(&device2);
203     QCOMPARE(Device::devices().count(), 2);
204     QCOMPARE(Device::devices().first(), d1);
205     QCOMPARE(Device::devices().last(), d2);
206     QCOMPARE(Device::getDevice(&device1), d1);
207     QCOMPARE(Device::getDevice(&device2), d2);
208 
209     // now delete d1
210     delete d1;
211     QCOMPARE(Device::devices().count(), 1);
212     QCOMPARE(Device::devices().first(), d2);
213     QCOMPARE(Device::getDevice(&device2), d2);
214     QVERIFY(!Device::getDevice(&device1));
215 
216     // and delete d2
217     delete d2;
218     QVERIFY(!Device::getDevice(&device1));
219     QVERIFY(!Device::getDevice(&device2));
220     QVERIFY(Device::devices().isEmpty());
221 }
222 
testDeviceType_data()223 void TestLibinputDevice::testDeviceType_data()
224 {
225     QTest::addColumn<bool>("keyboard");
226     QTest::addColumn<bool>("pointer");
227     QTest::addColumn<bool>("touch");
228     QTest::addColumn<bool>("tabletTool");
229     QTest::addColumn<bool>("switchDevice");
230 
231     QTest::newRow("keyboard") << true << false << false << false << false;
232     QTest::newRow("pointer") << false << true << false << false << false;
233     QTest::newRow("touch") << false << false << true << false << false;
234     QTest::newRow("keyboard/pointer") << true << true << false << false << false;
235     QTest::newRow("keyboard/touch") << true << false << true << false << false;
236     QTest::newRow("pointer/touch") << false << true << true << false << false;
237     QTest::newRow("keyboard/pointer/touch") << true << true << true << false << false;
238     QTest::newRow("tabletTool") << false << false << false << true << false;
239     QTest::newRow("switch") << false << false << false << false << true;
240 }
241 
testDeviceType()242 void TestLibinputDevice::testDeviceType()
243 {
244     // this test verifies that the device type is recognized correctly
245     QFETCH(bool, keyboard);
246     QFETCH(bool, pointer);
247     QFETCH(bool, touch);
248     QFETCH(bool, tabletTool);
249     QFETCH(bool, switchDevice);
250 
251     libinput_device device;
252     device.keyboard = keyboard;
253     device.pointer = pointer;
254     device.touch = touch;
255     device.tabletTool = tabletTool;
256     device.switchDevice = switchDevice;
257 
258     Device d(&device);
259     QCOMPARE(d.isKeyboard(), keyboard);
260     QCOMPARE(d.property("keyboard").toBool(), keyboard);
261     QCOMPARE(dbusProperty<bool>(d.sysName(), "keyboard"), keyboard);
262     QCOMPARE(d.isPointer(), pointer);
263     QCOMPARE(d.property("pointer").toBool(), pointer);
264     QCOMPARE(dbusProperty<bool>(d.sysName(), "pointer"), pointer);
265     QCOMPARE(d.isTouch(), touch);
266     QCOMPARE(d.property("touch").toBool(), touch);
267     QCOMPARE(dbusProperty<bool>(d.sysName(), "touch"), touch);
268     QCOMPARE(d.isTabletPad(), false);
269     QCOMPARE(d.property("tabletPad").toBool(), false);
270     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletPad"), false);
271     QCOMPARE(d.isTabletTool(), tabletTool);
272     QCOMPARE(d.property("tabletTool").toBool(), tabletTool);
273     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletTool"), tabletTool);
274     QCOMPARE(d.isSwitch(), switchDevice);
275     QCOMPARE(d.property("switchDevice").toBool(), switchDevice);
276     QCOMPARE(dbusProperty<bool>(d.sysName(), "switchDevice"), switchDevice);
277 
278     QCOMPARE(d.device(), &device);
279 }
280 
testGestureSupport_data()281 void TestLibinputDevice::testGestureSupport_data()
282 {
283     QTest::addColumn<bool>("supported");
284 
285     QTest::newRow("supported") << true;
286     QTest::newRow("not supported") << false;
287 }
288 
testGestureSupport()289 void TestLibinputDevice::testGestureSupport()
290 {
291     // this test verifies whether the Device supports gestures
292     QFETCH(bool, supported);
293     libinput_device device;
294     device.gestureSupported = supported;
295 
296     Device d(&device);
297     QCOMPARE(d.supportsGesture(), supported);
298     QCOMPARE(d.property("gestureSupport").toBool(), supported);
299     QCOMPARE(dbusProperty<bool>(d.sysName(), "gestureSupport"), supported);
300 }
301 
testNames_data()302 void TestLibinputDevice::testNames_data()
303 {
304     QTest::addColumn<QByteArray>("name");
305     QTest::addColumn<QByteArray>("sysName");
306     QTest::addColumn<QByteArray>("outputName");
307 
308     QTest::newRow("empty") << QByteArray() << QByteArrayLiteral("event1") << QByteArray();
309     QTest::newRow("set") << QByteArrayLiteral("awesome test device") << QByteArrayLiteral("event0") << QByteArrayLiteral("hdmi0");
310 }
311 
testNames()312 void TestLibinputDevice::testNames()
313 {
314     // this test verifies the various name properties of the Device
315     QFETCH(QByteArray, name);
316     QFETCH(QByteArray, sysName);
317     QFETCH(QByteArray, outputName);
318     libinput_device device;
319     device.name = name;
320     device.sysName = sysName;
321     device.outputName = outputName;
322 
323     Device d(&device);
324     QCOMPARE(d.name().toUtf8(), name);
325     QCOMPARE(d.property("name").toString().toUtf8(), name);
326     QCOMPARE(dbusProperty<QString>(d.sysName(), "name"), name);
327     QCOMPARE(d.sysName().toUtf8(), sysName);
328     QCOMPARE(d.property("sysName").toString().toUtf8(), sysName);
329     QCOMPARE(dbusProperty<QString>(d.sysName(), "sysName"), sysName);
330     QCOMPARE(d.outputName().toUtf8(), outputName);
331     QCOMPARE(d.property("outputName").toString().toUtf8(), outputName);
332     QCOMPARE(dbusProperty<QString>(d.sysName(), "outputName"), outputName);
333 }
334 
testProduct()335 void TestLibinputDevice::testProduct()
336 {
337     // this test verifies the product property
338     libinput_device device;
339     device.product = 100u;
340     Device d(&device);
341     QCOMPARE(d.product(), 100u);
342     QCOMPARE(d.property("product").toUInt(), 100u);
343     QCOMPARE(dbusProperty<quint32>(d.sysName(), "product"), 100u);
344 }
345 
testVendor()346 void TestLibinputDevice::testVendor()
347 {
348     // this test verifies the vendor property
349     libinput_device device;
350     device.vendor = 200u;
351     Device d(&device);
352     QCOMPARE(d.vendor(), 200u);
353     QCOMPARE(d.property("vendor").toUInt(), 200u);
354     QCOMPARE(dbusProperty<quint32>(d.sysName(), "vendor"), 200u);
355 }
356 
testTapFingerCount()357 void TestLibinputDevice::testTapFingerCount()
358 {
359     // this test verifies the tap finger count property
360     libinput_device device;
361     device.tapFingerCount = 3;
362     Device d(&device);
363     QCOMPARE(d.tapFingerCount(), 3);
364     QCOMPARE(d.property("tapFingerCount").toInt(), 3);
365     QCOMPARE(dbusProperty<int>(d.sysName(), "tapFingerCount"), 3);
366 }
367 
testSize_data()368 void TestLibinputDevice::testSize_data()
369 {
370     QTest::addColumn<QSizeF>("setSize");
371     QTest::addColumn<int>("returnValue");
372     QTest::addColumn<QSizeF>("expectedSize");
373 
374     QTest::newRow("10/20") << QSizeF(10.5, 20.2) << 0 << QSizeF(10.5, 20.2);
375     QTest::newRow("failure") << QSizeF(10, 20) << 1 << QSizeF();
376 }
377 
testSize()378 void TestLibinputDevice::testSize()
379 {
380     // this test verifies that getting the size works correctly including failures
381     QFETCH(QSizeF, setSize);
382     QFETCH(int, returnValue);
383     libinput_device device;
384     device.deviceSize = setSize;
385     device.deviceSizeReturnValue = returnValue;
386 
387     Device d(&device);
388     QTEST(d.size(), "expectedSize");
389     QTEST(d.property("size").toSizeF(), "expectedSize");
390     QTEST(dbusProperty<QSizeF>(d.sysName(), "size"), "expectedSize");
391 }
392 
testLeftHandedEnabledByDefault_data()393 void TestLibinputDevice::testLeftHandedEnabledByDefault_data()
394 {
395     QTest::addColumn<bool>("enabled");
396 
397     QTest::newRow("enabled") << true;
398     QTest::newRow("disabled") << false;
399 }
400 
testLeftHandedEnabledByDefault()401 void TestLibinputDevice::testLeftHandedEnabledByDefault()
402 {
403     QFETCH(bool, enabled);
404     libinput_device device;
405     device.leftHandedEnabledByDefault = enabled;
406 
407     Device d(&device);
408     QCOMPARE(d.leftHandedEnabledByDefault(), enabled);
409     QCOMPARE(d.property("leftHandedEnabledByDefault").toBool(), enabled);
410     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHandedEnabledByDefault"), enabled);
411 }
412 
testTapEnabledByDefault_data()413 void TestLibinputDevice::testTapEnabledByDefault_data()
414 {
415     QTest::addColumn<bool>("enabled");
416 
417     QTest::newRow("enabled") << true;
418     QTest::newRow("disabled") << false;
419 }
420 
testTapEnabledByDefault()421 void TestLibinputDevice::testTapEnabledByDefault()
422 {
423     QFETCH(bool, enabled);
424     libinput_device device;
425     device.tapEnabledByDefault = enabled;
426 
427     Device d(&device);
428     QCOMPARE(d.tapToClickEnabledByDefault(), enabled);
429     QCOMPARE(d.property("tapToClickEnabledByDefault").toBool(), enabled);
430     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClickEnabledByDefault"), enabled);
431 }
432 
testMiddleEmulationEnabledByDefault_data()433 void TestLibinputDevice::testMiddleEmulationEnabledByDefault_data()
434 {
435     QTest::addColumn<bool>("enabled");
436 
437     QTest::newRow("enabled") << true;
438     QTest::newRow("disabled") << false;
439 }
440 
testMiddleEmulationEnabledByDefault()441 void TestLibinputDevice::testMiddleEmulationEnabledByDefault()
442 {
443     QFETCH(bool, enabled);
444     libinput_device device;
445     device.middleEmulationEnabledByDefault = enabled;
446 
447     Device d(&device);
448     QCOMPARE(d.middleEmulationEnabledByDefault(), enabled);
449     QCOMPARE(d.property("middleEmulationEnabledByDefault").toBool(), enabled);
450     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulationEnabledByDefault"), enabled);
451 }
452 
testNaturalScrollEnabledByDefault_data()453 void TestLibinputDevice::testNaturalScrollEnabledByDefault_data()
454 {
455     QTest::addColumn<bool>("enabled");
456 
457     QTest::newRow("enabled") << true;
458     QTest::newRow("disabled") << false;
459 }
460 
testNaturalScrollEnabledByDefault()461 void TestLibinputDevice::testNaturalScrollEnabledByDefault()
462 {
463     QFETCH(bool, enabled);
464     libinput_device device;
465     device.naturalScrollEnabledByDefault = enabled;
466 
467     Device d(&device);
468     QCOMPARE(d.naturalScrollEnabledByDefault(), enabled);
469     QCOMPARE(d.property("naturalScrollEnabledByDefault").toBool(), enabled);
470     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScrollEnabledByDefault"), enabled);
471 }
472 
testScrollTwoFingerEnabledByDefault_data()473 void TestLibinputDevice::testScrollTwoFingerEnabledByDefault_data()
474 {
475     QTest::addColumn<bool>("enabled");
476 
477     QTest::newRow("enabled") << true;
478     QTest::newRow("disabled") << false;
479 }
480 
testScrollTwoFingerEnabledByDefault()481 void TestLibinputDevice::testScrollTwoFingerEnabledByDefault()
482 {
483     QFETCH(bool, enabled);
484     libinput_device device;
485     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
486 
487     Device d(&device);
488     QCOMPARE(d.scrollTwoFingerEnabledByDefault(), enabled);
489     QCOMPARE(d.property("scrollTwoFingerEnabledByDefault").toBool(), enabled);
490     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFingerEnabledByDefault"), enabled);
491 }
492 
testScrollEdgeEnabledByDefault_data()493 void TestLibinputDevice::testScrollEdgeEnabledByDefault_data()
494 {
495     QTest::addColumn<bool>("enabled");
496 
497     QTest::newRow("enabled") << true;
498     QTest::newRow("disabled") << false;
499 }
500 
testScrollEdgeEnabledByDefault()501 void TestLibinputDevice::testScrollEdgeEnabledByDefault()
502 {
503     QFETCH(bool, enabled);
504     libinput_device device;
505     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
506 
507     Device d(&device);
508     QCOMPARE(d.scrollEdgeEnabledByDefault(), enabled);
509     QCOMPARE(d.property("scrollEdgeEnabledByDefault").toBool(), enabled);
510     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdgeEnabledByDefault"), enabled);
511 }
512 
testDefaultPointerAccelerationProfileFlat_data()513 void TestLibinputDevice::testDefaultPointerAccelerationProfileFlat_data()
514 {
515     QTest::addColumn<bool>("enabled");
516 
517     QTest::newRow("enabled") << true;
518     QTest::newRow("disabled") << false;
519 }
520 
testDefaultPointerAccelerationProfileFlat()521 void TestLibinputDevice::testDefaultPointerAccelerationProfileFlat()
522 {
523     QFETCH(bool, enabled);
524     libinput_device device;
525     device.defaultPointerAccelerationProfile = enabled ? LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT : LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
526 
527     Device d(&device);
528     QCOMPARE(d.defaultPointerAccelerationProfileFlat(), enabled);
529     QCOMPARE(d.property("defaultPointerAccelerationProfileFlat").toBool(), enabled);
530     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultPointerAccelerationProfileFlat"), enabled);
531 }
532 
testDefaultPointerAccelerationProfileAdaptive_data()533 void TestLibinputDevice::testDefaultPointerAccelerationProfileAdaptive_data()
534 {
535     QTest::addColumn<bool>("enabled");
536 
537     QTest::newRow("enabled") << true;
538     QTest::newRow("disabled") << false;
539 }
540 
testDefaultPointerAccelerationProfileAdaptive()541 void TestLibinputDevice::testDefaultPointerAccelerationProfileAdaptive()
542 {
543     QFETCH(bool, enabled);
544     libinput_device device;
545     device.defaultPointerAccelerationProfile = enabled ? LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE : LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
546 
547     Device d(&device);
548     QCOMPARE(d.defaultPointerAccelerationProfileAdaptive(), enabled);
549     QCOMPARE(d.property("defaultPointerAccelerationProfileAdaptive").toBool(), enabled);
550     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultPointerAccelerationProfileAdaptive"), enabled);
551 }
552 
testDefaultClickMethodAreas_data()553 void TestLibinputDevice::testDefaultClickMethodAreas_data()
554 {
555     QTest::addColumn<bool>("enabled");
556 
557     QTest::addRow("enabled") << true;
558     QTest::addRow("disabled") << false;
559 }
560 
testDefaultClickMethodAreas()561 void TestLibinputDevice::testDefaultClickMethodAreas()
562 {
563     QFETCH(bool, enabled);
564     libinput_device device;
565     device.defaultClickMethod = enabled ? LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS : LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
566 
567     Device d(&device);
568     QCOMPARE(d.defaultClickMethodAreas(), enabled);
569     QCOMPARE(d.property("defaultClickMethodAreas").toBool(), enabled);
570     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultClickMethodAreas"), enabled);
571 }
572 
testDefaultClickMethodClickfinger_data()573 void TestLibinputDevice::testDefaultClickMethodClickfinger_data()
574 {
575     QTest::addColumn<bool>("enabled");
576 
577     QTest::addRow("enabled") << true;
578     QTest::addRow("disabled") << false;
579 }
580 
testDefaultClickMethodClickfinger()581 void TestLibinputDevice::testDefaultClickMethodClickfinger()
582 {
583     QFETCH(bool, enabled);
584     libinput_device device;
585     device.defaultClickMethod = enabled ? LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER : LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
586 
587     Device d(&device);
588     QCOMPARE(d.defaultClickMethodClickfinger(), enabled);
589     QCOMPARE(d.property("defaultClickMethodClickfinger").toBool(), enabled);
590     QCOMPARE(dbusProperty<bool>(d.sysName(), "defaultClickMethodClickfinger"), enabled);
591 }
592 
testScrollOnButtonDownEnabledByDefault_data()593 void TestLibinputDevice::testScrollOnButtonDownEnabledByDefault_data()
594 {
595     QTest::addColumn<bool>("enabled");
596 
597     QTest::newRow("enabled") << true;
598     QTest::newRow("disabled") << false;
599 }
600 
testScrollOnButtonDownEnabledByDefault()601 void TestLibinputDevice::testScrollOnButtonDownEnabledByDefault()
602 {
603     QFETCH(bool, enabled);
604     libinput_device device;
605     device.defaultScrollMethod = enabled ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
606 
607     Device d(&device);
608     QCOMPARE(d.scrollOnButtonDownEnabledByDefault(), enabled);
609     QCOMPARE(d.property("scrollOnButtonDownEnabledByDefault").toBool(), enabled);
610     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDownEnabledByDefault"), enabled);
611 }
612 
testDefaultScrollButton_data()613 void TestLibinputDevice::testDefaultScrollButton_data()
614 {
615     QTest::addColumn<quint32>("button");
616 
617     QTest::newRow("0") << 0u;
618     QTest::newRow("BTN_LEFT") << quint32(BTN_LEFT);
619     QTest::newRow("BTN_RIGHT") << quint32(BTN_RIGHT);
620     QTest::newRow("BTN_MIDDLE") << quint32(BTN_MIDDLE);
621     QTest::newRow("BTN_SIDE") << quint32(BTN_SIDE);
622     QTest::newRow("BTN_EXTRA") << quint32(BTN_EXTRA);
623     QTest::newRow("BTN_FORWARD") << quint32(BTN_FORWARD);
624     QTest::newRow("BTN_BACK") << quint32(BTN_BACK);
625     QTest::newRow("BTN_TASK") << quint32(BTN_TASK);
626 }
627 
testDefaultScrollButton()628 void TestLibinputDevice::testDefaultScrollButton()
629 {
630     libinput_device device;
631     QFETCH(quint32, button);
632     device.defaultScrollButton = button;
633 
634     Device d(&device);
635     QCOMPARE(d.defaultScrollButton(), button);
636     QCOMPARE(d.property("defaultScrollButton").value<quint32>(), button);
637     QCOMPARE(dbusProperty<quint32>(d.sysName(), "defaultScrollButton"), button);
638 }
639 
testSupportsDisableWhileTyping_data()640 void TestLibinputDevice::testSupportsDisableWhileTyping_data()
641 {
642     QTest::addColumn<bool>("enabled");
643 
644     QTest::newRow("enabled") << true;
645     QTest::newRow("disabled") << false;
646 }
647 
testSupportsDisableWhileTyping()648 void TestLibinputDevice::testSupportsDisableWhileTyping()
649 {
650     QFETCH(bool, enabled);
651     libinput_device device;
652     device.supportsDisableWhileTyping = enabled;
653 
654     Device d(&device);
655     QCOMPARE(d.supportsDisableWhileTyping(), enabled);
656     QCOMPARE(d.property("supportsDisableWhileTyping").toBool(), enabled);
657     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableWhileTyping"), enabled);
658 }
659 
testSupportsPointerAcceleration_data()660 void TestLibinputDevice::testSupportsPointerAcceleration_data()
661 {
662     QTest::addColumn<bool>("enabled");
663 
664     QTest::newRow("enabled") << true;
665     QTest::newRow("disabled") << false;
666 }
667 
testSupportsPointerAcceleration()668 void TestLibinputDevice::testSupportsPointerAcceleration()
669 {
670     QFETCH(bool, enabled);
671     libinput_device device;
672     device.supportsPointerAcceleration = enabled;
673 
674     Device d(&device);
675     QCOMPARE(d.supportsPointerAcceleration(), enabled);
676     QCOMPARE(d.property("supportsPointerAcceleration").toBool(), enabled);
677     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsPointerAcceleration"), enabled);
678 }
679 
testSupportsLeftHanded_data()680 void TestLibinputDevice::testSupportsLeftHanded_data()
681 {
682     QTest::addColumn<bool>("enabled");
683 
684     QTest::newRow("enabled") << true;
685     QTest::newRow("disabled") << false;
686 }
687 
testSupportsLeftHanded()688 void TestLibinputDevice::testSupportsLeftHanded()
689 {
690     QFETCH(bool, enabled);
691     libinput_device device;
692     device.supportsLeftHanded = enabled;
693 
694     Device d(&device);
695     QCOMPARE(d.supportsLeftHanded(), enabled);
696     QCOMPARE(d.property("supportsLeftHanded").toBool(), enabled);
697     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsLeftHanded"), enabled);
698 }
699 
testSupportsCalibrationMatrix_data()700 void TestLibinputDevice::testSupportsCalibrationMatrix_data()
701 {
702     QTest::addColumn<bool>("enabled");
703 
704     QTest::newRow("enabled") << true;
705     QTest::newRow("disabled") << false;
706 }
707 
testSupportsCalibrationMatrix()708 void TestLibinputDevice::testSupportsCalibrationMatrix()
709 {
710     QFETCH(bool, enabled);
711     libinput_device device;
712     device.supportsCalibrationMatrix = enabled;
713 
714     Device d(&device);
715     QCOMPARE(d.supportsCalibrationMatrix(), enabled);
716     QCOMPARE(d.property("supportsCalibrationMatrix").toBool(), enabled);
717     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsCalibrationMatrix"), enabled);
718 }
719 
testSupportsDisableEvents_data()720 void TestLibinputDevice::testSupportsDisableEvents_data()
721 {
722     QTest::addColumn<bool>("enabled");
723 
724     QTest::newRow("enabled") << true;
725     QTest::newRow("disabled") << false;
726 }
727 
testSupportsDisableEvents()728 void TestLibinputDevice::testSupportsDisableEvents()
729 {
730     QFETCH(bool, enabled);
731     libinput_device device;
732     device.supportsDisableEvents = enabled;
733 
734     Device d(&device);
735     QCOMPARE(d.supportsDisableEvents(), enabled);
736     QCOMPARE(d.property("supportsDisableEvents").toBool(), enabled);
737     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableEvents"), enabled);
738 }
739 
testSupportsDisableEventsOnExternalMouse_data()740 void TestLibinputDevice::testSupportsDisableEventsOnExternalMouse_data()
741 {
742     QTest::addColumn<bool>("enabled");
743 
744     QTest::newRow("enabled") << true;
745     QTest::newRow("disabled") << false;
746 }
747 
testSupportsDisableEventsOnExternalMouse()748 void TestLibinputDevice::testSupportsDisableEventsOnExternalMouse()
749 {
750     QFETCH(bool, enabled);
751     libinput_device device;
752     device.supportsDisableEventsOnExternalMouse = enabled;
753 
754     Device d(&device);
755     QCOMPARE(d.supportsDisableEventsOnExternalMouse(), enabled);
756     QCOMPARE(d.property("supportsDisableEventsOnExternalMouse").toBool(), enabled);
757     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsDisableEventsOnExternalMouse"), enabled);
758 }
759 
testSupportsMiddleEmulation_data()760 void TestLibinputDevice::testSupportsMiddleEmulation_data()
761 {
762     QTest::addColumn<bool>("enabled");
763 
764     QTest::newRow("enabled") << true;
765     QTest::newRow("disabled") << false;
766 }
767 
testSupportsMiddleEmulation()768 void TestLibinputDevice::testSupportsMiddleEmulation()
769 {
770     QFETCH(bool, enabled);
771     libinput_device device;
772     device.supportsMiddleEmulation = enabled;
773 
774     Device d(&device);
775     QCOMPARE(d.supportsMiddleEmulation(), enabled);
776     QCOMPARE(d.property("supportsMiddleEmulation").toBool(), enabled);
777     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsMiddleEmulation"), enabled);
778 }
779 
testSupportsNaturalScroll_data()780 void TestLibinputDevice::testSupportsNaturalScroll_data()
781 {
782     QTest::addColumn<bool>("enabled");
783 
784     QTest::newRow("enabled") << true;
785     QTest::newRow("disabled") << false;
786 }
787 
testSupportsNaturalScroll()788 void TestLibinputDevice::testSupportsNaturalScroll()
789 {
790     QFETCH(bool, enabled);
791     libinput_device device;
792     device.supportsNaturalScroll = enabled;
793 
794     Device d(&device);
795     QCOMPARE(d.supportsNaturalScroll(), enabled);
796     QCOMPARE(d.property("supportsNaturalScroll").toBool(), enabled);
797     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsNaturalScroll"), enabled);
798 }
799 
testSupportsScrollTwoFinger_data()800 void TestLibinputDevice::testSupportsScrollTwoFinger_data()
801 {
802     QTest::addColumn<bool>("enabled");
803 
804     QTest::newRow("enabled") << true;
805     QTest::newRow("disabled") << false;
806 }
807 
testSupportsScrollTwoFinger()808 void TestLibinputDevice::testSupportsScrollTwoFinger()
809 {
810     QFETCH(bool, enabled);
811     libinput_device device;
812     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
813 
814     Device d(&device);
815     QCOMPARE(d.supportsScrollTwoFinger(), enabled);
816     QCOMPARE(d.property("supportsScrollTwoFinger").toBool(), enabled);
817     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollTwoFinger"), enabled);
818 }
819 
testSupportsScrollEdge_data()820 void TestLibinputDevice::testSupportsScrollEdge_data()
821 {
822     QTest::addColumn<bool>("enabled");
823 
824     QTest::newRow("enabled") << true;
825     QTest::newRow("disabled") << false;
826 }
827 
testSupportsScrollEdge()828 void TestLibinputDevice::testSupportsScrollEdge()
829 {
830     QFETCH(bool, enabled);
831     libinput_device device;
832     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
833 
834     Device d(&device);
835     QCOMPARE(d.supportsScrollEdge(), enabled);
836     QCOMPARE(d.property("supportsScrollEdge").toBool(), enabled);
837     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollEdge"), enabled);
838 }
839 
testSupportsScrollOnButtonDown_data()840 void TestLibinputDevice::testSupportsScrollOnButtonDown_data()
841 {
842     QTest::addColumn<bool>("enabled");
843 
844     QTest::newRow("enabled") << true;
845     QTest::newRow("disabled") << false;
846 }
847 
testSupportsScrollOnButtonDown()848 void TestLibinputDevice::testSupportsScrollOnButtonDown()
849 {
850     QFETCH(bool, enabled);
851     libinput_device device;
852     device.supportedScrollMethods = enabled ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
853 
854     Device d(&device);
855     QCOMPARE(d.supportsScrollOnButtonDown(), enabled);
856     QCOMPARE(d.property("supportsScrollOnButtonDown").toBool(), enabled);
857     QCOMPARE(dbusProperty<bool>(d.sysName(), "supportsScrollOnButtonDown"), enabled);
858 }
859 
testDefaultPointerAcceleration_data()860 void TestLibinputDevice::testDefaultPointerAcceleration_data()
861 {
862     QTest::addColumn<qreal>("accel");
863 
864     QTest::newRow("-1.0") << -1.0;
865     QTest::newRow("-0.5") << -0.5;
866     QTest::newRow("0.0") << 0.0;
867     QTest::newRow("0.3") << 0.3;
868     QTest::newRow("1.0") << 1.0;
869 }
870 
testDefaultPointerAcceleration()871 void TestLibinputDevice::testDefaultPointerAcceleration()
872 {
873     QFETCH(qreal, accel);
874     libinput_device device;
875     device.defaultPointerAcceleration = accel;
876 
877     Device d(&device);
878     QCOMPARE(d.defaultPointerAcceleration(), accel);
879     QCOMPARE(d.property("defaultPointerAcceleration").toReal(), accel);
880     QCOMPARE(dbusProperty<qreal>(d.sysName(), "defaultPointerAcceleration"), accel);
881 }
882 
testPointerAcceleration_data()883 void TestLibinputDevice::testPointerAcceleration_data()
884 {
885     QTest::addColumn<bool>("supported");
886     QTest::addColumn<bool>("setShouldFail");
887     QTest::addColumn<qreal>("accel");
888     QTest::addColumn<qreal>("setAccel");
889     QTest::addColumn<qreal>("expectedAccel");
890     QTest::addColumn<bool>("expectedChanged");
891 
892     QTest::newRow("-1 -> 2.0") << true << false << -1.0 << 2.0 << 1.0 << true;
893     QTest::newRow("0 -> -1.0") << true << false << 0.0 << -1.0 << -1.0 << true;
894     QTest::newRow("1 -> 1") << true << false << 1.0 << 1.0 << 1.0 << false;
895     QTest::newRow("unsupported") << false << false << 0.0 << 1.0 << 0.0 << false;
896     QTest::newRow("set fails") << true << true << -1.0 << 1.0 << -1.0 << false;
897 }
898 
testPointerAcceleration()899 void TestLibinputDevice::testPointerAcceleration()
900 {
901     QFETCH(bool, supported);
902     QFETCH(bool, setShouldFail);
903     QFETCH(qreal, accel);
904     libinput_device device;
905     device.supportsPointerAcceleration = supported;
906     device.pointerAcceleration = accel;
907     device.setPointerAccelerationReturnValue = setShouldFail;
908 
909     Device d(&device);
910     QCOMPARE(d.pointerAcceleration(), accel);
911     QCOMPARE(d.property("pointerAcceleration").toReal(), accel);
912     QCOMPARE(dbusProperty<qreal>(d.sysName(), "pointerAcceleration"), accel);
913 
914     QSignalSpy pointerAccelChangedSpy(&d, &Device::pointerAccelerationChanged);
915     QVERIFY(pointerAccelChangedSpy.isValid());
916     QFETCH(qreal, setAccel);
917     d.setPointerAcceleration(setAccel);
918     QTEST(d.pointerAcceleration(), "expectedAccel");
919     QTEST(!pointerAccelChangedSpy.isEmpty(), "expectedChanged");
920     QTEST(dbusProperty<qreal>(d.sysName(), "pointerAcceleration"), "expectedAccel");
921 }
922 
testLeftHanded_data()923 void TestLibinputDevice::testLeftHanded_data()
924 {
925     QTest::addColumn<bool>("supported");
926     QTest::addColumn<bool>("setShouldFail");
927     QTest::addColumn<bool>("initValue");
928     QTest::addColumn<bool>("setValue");
929     QTest::addColumn<bool>("expectedValue");
930 
931     QTest::newRow("unsupported/true") << false << false << true << false << false;
932     QTest::newRow("unsupported/false") << false << false << false << true << false;
933     QTest::newRow("true -> false") << true << false << true << false << false;
934     QTest::newRow("false -> true") << true << false << false << true  << true;
935     QTest::newRow("set fails") << true << true << true << false << true;
936     QTest::newRow("true -> true") << true << false << true << true << true;
937     QTest::newRow("false -> false") << true << false << false << false << false;
938 }
939 
testLeftHanded()940 void TestLibinputDevice::testLeftHanded()
941 {
942     QFETCH(bool, supported);
943     QFETCH(bool, setShouldFail);
944     QFETCH(bool, initValue);
945     libinput_device device;
946     device.supportsLeftHanded = supported;
947     device.leftHanded = initValue;
948     device.setLeftHandedReturnValue = setShouldFail;
949 
950     Device d(&device);
951     QCOMPARE(d.isLeftHanded(), supported && initValue);
952     QCOMPARE(d.property("leftHanded").toBool(), supported && initValue);
953     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHanded"), supported && initValue);
954 
955     QSignalSpy leftHandedChangedSpy(&d, &Device::leftHandedChanged);
956     QVERIFY(leftHandedChangedSpy.isValid());
957     QFETCH(bool, setValue);
958     d.setLeftHanded(setValue);
959     QFETCH(bool, expectedValue);
960     QCOMPARE(d.isLeftHanded(), expectedValue);
961     QCOMPARE(leftHandedChangedSpy.isEmpty(), (supported && initValue) == expectedValue);
962     QCOMPARE(dbusProperty<bool>(d.sysName(), "leftHanded"), expectedValue);
963 }
964 
testSupportedButtons_data()965 void TestLibinputDevice::testSupportedButtons_data()
966 {
967     QTest::addColumn<bool>("isPointer");
968     QTest::addColumn<Qt::MouseButtons>("setButtons");
969     QTest::addColumn<Qt::MouseButtons>("expectedButtons");
970 
971     QTest::newRow("left")    << true << Qt::MouseButtons(Qt::LeftButton)    << Qt::MouseButtons(Qt::LeftButton);
972     QTest::newRow("right")   << true << Qt::MouseButtons(Qt::RightButton)   << Qt::MouseButtons(Qt::RightButton);
973     QTest::newRow("middle")  << true << Qt::MouseButtons(Qt::MiddleButton)  << Qt::MouseButtons(Qt::MiddleButton);
974     QTest::newRow("extra1")  << true << Qt::MouseButtons(Qt::ExtraButton1)  << Qt::MouseButtons(Qt::ExtraButton1);
975     QTest::newRow("extra2")  << true << Qt::MouseButtons(Qt::ExtraButton2)  << Qt::MouseButtons(Qt::ExtraButton2);
976     QTest::newRow("back")    << true << Qt::MouseButtons(Qt::BackButton)    << Qt::MouseButtons(Qt::BackButton);
977     QTest::newRow("forward") << true << Qt::MouseButtons(Qt::ForwardButton) << Qt::MouseButtons(Qt::ForwardButton);
978     QTest::newRow("task")    << true << Qt::MouseButtons(Qt::TaskButton)    << Qt::MouseButtons(Qt::TaskButton);
979 
980     QTest::newRow("no pointer/left")    << false << Qt::MouseButtons(Qt::LeftButton)    << Qt::MouseButtons();
981     QTest::newRow("no pointer/right")   << false << Qt::MouseButtons(Qt::RightButton)   << Qt::MouseButtons();
982     QTest::newRow("no pointer/middle")  << false << Qt::MouseButtons(Qt::MiddleButton)  << Qt::MouseButtons();
983     QTest::newRow("no pointer/extra1")  << false << Qt::MouseButtons(Qt::ExtraButton1)  << Qt::MouseButtons();
984     QTest::newRow("no pointer/extra2")  << false << Qt::MouseButtons(Qt::ExtraButton2)  << Qt::MouseButtons();
985     QTest::newRow("no pointer/back")    << false << Qt::MouseButtons(Qt::BackButton)    << Qt::MouseButtons();
986     QTest::newRow("no pointer/forward") << false << Qt::MouseButtons(Qt::ForwardButton) << Qt::MouseButtons();
987     QTest::newRow("no pointer/task")    << false << Qt::MouseButtons(Qt::TaskButton)    << Qt::MouseButtons();
988 
989     QTest::newRow("all") << true
990                          << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton | Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::BackButton | Qt::ForwardButton | Qt::TaskButton)
991                          << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton | Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::BackButton | Qt::ForwardButton | Qt::TaskButton);
992 }
993 
testSupportedButtons()994 void TestLibinputDevice::testSupportedButtons()
995 {
996     libinput_device device;
997     QFETCH(bool, isPointer);
998     device.pointer = isPointer;
999     QFETCH(Qt::MouseButtons, setButtons);
1000     device.supportedButtons = setButtons;
1001 
1002     Device d(&device);
1003     QCOMPARE(d.isPointer(), isPointer);
1004     QTEST(d.supportedButtons(), "expectedButtons");
1005     QTEST(Qt::MouseButtons(dbusProperty<int>(d.sysName(), "supportedButtons")), "expectedButtons");
1006 }
1007 
testAlphaNumericKeyboard_data()1008 void TestLibinputDevice::testAlphaNumericKeyboard_data()
1009 {
1010     QTest::addColumn<QVector<quint32>>("supportedKeys");
1011     QTest::addColumn<bool>("isAlpha");
1012 
1013     QVector<quint32> keys;
1014 
1015     for (int i = KEY_1; i <= KEY_0; i++) {
1016         keys << i;
1017         QByteArray row = QByteArrayLiteral("number");
1018         row.append(QByteArray::number(i));
1019         QTest::newRow(row.constData()) << keys << false;
1020     }
1021     for (int i = KEY_Q; i <= KEY_P; i++) {
1022         keys << i;
1023         QByteArray row = QByteArrayLiteral("alpha");
1024         row.append(QByteArray::number(i));
1025         QTest::newRow(row.constData()) << keys << false;
1026     }
1027     for (int i = KEY_A; i <= KEY_L; i++) {
1028         keys << i;
1029         QByteArray row = QByteArrayLiteral("alpha");
1030         row.append(QByteArray::number(i));
1031         QTest::newRow(row.constData()) << keys << false;
1032     }
1033     for (int i = KEY_Z; i < KEY_M; i++) {
1034         keys << i;
1035         QByteArray row = QByteArrayLiteral("alpha");
1036         row.append(QByteArray::number(i));
1037         QTest::newRow(row.constData()) << keys << false;
1038     }
1039     // adding a different key should not result in it becoming alphanumeric keyboard
1040     keys << KEY_SEMICOLON;
1041     QTest::newRow("semicolon") << keys << false;
1042 
1043     // last but not least the M which should turn everything on
1044     keys << KEY_M;
1045     QTest::newRow("alphanumeric") << keys << true;
1046 }
1047 
testAlphaNumericKeyboard()1048 void TestLibinputDevice::testAlphaNumericKeyboard()
1049 {
1050     QFETCH(QVector<quint32>, supportedKeys);
1051     libinput_device device;
1052     device.keyboard = true;
1053     device.keys = supportedKeys;
1054 
1055     Device d(&device);
1056     QCOMPARE(d.isKeyboard(), true);
1057     QTEST(d.isAlphaNumericKeyboard(), "isAlpha");
1058     QTEST(dbusProperty<bool>(d.sysName(), "alphaNumericKeyboard"), "isAlpha");
1059 }
1060 
1061 
testEnabled_data()1062 void TestLibinputDevice::testEnabled_data()
1063 {
1064     QTest::addColumn<bool>("supported");
1065     QTest::addColumn<bool>("setShouldFail");
1066     QTest::addColumn<bool>("initValue");
1067     QTest::addColumn<bool>("setValue");
1068     QTest::addColumn<bool>("expectedValue");
1069 
1070     QTest::newRow("unsupported/true") << false << false << true << false << true;
1071     QTest::newRow("unsupported/false") << false << false << false << true << true;
1072     QTest::newRow("true -> false") << true << false << true << false << false;
1073     QTest::newRow("false -> true") << true << false << false << true  << true;
1074     QTest::newRow("set fails") << true << true << true << false << true;
1075     QTest::newRow("true -> true") << true << false << true << true << true;
1076     QTest::newRow("false -> false") << true << false << false << false << false;
1077 }
1078 
testEnabled()1079 void TestLibinputDevice::testEnabled()
1080 {
1081     libinput_device device;
1082     QFETCH(bool, supported);
1083     QFETCH(bool, setShouldFail);
1084     QFETCH(bool, initValue);
1085     device.supportsDisableEvents = supported;
1086     device.enabled = initValue;
1087     device.setEnableModeReturnValue = setShouldFail;
1088 
1089     Device d(&device);
1090     QCOMPARE(d.isEnabled(), !supported || initValue);
1091     QCOMPARE(d.property("enabled").toBool(), !supported || initValue);
1092     QCOMPARE(dbusProperty<bool>(d.sysName(), "enabled"), !supported || initValue);
1093 
1094     QSignalSpy enabledChangedSpy(&d, &Device::enabledChanged);
1095     QVERIFY(enabledChangedSpy.isValid());
1096     QFETCH(bool, setValue);
1097     d.setEnabled(setValue);
1098     QFETCH(bool, expectedValue);
1099     QCOMPARE(d.isEnabled(), expectedValue);
1100 
1101     QCOMPARE(dbusProperty<bool>(d.sysName(), "enabled"), expectedValue);
1102 }
1103 
testTapToClick_data()1104 void TestLibinputDevice::testTapToClick_data()
1105 {
1106     QTest::addColumn<int>("fingerCount");
1107     QTest::addColumn<bool>("initValue");
1108     QTest::addColumn<bool>("setValue");
1109     QTest::addColumn<bool>("setShouldFail");
1110     QTest::addColumn<bool>("expectedValue");
1111 
1112     QTest::newRow("unsupported") << 0 << false << true << true << false;
1113     QTest::newRow("true -> false") << 1 << true << false << false << false;
1114     QTest::newRow("false -> true") << 2 << false << true << false << true;
1115     QTest::newRow("set fails") << 3 << true << false << true << true;
1116     QTest::newRow("true -> true") << 2 << true << true << false << true;
1117     QTest::newRow("false -> false") << 1 << false << false << false << false;
1118 }
1119 
testTapToClick()1120 void TestLibinputDevice::testTapToClick()
1121 {
1122     libinput_device device;
1123     QFETCH(int, fingerCount);
1124     QFETCH(bool, initValue);
1125     QFETCH(bool, setShouldFail);
1126     device.tapFingerCount = fingerCount;
1127     device.tapToClick = initValue;
1128     device.setTapToClickReturnValue = setShouldFail;
1129 
1130     Device d(&device);
1131     QCOMPARE(d.tapFingerCount(), fingerCount);
1132     QCOMPARE(d.isTapToClick(), initValue);
1133     QCOMPARE(d.property("tapToClick").toBool(), initValue);
1134     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClick"), initValue);
1135 
1136     QSignalSpy tapToClickChangedSpy(&d, &Device::tapToClickChanged);
1137     QVERIFY(tapToClickChangedSpy.isValid());
1138     QFETCH(bool, setValue);
1139     d.setTapToClick(setValue);
1140     QFETCH(bool, expectedValue);
1141     QCOMPARE(d.isTapToClick(), expectedValue);
1142     QCOMPARE(tapToClickChangedSpy.isEmpty(), initValue == expectedValue);
1143     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapToClick"), expectedValue);
1144 }
1145 
testTapAndDragEnabledByDefault_data()1146 void TestLibinputDevice::testTapAndDragEnabledByDefault_data()
1147 {
1148     QTest::addColumn<bool>("enabled");
1149 
1150     QTest::newRow("enabled") << true;
1151     QTest::newRow("disabled") << false;
1152 }
1153 
testTapAndDragEnabledByDefault()1154 void TestLibinputDevice::testTapAndDragEnabledByDefault()
1155 {
1156     QFETCH(bool, enabled);
1157     libinput_device device;
1158     device.tapAndDragEnabledByDefault = enabled;
1159 
1160     Device d(&device);
1161     QCOMPARE(d.tapAndDragEnabledByDefault(), enabled);
1162     QCOMPARE(d.property("tapAndDragEnabledByDefault").toBool(), enabled);
1163     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDragEnabledByDefault"), enabled);
1164 }
1165 
testTapAndDrag_data()1166 void TestLibinputDevice::testTapAndDrag_data()
1167 {
1168     QTest::addColumn<bool>("initValue");
1169     QTest::addColumn<bool>("setValue");
1170     QTest::addColumn<bool>("setShouldFail");
1171     QTest::addColumn<bool>("expectedValue");
1172 
1173     QTest::newRow("true -> false") << true << false << false << false;
1174     QTest::newRow("false -> true") << false << true << false << true;
1175     QTest::newRow("set fails") << true << false << true << true;
1176     QTest::newRow("true -> true") << true << true << false << true;
1177     QTest::newRow("false -> false") << false << false << false << false;
1178 }
1179 
testTapAndDrag()1180 void TestLibinputDevice::testTapAndDrag()
1181 {
1182     libinput_device device;
1183     QFETCH(bool, initValue);
1184     QFETCH(bool, setShouldFail);
1185     device.tapAndDrag = initValue;
1186     device.setTapAndDragReturnValue = setShouldFail;
1187 
1188     Device d(&device);
1189     QCOMPARE(d.isTapAndDrag(), initValue);
1190     QCOMPARE(d.property("tapAndDrag").toBool(), initValue);
1191     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDrag"), initValue);
1192 
1193     QSignalSpy tapAndDragChangedSpy(&d, &Device::tapAndDragChanged);
1194     QVERIFY(tapAndDragChangedSpy.isValid());
1195     QFETCH(bool, setValue);
1196     d.setTapAndDrag(setValue);
1197     QFETCH(bool, expectedValue);
1198     QCOMPARE(d.isTapAndDrag(), expectedValue);
1199     QCOMPARE(tapAndDragChangedSpy.isEmpty(), initValue == expectedValue);
1200     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapAndDrag"), expectedValue);
1201 }
1202 
testTapDragLockEnabledByDefault_data()1203 void TestLibinputDevice::testTapDragLockEnabledByDefault_data()
1204 {
1205     QTest::addColumn<bool>("enabled");
1206 
1207     QTest::newRow("enabled") << true;
1208     QTest::newRow("disabled") << false;
1209 }
1210 
testTapDragLockEnabledByDefault()1211 void TestLibinputDevice::testTapDragLockEnabledByDefault()
1212 {
1213     QFETCH(bool, enabled);
1214     libinput_device device;
1215     device.tapDragLockEnabledByDefault = enabled;
1216 
1217     Device d(&device);
1218     QCOMPARE(d.tapDragLockEnabledByDefault(), enabled);
1219     QCOMPARE(d.property("tapDragLockEnabledByDefault").toBool(), enabled);
1220     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLockEnabledByDefault"), enabled);
1221 }
1222 
testTapDragLock_data()1223 void TestLibinputDevice::testTapDragLock_data()
1224 {
1225     QTest::addColumn<bool>("initValue");
1226     QTest::addColumn<bool>("setValue");
1227     QTest::addColumn<bool>("setShouldFail");
1228     QTest::addColumn<bool>("expectedValue");
1229 
1230     QTest::newRow("true -> false") << true << false << false << false;
1231     QTest::newRow("false -> true") << false << true << false << true;
1232     QTest::newRow("set fails") << true << false << true << true;
1233     QTest::newRow("true -> true") << true << true << false << true;
1234     QTest::newRow("false -> false") << false << false << false << false;
1235 }
1236 
testTapDragLock()1237 void TestLibinputDevice::testTapDragLock()
1238 {
1239     libinput_device device;
1240     QFETCH(bool, initValue);
1241     QFETCH(bool, setShouldFail);
1242     device.tapDragLock = initValue;
1243     device.setTapDragLockReturnValue = setShouldFail;
1244 
1245     Device d(&device);
1246     QCOMPARE(d.isTapDragLock(), initValue);
1247     QCOMPARE(d.property("tapDragLock").toBool(), initValue);
1248     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLock"), initValue);
1249 
1250     QSignalSpy tapDragLockChangedSpy(&d, &Device::tapDragLockChanged);
1251     QVERIFY(tapDragLockChangedSpy.isValid());
1252     QFETCH(bool, setValue);
1253     d.setTapDragLock(setValue);
1254     QFETCH(bool, expectedValue);
1255     QCOMPARE(d.isTapDragLock(), expectedValue);
1256     QCOMPARE(tapDragLockChangedSpy.isEmpty(), initValue == expectedValue);
1257     QCOMPARE(dbusProperty<bool>(d.sysName(), "tapDragLock"), expectedValue);
1258 }
1259 
testMiddleEmulation_data()1260 void TestLibinputDevice::testMiddleEmulation_data()
1261 {
1262     QTest::addColumn<bool>("initValue");
1263     QTest::addColumn<bool>("setValue");
1264     QTest::addColumn<bool>("setShouldFail");
1265     QTest::addColumn<bool>("expectedValue");
1266     QTest::addColumn<bool>("supportsMiddleButton");
1267 
1268     QTest::newRow("true -> false") << true << false << false << false << true;
1269     QTest::newRow("false -> true") << false << true << false << true << true;
1270     QTest::newRow("set fails") << true << false << true << true << true;
1271     QTest::newRow("true -> true") << true << true << false << true << true;
1272     QTest::newRow("false -> false") << false << false << false << false << true;
1273 
1274     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1275 }
1276 
testMiddleEmulation()1277 void TestLibinputDevice::testMiddleEmulation()
1278 {
1279     libinput_device device;
1280     QFETCH(bool, initValue);
1281     QFETCH(bool, setShouldFail);
1282     QFETCH(bool, supportsMiddleButton);
1283     device.supportsMiddleEmulation = supportsMiddleButton;
1284     device.middleEmulation = initValue;
1285     device.setMiddleEmulationReturnValue = setShouldFail;
1286 
1287     Device d(&device);
1288     QCOMPARE(d.isMiddleEmulation(), initValue);
1289     QCOMPARE(d.property("middleEmulation").toBool(), initValue);
1290     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulation"), initValue);
1291 
1292     QSignalSpy middleEmulationChangedSpy(&d, &Device::middleEmulationChanged);
1293     QVERIFY(middleEmulationChangedSpy.isValid());
1294     QFETCH(bool, setValue);
1295     d.setMiddleEmulation(setValue);
1296     QFETCH(bool, expectedValue);
1297     QCOMPARE(d.isMiddleEmulation(), expectedValue);
1298     QCOMPARE(d.property("middleEmulation").toBool(), expectedValue);
1299     QCOMPARE(middleEmulationChangedSpy.isEmpty(), initValue == expectedValue);
1300     QCOMPARE(dbusProperty<bool>(d.sysName(), "middleEmulation"), expectedValue);
1301 }
1302 
testNaturalScroll_data()1303 void TestLibinputDevice::testNaturalScroll_data()
1304 {
1305     QTest::addColumn<bool>("initValue");
1306     QTest::addColumn<bool>("setValue");
1307     QTest::addColumn<bool>("setShouldFail");
1308     QTest::addColumn<bool>("expectedValue");
1309     QTest::addColumn<bool>("supportsNaturalScroll");
1310 
1311     QTest::newRow("true -> false") << true << false << false << false << true;
1312     QTest::newRow("false -> true") << false << true << false << true << true;
1313     QTest::newRow("set fails") << true << false << true << true << true;
1314     QTest::newRow("true -> true") << true << true << false << true << true;
1315     QTest::newRow("false -> false") << false << false << false << false << true;
1316 
1317     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1318 }
1319 
testNaturalScroll()1320 void TestLibinputDevice::testNaturalScroll()
1321 {
1322     libinput_device device;
1323     QFETCH(bool, initValue);
1324     QFETCH(bool, setShouldFail);
1325     QFETCH(bool, supportsNaturalScroll);
1326     device.supportsNaturalScroll = supportsNaturalScroll;
1327     device.naturalScroll = initValue;
1328     device.setNaturalScrollReturnValue = setShouldFail;
1329 
1330     Device d(&device);
1331     QCOMPARE(d.isNaturalScroll(), initValue);
1332     QCOMPARE(d.property("naturalScroll").toBool(), initValue);
1333     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScroll"), initValue);
1334 
1335     QSignalSpy naturalScrollChangedSpy(&d, &Device::naturalScrollChanged);
1336     QVERIFY(naturalScrollChangedSpy.isValid());
1337     QFETCH(bool, setValue);
1338     d.setNaturalScroll(setValue);
1339     QFETCH(bool, expectedValue);
1340     QCOMPARE(d.isNaturalScroll(), expectedValue);
1341     QCOMPARE(d.property("naturalScroll").toBool(), expectedValue);
1342     QCOMPARE(naturalScrollChangedSpy.isEmpty(), initValue == expectedValue);
1343     QCOMPARE(dbusProperty<bool>(d.sysName(), "naturalScroll"), expectedValue);
1344 }
1345 
testScrollFactor()1346 void TestLibinputDevice::testScrollFactor()
1347 {
1348     libinput_device device;
1349 
1350     qreal initValue = 1.0;
1351 
1352     Device d(&device);
1353     QCOMPARE(d.scrollFactor(), initValue);
1354     QCOMPARE(d.property("scrollFactor").toReal(), initValue);
1355     QCOMPARE(dbusProperty<qreal>(d.sysName(), "scrollFactor"), initValue);
1356 
1357     QSignalSpy scrollFactorChangedSpy(&d, &Device::scrollFactorChanged);
1358     QVERIFY(scrollFactorChangedSpy.isValid());
1359 
1360     qreal expectedValue = 2.0;
1361 
1362     d.setScrollFactor(expectedValue);
1363     QCOMPARE(d.scrollFactor(), expectedValue);
1364     QCOMPARE(d.property("scrollFactor").toReal(), expectedValue);
1365     QCOMPARE(scrollFactorChangedSpy.isEmpty(), false);
1366     QCOMPARE(dbusProperty<qreal>(d.sysName(), "scrollFactor"), expectedValue);
1367 }
1368 
testScrollTwoFinger_data()1369 void TestLibinputDevice::testScrollTwoFinger_data()
1370 {
1371     QTest::addColumn<bool>("initValue");
1372     QTest::addColumn<bool>("otherValue");
1373     QTest::addColumn<bool>("setValue");
1374     QTest::addColumn<bool>("setShouldFail");
1375     QTest::addColumn<bool>("expectedValue");
1376     QTest::addColumn<bool>("supportsScrollTwoFinger");
1377 
1378     QTest::newRow("true -> false") << true << false << false << false << false << true;
1379     QTest::newRow("other -> false") << false << true << false << false << false << true;
1380     QTest::newRow("false -> true") << false << false << true << false << true << true;
1381     QTest::newRow("set fails") << true << false << false << true << true << true;
1382     QTest::newRow("true -> true") << true << false << true << false << true << true;
1383     QTest::newRow("false -> false") << false << false << false << false << false << true;
1384 
1385     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1386 }
1387 
testScrollTwoFinger()1388 void TestLibinputDevice::testScrollTwoFinger()
1389 {
1390     libinput_device device;
1391     QFETCH(bool, initValue);
1392     QFETCH(bool, otherValue);
1393     QFETCH(bool, setShouldFail);
1394     QFETCH(bool, supportsScrollTwoFinger);
1395     device.supportedScrollMethods = (supportsScrollTwoFinger ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_EDGE;
1396     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_2FG : otherValue ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1397     device.setScrollMethodReturnValue = setShouldFail;
1398 
1399     Device d(&device);
1400     QCOMPARE(d.isScrollTwoFinger(), initValue);
1401     QCOMPARE(d.property("scrollTwoFinger").toBool(), initValue);
1402     QCOMPARE(d.property("scrollEdge").toBool(), otherValue);
1403     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), initValue);
1404     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), otherValue);
1405 
1406     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1407     QVERIFY(scrollMethodChangedSpy.isValid());
1408     QFETCH(bool, setValue);
1409     d.setScrollTwoFinger(setValue);
1410     QFETCH(bool, expectedValue);
1411     QCOMPARE(d.isScrollTwoFinger(), expectedValue);
1412     QCOMPARE(d.property("scrollTwoFinger").toBool(), expectedValue);
1413     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1414     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), expectedValue);
1415 }
1416 
testScrollEdge_data()1417 void TestLibinputDevice::testScrollEdge_data()
1418 {
1419     QTest::addColumn<bool>("initValue");
1420     QTest::addColumn<bool>("otherValue");
1421     QTest::addColumn<bool>("setValue");
1422     QTest::addColumn<bool>("setShouldFail");
1423     QTest::addColumn<bool>("expectedValue");
1424     QTest::addColumn<bool>("supportsScrollEdge");
1425 
1426     QTest::newRow("true -> false") << true << false << false << false << false << true;
1427     QTest::newRow("other -> false") << false << true << false << false << false << true;
1428     QTest::newRow("false -> true") << false << false << true << false << true << true;
1429     QTest::newRow("set fails") << true << false << false << true << true << true;
1430     QTest::newRow("true -> true") << true << false << true << false << true << true;
1431     QTest::newRow("false -> false") << false << false << false << false << false << true;
1432 
1433     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1434 }
1435 
testScrollEdge()1436 void TestLibinputDevice::testScrollEdge()
1437 {
1438     libinput_device device;
1439     QFETCH(bool, initValue);
1440     QFETCH(bool, otherValue);
1441     QFETCH(bool, setShouldFail);
1442     QFETCH(bool, supportsScrollEdge);
1443     device.supportedScrollMethods = (supportsScrollEdge ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_2FG;
1444     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_EDGE : otherValue ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1445     device.setScrollMethodReturnValue = setShouldFail;
1446 
1447     Device d(&device);
1448     QCOMPARE(d.isScrollEdge(), initValue);
1449     QCOMPARE(d.property("scrollEdge").toBool(), initValue);
1450     QCOMPARE(d.property("scrollTwoFinger").toBool(), otherValue);
1451     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), initValue);
1452     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), otherValue);
1453 
1454     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1455     QVERIFY(scrollMethodChangedSpy.isValid());
1456     QFETCH(bool, setValue);
1457     d.setScrollEdge(setValue);
1458     QFETCH(bool, expectedValue);
1459     QCOMPARE(d.isScrollEdge(), expectedValue);
1460     QCOMPARE(d.property("scrollEdge").toBool(), expectedValue);
1461     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1462     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollEdge"), expectedValue);
1463 }
1464 
testScrollButtonDown_data()1465 void TestLibinputDevice::testScrollButtonDown_data()
1466 {
1467     QTest::addColumn<bool>("initValue");
1468     QTest::addColumn<bool>("otherValue");
1469     QTest::addColumn<bool>("setValue");
1470     QTest::addColumn<bool>("setShouldFail");
1471     QTest::addColumn<bool>("expectedValue");
1472     QTest::addColumn<bool>("supportsScrollButtonDown");
1473 
1474     QTest::newRow("true -> false") << true << false << false << false << false << true;
1475     QTest::newRow("other -> false") << false << true << false << false << false << true;
1476     QTest::newRow("false -> true") << false << false << true << false << true << true;
1477     QTest::newRow("set fails") << true << false << false << true << true << true;
1478     QTest::newRow("true -> true") << true << false << true << false << true << true;
1479     QTest::newRow("false -> false") << false << false << false << false << false << true;
1480 
1481     QTest::newRow("false -> true, unsupported") << false << false << true << true << false << false;
1482 }
1483 
testScrollButtonDown()1484 void TestLibinputDevice::testScrollButtonDown()
1485 {
1486     libinput_device device;
1487     QFETCH(bool, initValue);
1488     QFETCH(bool, otherValue);
1489     QFETCH(bool, setShouldFail);
1490     QFETCH(bool, supportsScrollButtonDown);
1491     device.supportedScrollMethods = (supportsScrollButtonDown ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL) | LIBINPUT_CONFIG_SCROLL_2FG;
1492     device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : otherValue ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1493     device.setScrollMethodReturnValue = setShouldFail;
1494 
1495     Device d(&device);
1496     QCOMPARE(d.isScrollOnButtonDown(), initValue);
1497     QCOMPARE(d.property("scrollOnButtonDown").toBool(), initValue);
1498     QCOMPARE(d.property("scrollTwoFinger").toBool(), otherValue);
1499     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDown"), initValue);
1500     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollTwoFinger"), otherValue);
1501 
1502     QSignalSpy scrollMethodChangedSpy(&d, &Device::scrollMethodChanged);
1503     QVERIFY(scrollMethodChangedSpy.isValid());
1504     QFETCH(bool, setValue);
1505     d.setScrollOnButtonDown(setValue);
1506     QFETCH(bool, expectedValue);
1507     QCOMPARE(d.isScrollOnButtonDown(), expectedValue);
1508     QCOMPARE(d.property("scrollOnButtonDown").toBool(), expectedValue);
1509     QCOMPARE(scrollMethodChangedSpy.isEmpty(), initValue == expectedValue);
1510     QCOMPARE(dbusProperty<bool>(d.sysName(), "scrollOnButtonDown"), expectedValue);
1511 }
1512 
testScrollButton_data()1513 void TestLibinputDevice::testScrollButton_data()
1514 {
1515     QTest::addColumn<quint32>("initValue");
1516     QTest::addColumn<quint32>("setValue");
1517     QTest::addColumn<quint32>("expectedValue");
1518     QTest::addColumn<bool>("setShouldFail");
1519     QTest::addColumn<bool>("scrollOnButton");
1520 
1521     QTest::newRow("BTN_LEFT -> BTN_RIGHT") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_RIGHT) << false << true;
1522     QTest::newRow("BTN_LEFT -> BTN_LEFT") << quint32(BTN_LEFT) << quint32(BTN_LEFT) << quint32(BTN_LEFT) << false << true;
1523     QTest::newRow("set should fail") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_LEFT) << true << true;
1524     QTest::newRow("not scroll on button") << quint32(BTN_LEFT) << quint32(BTN_RIGHT) << quint32(BTN_LEFT) << false << false;
1525 }
1526 
testScrollButton()1527 void TestLibinputDevice::testScrollButton()
1528 {
1529     libinput_device device;
1530     QFETCH(quint32, initValue);
1531     QFETCH(bool, setShouldFail);
1532     QFETCH(bool, scrollOnButton);
1533     device.scrollButton = initValue;
1534     device.supportedScrollMethods = scrollOnButton ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1535     device.setScrollButtonReturnValue = setShouldFail;
1536 
1537     Device d(&device);
1538     QCOMPARE(d.scrollButton(), initValue);
1539     QCOMPARE(d.property("scrollButton").value<quint32>(), initValue);
1540     QCOMPARE(dbusProperty<quint32>(d.sysName(), "scrollButton"), initValue);
1541 
1542     QSignalSpy scrollButtonChangedSpy(&d, &Device::scrollButtonChanged);
1543     QVERIFY(scrollButtonChangedSpy.isValid());
1544     QFETCH(quint32, setValue);
1545     d.setScrollButton(setValue);
1546     QFETCH(quint32, expectedValue);
1547     QCOMPARE(d.scrollButton(), expectedValue);
1548     QCOMPARE(d.property("scrollButton").value<quint32>(), expectedValue);
1549     QCOMPARE(scrollButtonChangedSpy.isEmpty(), initValue == expectedValue);
1550     QCOMPARE(dbusProperty<quint32>(d.sysName(), "scrollButton"), expectedValue);
1551 }
1552 
testDisableWhileTypingEnabledByDefault_data()1553 void TestLibinputDevice::testDisableWhileTypingEnabledByDefault_data()
1554 {
1555     QTest::addColumn<bool>("enabled");
1556 
1557     QTest::newRow("enabled") << true;
1558     QTest::newRow("disabled") << false;
1559 }
1560 
testDisableWhileTypingEnabledByDefault()1561 void TestLibinputDevice::testDisableWhileTypingEnabledByDefault()
1562 {
1563     QFETCH(bool, enabled);
1564     libinput_device device;
1565     device.disableWhileTypingEnabledByDefault = enabled ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
1566 
1567     Device d(&device);
1568     QCOMPARE(d.disableWhileTypingEnabledByDefault(), enabled);
1569     QCOMPARE(d.property("disableWhileTypingEnabledByDefault").toBool(), enabled);
1570     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTypingEnabledByDefault"), enabled);
1571 }
1572 
testLmrTapButtonMapEnabledByDefault_data()1573 void TestLibinputDevice::testLmrTapButtonMapEnabledByDefault_data()
1574 {
1575     QTest::addColumn<bool>("enabled");
1576 
1577     QTest::newRow("enabled") << true;
1578     QTest::newRow("disabled") << false;
1579 }
1580 
testLmrTapButtonMapEnabledByDefault()1581 void TestLibinputDevice::testLmrTapButtonMapEnabledByDefault()
1582 {
1583     QFETCH(bool, enabled);
1584     libinput_device device;
1585     device.defaultTapButtonMap = enabled ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
1586 
1587     Device d(&device);
1588     QCOMPARE(d.lmrTapButtonMapEnabledByDefault(), enabled);
1589     QCOMPARE(d.property("lmrTapButtonMapEnabledByDefault").toBool(), enabled);
1590     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMapEnabledByDefault"), enabled);
1591 }
1592 
testLmrTapButtonMap_data()1593 void TestLibinputDevice::testLmrTapButtonMap_data()
1594 {
1595     QTest::addColumn<bool>("initValue");
1596     QTest::addColumn<bool>("setValue");
1597     QTest::addColumn<bool>("setShouldFail");
1598     QTest::addColumn<bool>("expectedValue");
1599     QTest::addColumn<int>("fingerCount");
1600 
1601     QTest::newRow("true -> false") << true << false << false << false << 3;
1602     QTest::newRow("false -> true") << false << true << false << true << 3;
1603     QTest::newRow("true -> false") << true << false << false << false << 2;
1604     QTest::newRow("false -> true") << false << true << false << true << 2;
1605 
1606     QTest::newRow("set fails") << true << false << true << true << 3;
1607 
1608     QTest::newRow("true -> true") << true << true << false << true << 3;
1609     QTest::newRow("false -> false") << false << false << false << false << 3;
1610     QTest::newRow("true -> true") << true << true << false << true << 2;
1611     QTest::newRow("false -> false") << false << false << false << false << 2;
1612 
1613     QTest::newRow("false -> true, fingerCount 0") << false << true << true << false << 0;
1614 
1615     // TODO: is this a fail in libinput?
1616     //QTest::newRow("false -> true, fingerCount 1") << false << true << true << false << 1;
1617 }
1618 
testLmrTapButtonMap()1619 void TestLibinputDevice::testLmrTapButtonMap()
1620 {
1621     libinput_device device;
1622     QFETCH(bool, initValue);
1623     QFETCH(bool, setShouldFail);
1624     QFETCH(int, fingerCount);
1625     device.tapFingerCount = fingerCount;
1626     device.tapButtonMap = initValue ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
1627     device.setTapButtonMapReturnValue = setShouldFail;
1628 
1629     Device d(&device);
1630     QCOMPARE(d.lmrTapButtonMap(), initValue);
1631     QCOMPARE(d.property("lmrTapButtonMap").toBool(), initValue);
1632 
1633     QSignalSpy tapButtonMapChangedSpy(&d, &Device::tapButtonMapChanged);
1634     QVERIFY(tapButtonMapChangedSpy.isValid());
1635     QFETCH(bool, setValue);
1636     d.setLmrTapButtonMap(setValue);
1637     QFETCH(bool, expectedValue);
1638     QCOMPARE(d.lmrTapButtonMap(), expectedValue);
1639     QCOMPARE(d.property("lmrTapButtonMap").toBool(), expectedValue);
1640     QCOMPARE(tapButtonMapChangedSpy.isEmpty(), initValue == expectedValue);
1641 }
1642 
testDisableWhileTyping_data()1643 void TestLibinputDevice::testDisableWhileTyping_data()
1644 {
1645     QTest::addColumn<bool>("initValue");
1646     QTest::addColumn<bool>("setValue");
1647     QTest::addColumn<bool>("setShouldFail");
1648     QTest::addColumn<bool>("expectedValue");
1649     QTest::addColumn<bool>("supportsDisableWhileTyping");
1650 
1651     QTest::newRow("true -> false") << true << false << false << false << true;
1652     QTest::newRow("false -> true") << false << true << false << true << true;
1653     QTest::newRow("set fails") << true << false << true << true << true;
1654     QTest::newRow("true -> true") << true << true << false << true << true;
1655     QTest::newRow("false -> false") << false << false << false << false << true;
1656 
1657     QTest::newRow("false -> true, unsupported") << false << true << true << false << false;
1658 }
1659 
testDisableWhileTyping()1660 void TestLibinputDevice::testDisableWhileTyping()
1661 {
1662     libinput_device device;
1663     QFETCH(bool, initValue);
1664     QFETCH(bool, setShouldFail);
1665     QFETCH(bool, supportsDisableWhileTyping);
1666     device.supportsDisableWhileTyping = supportsDisableWhileTyping;
1667     device.disableWhileTyping = initValue ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
1668     device.setDisableWhileTypingReturnValue = setShouldFail;
1669 
1670     Device d(&device);
1671     QCOMPARE(d.isDisableWhileTyping(), initValue);
1672     QCOMPARE(d.property("disableWhileTyping").toBool(), initValue);
1673     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTyping"), initValue);
1674 
1675     QSignalSpy disableWhileTypingChangedSpy(&d, &Device::disableWhileTypingChanged);
1676     QVERIFY(disableWhileTypingChangedSpy.isValid());
1677     QFETCH(bool, setValue);
1678     d.setDisableWhileTyping(setValue);
1679     QFETCH(bool, expectedValue);
1680     QCOMPARE(d.isDisableWhileTyping(), expectedValue);
1681     QCOMPARE(d.property("disableWhileTyping").toBool(), expectedValue);
1682     QCOMPARE(disableWhileTypingChangedSpy.isEmpty(), initValue == expectedValue);
1683     QCOMPARE(dbusProperty<bool>(d.sysName(), "disableWhileTyping"), expectedValue);
1684 }
1685 
testLoadEnabled_data()1686 void TestLibinputDevice::testLoadEnabled_data()
1687 {
1688     QTest::addColumn<bool>("initValue");
1689     QTest::addColumn<bool>("configValue");
1690 
1691     QTest::newRow("false -> true") << false << true;
1692     QTest::newRow("true -> false") << true << false;
1693     QTest::newRow("true -> true") << true << true;
1694     QTest::newRow("false -> false") << false << false;
1695 }
1696 
testLoadEnabled()1697 void TestLibinputDevice::testLoadEnabled()
1698 {
1699     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1700     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1701     QFETCH(bool, configValue);
1702     QFETCH(bool, initValue);
1703     inputConfig.writeEntry("Enabled", configValue);
1704 
1705     libinput_device device;
1706     device.supportsDisableEvents = true;
1707     device.enabled = initValue;
1708     device.setEnableModeReturnValue = false;
1709 
1710     Device d(&device);
1711     QCOMPARE(d.isEnabled(), initValue);
1712     // no config group set, should not change
1713     d.loadConfiguration();
1714     QCOMPARE(d.isEnabled(), initValue);
1715 
1716     // set the group
1717     d.setConfig(inputConfig);
1718     d.loadConfiguration();
1719     QCOMPARE(d.isEnabled(), configValue);
1720 
1721     // and try to store
1722     if (configValue != initValue) {
1723         d.setEnabled(initValue);
1724         QCOMPARE(inputConfig.readEntry("Enabled", configValue), initValue);
1725     }
1726 }
1727 
testLoadPointerAcceleration_data()1728 void TestLibinputDevice::testLoadPointerAcceleration_data()
1729 {
1730     QTest::addColumn<qreal>("initValue");
1731     QTest::addColumn<qreal>("configValue");
1732 
1733     QTest::newRow("-0.2 -> 0.9") << -0.2 << 0.9;
1734     QTest::newRow("0.0 -> -1.0") << 0.0 << -1.0;
1735     QTest::newRow("0.123 -> -0.456") << 0.123 << -0.456;
1736     QTest::newRow("0.7 -> 0.7") << 0.7 << 0.7;
1737 }
1738 
testLoadPointerAcceleration()1739 void TestLibinputDevice::testLoadPointerAcceleration()
1740 {
1741     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1742     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1743     QFETCH(qreal, configValue);
1744     QFETCH(qreal, initValue);
1745     inputConfig.writeEntry("PointerAcceleration", configValue);
1746 
1747     libinput_device device;
1748     device.supportsPointerAcceleration = true;
1749     device.pointerAcceleration = initValue;
1750     device.setPointerAccelerationReturnValue = false;
1751 
1752     Device d(&device);
1753     QCOMPARE(d.pointerAcceleration(), initValue);
1754     QCOMPARE(d.property("pointerAcceleration").toReal(), initValue);
1755     // no config group set, should not change
1756     d.loadConfiguration();
1757     QCOMPARE(d.pointerAcceleration(), initValue);
1758     QCOMPARE(d.property("pointerAcceleration").toReal(), initValue);
1759 
1760     // set the group
1761     d.setConfig(inputConfig);
1762     d.loadConfiguration();
1763     QCOMPARE(d.pointerAcceleration(), configValue);
1764     QCOMPARE(d.property("pointerAcceleration").toReal(), configValue);
1765 
1766     // and try to store
1767     if (configValue != initValue) {
1768         d.setPointerAcceleration(initValue);
1769         QCOMPARE(inputConfig.readEntry("PointerAcceleration", configValue), initValue);
1770     }
1771 }
1772 
testLoadPointerAccelerationProfile_data()1773 void TestLibinputDevice::testLoadPointerAccelerationProfile_data()
1774 {
1775     QTest::addColumn<quint32>("initValue");
1776     QTest::addColumn<QString>("initValuePropNameString");
1777     QTest::addColumn<quint32>("configValue");
1778     QTest::addColumn<QString>("configValuePropNameString");
1779 
1780     QTest::newRow("pointerAccelerationProfileFlat -> pointerAccelerationProfileAdaptive")
1781             << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT << "pointerAccelerationProfileFlat"
1782             << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive";
1783     QTest::newRow("pointerAccelerationProfileAdaptive -> pointerAccelerationProfileFlat")
1784             << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive"
1785             << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT << "pointerAccelerationProfileFlat";
1786     QTest::newRow("pointerAccelerationProfileAdaptive -> pointerAccelerationProfileAdaptive")
1787             << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive" << (quint32) LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE << "pointerAccelerationProfileAdaptive";
1788 }
1789 
testLoadPointerAccelerationProfile()1790 void TestLibinputDevice::testLoadPointerAccelerationProfile()
1791 {
1792     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1793     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1794     QFETCH(quint32, initValue);
1795     QFETCH(quint32, configValue);
1796     QFETCH(QString, initValuePropNameString);
1797     QFETCH(QString, configValuePropNameString);
1798 
1799     QByteArray initValuePropName = initValuePropNameString.toLatin1();
1800     QByteArray configValuePropName = configValuePropNameString.toLatin1();
1801 
1802     inputConfig.writeEntry("PointerAccelerationProfile", configValue);
1803 
1804     libinput_device device;
1805     device.supportedPointerAccelerationProfiles = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT | LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
1806     device.pointerAccelerationProfile = (libinput_config_accel_profile) initValue;
1807     device.setPointerAccelerationProfileReturnValue = false;
1808 
1809     Device d(&device);
1810     QCOMPARE(d.property(initValuePropName).toBool(), true);
1811     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1812     // no config group set, should not change
1813     d.loadConfiguration();
1814     QCOMPARE(d.property(initValuePropName).toBool(), true);
1815     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1816 
1817     // set the group
1818     d.setConfig(inputConfig);
1819     d.loadConfiguration();
1820     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
1821     QCOMPARE(d.property(configValuePropName).toBool(), true);
1822     QCOMPARE(dbusProperty<bool>(d.sysName(), initValuePropName), initValue == configValue);
1823     QCOMPARE(dbusProperty<bool>(d.sysName(), configValuePropName), true);
1824 
1825     // and try to store
1826     if (configValue != initValue) {
1827         d.setProperty(initValuePropName, true);
1828         QCOMPARE(inputConfig.readEntry("PointerAccelerationProfile", configValue), initValue);
1829     }
1830 }
1831 
testLoadClickMethod_data()1832 void TestLibinputDevice::testLoadClickMethod_data()
1833 {
1834     QTest::addColumn<quint32>("initValue");
1835     QTest::addColumn<QString>("initValuePropNameString");
1836     QTest::addColumn<quint32>("configValue");
1837     QTest::addColumn<QString>("configValuePropNameString");
1838 
1839     QTest::newRow("clickMethodAreas -> clickMethodClickfinger")
1840             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas"
1841             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger";
1842     QTest::newRow("clickMethodClickfinger -> clickMethodAreas")
1843             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger"
1844             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas";
1845     QTest::newRow("clickMethodAreas -> clickMethodAreas")
1846             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas"
1847             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) << "clickMethodAreas";
1848     QTest::newRow("clickMethodClickfinger -> clickMethodClickfinger")
1849             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger"
1850             << static_cast<quint32>(LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) << "clickMethodClickfinger";
1851 }
1852 
testLoadClickMethod()1853 void TestLibinputDevice::testLoadClickMethod()
1854 {
1855     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1856     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1857     QFETCH(quint32, initValue);
1858     QFETCH(quint32, configValue);
1859     QFETCH(QString, initValuePropNameString);
1860     QFETCH(QString, configValuePropNameString);
1861 
1862     QByteArray initValuePropName = initValuePropNameString.toLatin1();
1863     QByteArray configValuePropName = configValuePropNameString.toLatin1();
1864 
1865     inputConfig.writeEntry("ClickMethod", configValue);
1866 
1867     libinput_device device;
1868     device.supportedClickMethods = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS | LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
1869     device.clickMethod = (libinput_config_click_method) initValue;
1870     device.setClickMethodReturnValue = false;
1871 
1872     Device d(&device);
1873     QCOMPARE(d.property(initValuePropName).toBool(), true);
1874     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1875     // no config group set, should not change
1876     d.loadConfiguration();
1877     QCOMPARE(d.property(initValuePropName).toBool(), true);
1878     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
1879 
1880     // set the group
1881     d.setConfig(inputConfig);
1882     d.loadConfiguration();
1883     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
1884     QCOMPARE(d.property(configValuePropName).toBool(), true);
1885     QCOMPARE(dbusProperty<bool>(d.sysName(), initValuePropName), initValue == configValue);
1886     QCOMPARE(dbusProperty<bool>(d.sysName(), configValuePropName), true);
1887 
1888     // and try to store
1889     if (configValue != initValue) {
1890         d.setProperty(initValuePropName, true);
1891         QCOMPARE(inputConfig.readEntry("ClickMethod", configValue), initValue);
1892     }
1893 }
1894 
testLoadTapToClick_data()1895 void TestLibinputDevice::testLoadTapToClick_data()
1896 {
1897     QTest::addColumn<bool>("initValue");
1898     QTest::addColumn<bool>("configValue");
1899 
1900     QTest::newRow("false -> true") << false << true;
1901     QTest::newRow("true -> false") << true << false;
1902     QTest::newRow("true -> true") << true << true;
1903     QTest::newRow("false -> false") << false << false;
1904 }
1905 
testLoadTapToClick()1906 void TestLibinputDevice::testLoadTapToClick()
1907 {
1908     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1909     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1910     QFETCH(bool, configValue);
1911     QFETCH(bool, initValue);
1912     inputConfig.writeEntry("TapToClick", configValue);
1913 
1914     libinput_device device;
1915     device.tapFingerCount = 2;
1916     device.tapToClick = initValue;
1917     device.setTapToClickReturnValue = false;
1918 
1919     Device d(&device);
1920     QCOMPARE(d.isTapToClick(), initValue);
1921     // no config group set, should not change
1922     d.loadConfiguration();
1923     QCOMPARE(d.isTapToClick(), initValue);
1924 
1925     // set the group
1926     d.setConfig(inputConfig);
1927     d.loadConfiguration();
1928     QCOMPARE(d.isTapToClick(), configValue);
1929 
1930     // and try to store
1931     if (configValue != initValue) {
1932         d.setTapToClick(initValue);
1933         QCOMPARE(inputConfig.readEntry("TapToClick", configValue), initValue);
1934     }
1935 }
1936 
testLoadTapAndDrag_data()1937 void TestLibinputDevice::testLoadTapAndDrag_data()
1938 {
1939     QTest::addColumn<bool>("initValue");
1940     QTest::addColumn<bool>("configValue");
1941 
1942     QTest::newRow("false -> true") << false << true;
1943     QTest::newRow("true -> false") << true << false;
1944     QTest::newRow("true -> true") << true << true;
1945     QTest::newRow("false -> false") << false << false;
1946 }
1947 
testLoadTapAndDrag()1948 void TestLibinputDevice::testLoadTapAndDrag()
1949 {
1950     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1951     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1952     QFETCH(bool, configValue);
1953     QFETCH(bool, initValue);
1954     inputConfig.writeEntry("TapAndDrag", configValue);
1955 
1956     libinput_device device;
1957     device.tapAndDrag = initValue;
1958     device.setTapAndDragReturnValue = false;
1959 
1960     Device d(&device);
1961     QCOMPARE(d.isTapAndDrag(), initValue);
1962     // no config group set, should not change
1963     d.loadConfiguration();
1964     QCOMPARE(d.isTapAndDrag(), initValue);
1965 
1966     // set the group
1967     d.setConfig(inputConfig);
1968     d.loadConfiguration();
1969     QCOMPARE(d.isTapAndDrag(), configValue);
1970 
1971     // and try to store
1972     if (configValue != initValue) {
1973         d.setTapAndDrag(initValue);
1974         QCOMPARE(inputConfig.readEntry("TapAndDrag", configValue), initValue);
1975     }
1976 }
1977 
testLoadTapDragLock_data()1978 void TestLibinputDevice::testLoadTapDragLock_data()
1979 {
1980     QTest::addColumn<bool>("initValue");
1981     QTest::addColumn<bool>("configValue");
1982 
1983     QTest::newRow("false -> true") << false << true;
1984     QTest::newRow("true -> false") << true << false;
1985     QTest::newRow("true -> true") << true << true;
1986     QTest::newRow("false -> false") << false << false;
1987 }
1988 
testLoadTapDragLock()1989 void TestLibinputDevice::testLoadTapDragLock()
1990 {
1991     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
1992     KConfigGroup inputConfig(config, QStringLiteral("Test"));
1993     QFETCH(bool, configValue);
1994     QFETCH(bool, initValue);
1995     inputConfig.writeEntry("TapDragLock", configValue);
1996 
1997     libinput_device device;
1998     device.tapDragLock = initValue;
1999     device.setTapDragLockReturnValue = false;
2000 
2001     Device d(&device);
2002     QCOMPARE(d.isTapDragLock(), initValue);
2003     // no config group set, should not change
2004     d.loadConfiguration();
2005     QCOMPARE(d.isTapDragLock(), initValue);
2006 
2007     // set the group
2008     d.setConfig(inputConfig);
2009     d.loadConfiguration();
2010     QCOMPARE(d.isTapDragLock(), configValue);
2011 
2012     // and try to store
2013     if (configValue != initValue) {
2014         d.setTapDragLock(initValue);
2015         QCOMPARE(inputConfig.readEntry("TapDragLock", configValue), initValue);
2016     }
2017 }
2018 
testLoadMiddleButtonEmulation_data()2019 void TestLibinputDevice::testLoadMiddleButtonEmulation_data()
2020 {
2021     QTest::addColumn<bool>("initValue");
2022     QTest::addColumn<bool>("configValue");
2023 
2024     QTest::newRow("false -> true") << false << true;
2025     QTest::newRow("true -> false") << true << false;
2026     QTest::newRow("true -> true") << true << true;
2027     QTest::newRow("false -> false") << false << false;
2028 }
2029 
testLoadMiddleButtonEmulation()2030 void TestLibinputDevice::testLoadMiddleButtonEmulation()
2031 {
2032     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2033     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2034     QFETCH(bool, configValue);
2035     QFETCH(bool, initValue);
2036     inputConfig.writeEntry("MiddleButtonEmulation", configValue);
2037 
2038     libinput_device device;
2039     device.supportsMiddleEmulation = true;
2040     device.middleEmulation = initValue;
2041     device.setMiddleEmulationReturnValue = false;
2042 
2043     Device d(&device);
2044     QCOMPARE(d.isMiddleEmulation(), initValue);
2045     // no config group set, should not change
2046     d.loadConfiguration();
2047     QCOMPARE(d.isMiddleEmulation(), initValue);
2048 
2049     // set the group
2050     d.setConfig(inputConfig);
2051     d.loadConfiguration();
2052     QCOMPARE(d.isMiddleEmulation(), configValue);
2053 
2054     // and try to store
2055     if (configValue != initValue) {
2056         d.setMiddleEmulation(initValue);
2057         QCOMPARE(inputConfig.readEntry("MiddleButtonEmulation", configValue), initValue);
2058     }
2059 }
2060 
testLoadNaturalScroll_data()2061 void TestLibinputDevice::testLoadNaturalScroll_data()
2062 {
2063     QTest::addColumn<bool>("initValue");
2064     QTest::addColumn<bool>("configValue");
2065 
2066     QTest::newRow("false -> true") << false << true;
2067     QTest::newRow("true -> false") << true << false;
2068     QTest::newRow("true -> true") << true << true;
2069     QTest::newRow("false -> false") << false << false;
2070 }
2071 
testLoadNaturalScroll()2072 void TestLibinputDevice::testLoadNaturalScroll()
2073 {
2074     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2075     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2076     QFETCH(bool, configValue);
2077     QFETCH(bool, initValue);
2078     inputConfig.writeEntry("NaturalScroll", configValue);
2079 
2080     libinput_device device;
2081     device.supportsNaturalScroll = true;
2082     device.naturalScroll = initValue;
2083     device.setNaturalScrollReturnValue = false;
2084 
2085     Device d(&device);
2086     QCOMPARE(d.isNaturalScroll(), initValue);
2087     // no config group set, should not change
2088     d.loadConfiguration();
2089     QCOMPARE(d.isNaturalScroll(), initValue);
2090 
2091     // set the group
2092     d.setConfig(inputConfig);
2093     d.loadConfiguration();
2094     QCOMPARE(d.isNaturalScroll(), configValue);
2095 
2096     // and try to store
2097     if (configValue != initValue) {
2098         d.setNaturalScroll(initValue);
2099         QCOMPARE(inputConfig.readEntry("NaturalScroll", configValue), initValue);
2100     }
2101 }
2102 
testLoadScrollMethod_data()2103 void TestLibinputDevice::testLoadScrollMethod_data()
2104 {
2105     QTest::addColumn<quint32>("initValue");
2106     QTest::addColumn<QString>("initValuePropNameString");
2107     QTest::addColumn<quint32>("configValue");
2108     QTest::addColumn<QString>("configValuePropNameString");
2109 
2110     QTest::newRow("scrollTwoFinger -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
2111     QTest::newRow("scrollOnButtonDown -> scrollTwoFinger") << (quint32) LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN << "scrollOnButtonDown" << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger";
2112     QTest::newRow("scrollEdge -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
2113 }
2114 
testLoadScrollMethod()2115 void TestLibinputDevice::testLoadScrollMethod()
2116 {
2117     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2118     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2119     QFETCH(quint32, initValue);
2120     QFETCH(quint32, configValue);
2121     QFETCH(QString, initValuePropNameString);
2122     QFETCH(QString, configValuePropNameString);
2123 
2124     QByteArray initValuePropName = initValuePropNameString.toLatin1();
2125     QByteArray configValuePropName = configValuePropNameString.toLatin1();
2126 
2127     inputConfig.writeEntry("ScrollMethod", configValue);
2128 
2129     libinput_device device;
2130     device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG | LIBINPUT_CONFIG_SCROLL_EDGE | LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2131     device.scrollMethod = (libinput_config_scroll_method) initValue;
2132     device.setScrollMethodReturnValue = false;
2133 
2134     Device d(&device);
2135     QCOMPARE(d.property(initValuePropName).toBool(), true);
2136     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
2137     // no config group set, should not change
2138     d.loadConfiguration();
2139     QCOMPARE(d.property(initValuePropName).toBool(), true);
2140     QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
2141 
2142     // set the group
2143     d.setConfig(inputConfig);
2144     d.loadConfiguration();
2145     QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
2146     QCOMPARE(d.property(configValuePropName).toBool(), true);
2147 
2148     // and try to store
2149     if (configValue != initValue) {
2150         d.setProperty(initValuePropName, true);
2151         QCOMPARE(inputConfig.readEntry("ScrollMethod", configValue), initValue);
2152     }
2153 }
2154 
testLoadScrollButton_data()2155 void TestLibinputDevice::testLoadScrollButton_data()
2156 {
2157     QTest::addColumn<quint32>("initValue");
2158     QTest::addColumn<quint32>("configValue");
2159 
2160     QTest::newRow("BTN_LEFT -> BTN_RIGHT") << quint32(BTN_LEFT) << quint32(BTN_RIGHT);
2161     QTest::newRow("BTN_LEFT -> BTN_LEFT") << quint32(BTN_LEFT) << quint32(BTN_LEFT);
2162 }
2163 
testLoadScrollButton()2164 void TestLibinputDevice::testLoadScrollButton()
2165 {
2166     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2167     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2168     QFETCH(quint32, configValue);
2169     QFETCH(quint32, initValue);
2170     inputConfig.writeEntry("ScrollButton", configValue);
2171 
2172     libinput_device device;
2173     device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2174     device.scrollMethod = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
2175     device.scrollButton = initValue;
2176     device.setScrollButtonReturnValue = false;
2177 
2178     Device d(&device);
2179     QCOMPARE(d.isScrollOnButtonDown(), true);
2180     QCOMPARE(d.scrollButton(), initValue);
2181     // no config group set, should not change
2182     d.loadConfiguration();
2183     QCOMPARE(d.isScrollOnButtonDown(), true);
2184     QCOMPARE(d.scrollButton(), initValue);
2185 
2186     // set the group
2187     d.setConfig(inputConfig);
2188     d.loadConfiguration();
2189     QCOMPARE(d.isScrollOnButtonDown(), true);
2190     QCOMPARE(d.scrollButton(), configValue);
2191 
2192     // and try to store
2193     if (configValue != initValue) {
2194         d.setScrollButton(initValue);
2195         QCOMPARE(inputConfig.readEntry("ScrollButton", configValue), initValue);
2196     }
2197 }
2198 
testLoadLeftHanded_data()2199 void TestLibinputDevice::testLoadLeftHanded_data()
2200 {
2201     QTest::addColumn<bool>("initValue");
2202     QTest::addColumn<bool>("configValue");
2203 
2204     QTest::newRow("false -> true") << false << true;
2205     QTest::newRow("true -> false") << true << false;
2206     QTest::newRow("true -> true") << true << true;
2207     QTest::newRow("false -> false") << false << false;
2208 }
2209 
testLoadLeftHanded()2210 void TestLibinputDevice::testLoadLeftHanded()
2211 {
2212     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2213     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2214     QFETCH(bool, configValue);
2215     QFETCH(bool, initValue);
2216     inputConfig.writeEntry("LeftHanded", configValue);
2217 
2218     libinput_device device;
2219     device.supportsLeftHanded = true;
2220     device.leftHanded = initValue;
2221     device.setLeftHandedReturnValue = false;
2222 
2223     Device d(&device);
2224     QCOMPARE(d.isLeftHanded(), initValue);
2225     // no config group set, should not change
2226     d.loadConfiguration();
2227     QCOMPARE(d.isLeftHanded(), initValue);
2228 
2229     // set the group
2230     d.setConfig(inputConfig);
2231     d.loadConfiguration();
2232     QCOMPARE(d.isLeftHanded(), configValue);
2233 
2234     // and try to store
2235     if (configValue != initValue) {
2236         d.setLeftHanded(initValue);
2237         QCOMPARE(inputConfig.readEntry("LeftHanded", configValue), initValue);
2238     }
2239 }
2240 
testLoadDisableWhileTyping_data()2241 void TestLibinputDevice::testLoadDisableWhileTyping_data()
2242 {
2243     QTest::addColumn<bool>("initValue");
2244     QTest::addColumn<bool>("configValue");
2245 
2246     QTest::newRow("false -> true") << false << true;
2247     QTest::newRow("true -> false") << true << false;
2248     QTest::newRow("true -> true") << true << true;
2249     QTest::newRow("false -> false") << false << false;
2250 }
2251 
testLoadDisableWhileTyping()2252 void TestLibinputDevice::testLoadDisableWhileTyping()
2253 {
2254     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2255     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2256     QFETCH(bool, configValue);
2257     QFETCH(bool, initValue);
2258     inputConfig.writeEntry("DisableWhileTyping", configValue);
2259 
2260     libinput_device device;
2261     device.supportsDisableWhileTyping = true;
2262     device.disableWhileTyping = initValue ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED;
2263     device.setDisableWhileTypingReturnValue = false;
2264 
2265     Device d(&device);
2266     QCOMPARE(d.isDisableWhileTyping(), initValue);
2267     // no config group set, should not change
2268     d.loadConfiguration();
2269     QCOMPARE(d.isDisableWhileTyping(), initValue);
2270 
2271     // set the group
2272     d.setConfig(inputConfig);
2273     d.loadConfiguration();
2274     QCOMPARE(d.isDisableWhileTyping(), configValue);
2275 
2276     // and try to store
2277     if (configValue != initValue) {
2278         d.setDisableWhileTyping(initValue);
2279         QCOMPARE(inputConfig.readEntry("DisableWhileTyping", configValue), initValue);
2280     }
2281 }
2282 
testLoadLmrTapButtonMap_data()2283 void TestLibinputDevice::testLoadLmrTapButtonMap_data()
2284 {
2285     QTest::addColumn<bool>("initValue");
2286     QTest::addColumn<bool>("configValue");
2287 
2288     QTest::newRow("false -> true") << false << true;
2289     QTest::newRow("true -> false") << true << false;
2290     QTest::newRow("true -> true") << true << true;
2291     QTest::newRow("false -> false") << false << false;
2292 }
2293 
testLoadLmrTapButtonMap()2294 void TestLibinputDevice::testLoadLmrTapButtonMap()
2295 {
2296     auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
2297     KConfigGroup inputConfig(config, QStringLiteral("Test"));
2298     QFETCH(bool, configValue);
2299     QFETCH(bool, initValue);
2300     inputConfig.writeEntry("LmrTapButtonMap", configValue);
2301 
2302     libinput_device device;
2303     device.tapFingerCount = 3;
2304     device.tapButtonMap = initValue ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
2305     device.setTapButtonMapReturnValue = false;
2306 
2307     Device d(&device);
2308     QCOMPARE(d.lmrTapButtonMap(), initValue);
2309     // no config group set, should not change
2310     d.loadConfiguration();
2311     QCOMPARE(d.lmrTapButtonMap(), initValue);
2312     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMap"), initValue);
2313 
2314     // set the group
2315     d.setConfig(inputConfig);
2316     d.loadConfiguration();
2317     QCOMPARE(d.lmrTapButtonMap(), configValue);
2318     QCOMPARE(dbusProperty<bool>(d.sysName(), "lmrTapButtonMap"), configValue);
2319 
2320     // and try to store
2321     if (configValue != initValue) {
2322         d.setLmrTapButtonMap(initValue);
2323         QCOMPARE(inputConfig.readEntry("LmrTapButtonMap", configValue), initValue);
2324     }
2325 }
2326 
testScreenId()2327 void TestLibinputDevice::testScreenId()
2328 {
2329     libinput_device device;
2330     Device d(&device);
2331     QCOMPARE(d.screenId(), 0);
2332     d.setScreenId(1);
2333     QCOMPARE(d.screenId(), 1);
2334 }
2335 
testOrientation_data()2336 void TestLibinputDevice::testOrientation_data()
2337 {
2338     QTest::addColumn<Qt::ScreenOrientation>("orientation");
2339     QTest::addColumn<float>("m11");
2340     QTest::addColumn<float>("m12");
2341     QTest::addColumn<float>("m13");
2342     QTest::addColumn<float>("m21");
2343     QTest::addColumn<float>("m22");
2344     QTest::addColumn<float>("m23");
2345     QTest::addColumn<bool>("defaultIsIdentity");
2346 
2347     QTest::newRow("Primary") << Qt::PrimaryOrientation << 1.0f << 2.0f << 3.0f << 4.0f << 5.0f << 6.0f << false;
2348     QTest::newRow("Landscape") << Qt::LandscapeOrientation << 1.0f << 2.0f << 3.0f << 4.0f << 5.0f << 6.0f << false;
2349     QTest::newRow("Portrait") << Qt::PortraitOrientation << 0.0f << -1.0f << 1.0f << 1.0f << 0.0f << 0.0f << true;
2350     QTest::newRow("InvertedLandscape") << Qt::InvertedLandscapeOrientation << -1.0f << 0.0f << 1.0f << 0.0f << -1.0f << 1.0f << true;
2351     QTest::newRow("InvertedPortrait") << Qt::InvertedPortraitOrientation << 0.0f << 1.0f << 0.0f << -1.0f << 0.0f << 1.0f << true;
2352 }
2353 
testOrientation()2354 void TestLibinputDevice::testOrientation()
2355 {
2356     libinput_device device;
2357     device.supportsCalibrationMatrix = true;
2358     device.defaultCalibrationMatrix = std::array<float, 6>{{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}};
2359     QFETCH(bool, defaultIsIdentity);
2360     device.defaultCalibrationMatrixIsIdentity = defaultIsIdentity;
2361     Device d(&device);
2362     QFETCH(Qt::ScreenOrientation, orientation);
2363     d.setOrientation(orientation);
2364     QTEST(device.calibrationMatrix[0], "m11");
2365     QTEST(device.calibrationMatrix[1], "m12");
2366     QTEST(device.calibrationMatrix[2], "m13");
2367     QTEST(device.calibrationMatrix[3], "m21");
2368     QTEST(device.calibrationMatrix[4], "m22");
2369     QTEST(device.calibrationMatrix[5], "m23");
2370 }
2371 
testCalibrationWithDefault()2372 void TestLibinputDevice::testCalibrationWithDefault()
2373 {
2374     libinput_device device;
2375     device.supportsCalibrationMatrix = true;
2376     device.defaultCalibrationMatrix = std::array<float, 6>{{2.0, 3.0, 0.0, 4.0, 5.0, 0.0}};
2377     device.defaultCalibrationMatrixIsIdentity = false;
2378     Device d(&device);
2379     d.setOrientation(Qt::PortraitOrientation);
2380     QCOMPARE(device.calibrationMatrix[0], 3.0f);
2381     QCOMPARE(device.calibrationMatrix[1], -2.0f);
2382     QCOMPARE(device.calibrationMatrix[2], 2.0f);
2383     QCOMPARE(device.calibrationMatrix[3], 5.0f);
2384     QCOMPARE(device.calibrationMatrix[4], -4.0f);
2385     QCOMPARE(device.calibrationMatrix[5], 4.0f);
2386 }
2387 
testSwitch_data()2388 void TestLibinputDevice::testSwitch_data()
2389 {
2390     QTest::addColumn<bool>("lid");
2391     QTest::addColumn<bool>("tablet");
2392 
2393     QTest::newRow("lid") << true << false;
2394     QTest::newRow("tablet") << false << true;
2395 }
2396 
testSwitch()2397 void TestLibinputDevice::testSwitch()
2398 {
2399     libinput_device device;
2400     device.switchDevice = true;
2401     QFETCH(bool, lid);
2402     QFETCH(bool, tablet);
2403     device.lidSwitch = lid;
2404     device.tabletModeSwitch = tablet;
2405 
2406     Device d(&device);
2407     QCOMPARE(d.isSwitch(), true);
2408     QCOMPARE(d.isLidSwitch(), lid);
2409     QCOMPARE(d.property("lidSwitch").toBool(), lid);
2410     QCOMPARE(dbusProperty<bool>(d.sysName(), "lidSwitch"), lid);
2411     QCOMPARE(d.isTabletModeSwitch(), tablet);
2412     QCOMPARE(d.property("tabletModeSwitch").toBool(), tablet);
2413     QCOMPARE(dbusProperty<bool>(d.sysName(), "tabletModeSwitch"), tablet);
2414 }
2415 
2416 QTEST_GUILESS_MAIN(TestLibinputDevice)
2417 #include "device_test.moc"
2418