13#include "wayland/datasource.h"
23#include "KWayland/Client/compositor.h"
24#include "KWayland/Client/connection_thread.h"
25#include "KWayland/Client/datadevice.h"
26#include "KWayland/Client/datadevicemanager.h"
27#include "KWayland/Client/datasource.h"
28#include "KWayland/Client/event_queue.h"
29#include "KWayland/Client/keyboard.h"
30#include "KWayland/Client/pointer.h"
31#include "KWayland/Client/pointergestures.h"
32#include "KWayland/Client/registry.h"
33#include "KWayland/Client/relativepointer.h"
34#include "KWayland/Client/seat.h"
35#include "KWayland/Client/shm_pool.h"
36#include "KWayland/Client/subcompositor.h"
37#include "KWayland/Client/subsurface.h"
38#include "KWayland/Client/surface.h"
39#include "KWayland/Client/touch.h"
42#include "qwayland-pointer-gestures-unstable-v1.h"
43#include <wayland-client-protocol.h>
45#include <linux/input.h>
50using namespace std::literals;
57 explicit WaylandSyncPoint(KWayland::Client::ConnectionThread *connection, KWayland::Client::EventQueue *eventQueue)
59 static const wl_callback_listener listener = {
60 .done = [](
void *data, wl_callback *callback, uint32_t callback_data) {
62 Q_EMIT syncPoint->
done();
66 m_callback = wl_display_sync(connection->display());
67 eventQueue->addProxy(m_callback);
68 wl_callback_add_listener(m_callback, &listener,
this);
73 wl_callback_destroy(m_callback);
80 wl_callback *m_callback;
93 void testCapabilities_data();
94 void testCapabilities();
96 void testPointerTransformation_data();
97 void testPointerTransformation();
98 void testPointerButton_data();
99 void testPointerButton();
100 void testPointerSubSurfaceTree();
101 void testPointerSwipeGesture_data();
102 void testPointerSwipeGesture();
103 void testPointerPinchGesture_data();
104 void testPointerPinchGesture();
105 void testPointerHoldGesture_data();
106 void testPointerHoldGesture();
107 void testPointerAxis();
110 void testSelection();
111 void testDataDeviceForKeyboardSurface();
124 KWayland::Client::ConnectionThread *m_connection;
125 KWayland::Client::Compositor *m_compositor;
126 KWayland::Client::Seat *m_seat;
127 KWayland::Client::ShmPool *m_shm;
128 KWayland::Client::SubCompositor *m_subCompositor;
129 KWayland::Client::RelativePointerManager *m_relativePointerManager;
130 KWayland::Client::PointerGestures *m_pointerGestures;
131 KWayland::Client::EventQueue *m_queue;
135static const QString s_socketName = QStringLiteral(
"kwin-test-wayland-seat-0");
140 , m_compositorInterface(nullptr)
141 , m_seatInterface(nullptr)
142 , m_subCompositorInterface(nullptr)
143 , m_relativePointerManagerV1Interface(nullptr)
144 , m_pointerGesturesV1Interface(nullptr)
145 , m_connection(nullptr)
146 , m_compositor(nullptr)
149 , m_subCompositor(nullptr)
150 , m_relativePointerManager(nullptr)
151 , m_pointerGestures(nullptr)
157void TestWaylandSeat::init()
159 using namespace KWin;
169 QVERIFY(m_subCompositorInterface);
175 m_connection =
new KWayland::Client::ConnectionThread;
176 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
177 m_connection->setSocketName(s_socketName);
179 m_thread =
new QThread(
this);
180 m_connection->moveToThread(m_thread);
183 m_connection->initConnection();
184 QVERIFY(connectedSpy.wait());
186 m_queue =
new KWayland::Client::EventQueue(
this);
187 m_queue->setup(m_connection);
189 KWayland::Client::Registry registry;
190 QSignalSpy compositorSpy(®istry, &KWayland::Client::Registry::compositorAnnounced);
191 QSignalSpy seatSpy(®istry, &KWayland::Client::Registry::seatAnnounced);
192 QSignalSpy shmSpy(®istry, &KWayland::Client::Registry::shmAnnounced);
193 registry.setEventQueue(m_queue);
194 registry.create(m_connection->display());
195 QVERIFY(registry.isValid());
197 QVERIFY(compositorSpy.wait());
200 QVERIFY(m_seatInterface);
201 m_seatInterface->
setName(QStringLiteral(
"seat0"));
202 QVERIFY(seatSpy.wait());
204 m_compositor =
new KWayland::Client::Compositor(
this);
205 m_compositor->setup(registry.bindCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>()));
206 QVERIFY(m_compositor->isValid());
208 m_seat = registry.createSeat(seatSpy.first().first().value<quint32>(), seatSpy.first().last().value<quint32>(),
this);
209 QSignalSpy nameSpy(m_seat, &KWayland::Client::Seat::nameChanged);
210 QVERIFY(nameSpy.wait());
212 m_shm =
new KWayland::Client::ShmPool(
this);
213 m_shm->setup(registry.bindShm(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>()));
214 QVERIFY(m_shm->isValid());
216 m_subCompositor = registry.createSubCompositor(registry.interface(KWayland::Client::Registry::Interface::SubCompositor).name,
217 registry.interface(KWayland::Client::Registry::Interface::SubCompositor).version,
219 QVERIFY(m_subCompositor->isValid());
221 m_relativePointerManager =
222 registry.createRelativePointerManager(registry.interface(KWayland::Client::Registry::Interface::RelativePointerManagerUnstableV1).name,
223 registry.interface(KWayland::Client::Registry::Interface::RelativePointerManagerUnstableV1).version,
225 QVERIFY(m_relativePointerManager->isValid());
227 m_pointerGestures = registry.createPointerGestures(registry.interface(KWayland::Client::Registry::Interface::PointerGesturesUnstableV1).name,
228 registry.interface(KWayland::Client::Registry::Interface::PointerGesturesUnstableV1).version,
230 QVERIFY(m_pointerGestures->isValid());
233void TestWaylandSeat::cleanup()
235 if (m_pointerGestures) {
236 delete m_pointerGestures;
237 m_pointerGestures =
nullptr;
239 if (m_relativePointerManager) {
240 delete m_relativePointerManager;
241 m_relativePointerManager =
nullptr;
243 if (m_subCompositor) {
244 delete m_subCompositor;
245 m_subCompositor =
nullptr;
257 m_compositor =
nullptr;
264 m_connection->deleteLater();
265 m_connection =
nullptr;
278 m_compositorInterface =
nullptr;
279 m_seatInterface =
nullptr;
280 m_subCompositorInterface =
nullptr;
281 m_relativePointerManagerV1Interface =
nullptr;
282 m_pointerGesturesV1Interface =
nullptr;
285bool TestWaylandSeat::sync()
289 return doneSpy.wait();
292void TestWaylandSeat::testName()
295 QCOMPARE(m_seat->name(), QStringLiteral(
"seat0"));
297 QSignalSpy spy(m_seat, &KWayland::Client::Seat::nameChanged);
299 const QString name = QStringLiteral(
"foobar");
300 m_seatInterface->
setName(name);
302 QCOMPARE(m_seat->name(), name);
303 QCOMPARE(spy.count(), 1);
304 QCOMPARE(spy.first().first().toString(), name);
307void TestWaylandSeat::testCapabilities_data()
309 QTest::addColumn<bool>(
"pointer");
310 QTest::addColumn<bool>(
"keyboard");
311 QTest::addColumn<bool>(
"touch");
313 QTest::newRow(
"none") <<
false <<
false <<
false;
314 QTest::newRow(
"pointer") <<
true <<
false <<
false;
315 QTest::newRow(
"keyboard") <<
false <<
true <<
false;
316 QTest::newRow(
"touch") <<
false <<
false <<
true;
317 QTest::newRow(
"pointer/keyboard") <<
true <<
true <<
false;
318 QTest::newRow(
"pointer/touch") <<
true <<
false <<
true;
319 QTest::newRow(
"keyboard/touch") <<
false <<
true <<
true;
320 QTest::newRow(
"all") <<
true <<
true <<
true;
323void TestWaylandSeat::testCapabilities()
325 QVERIFY(!m_seat->hasPointer());
326 QVERIFY(!m_seat->hasKeyboard());
327 QVERIFY(!m_seat->hasTouch());
329 QFETCH(
bool, pointer);
330 QFETCH(
bool, keyboard);
333 QSignalSpy pointerSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
334 QSignalSpy keyboardSpy(m_seat, &KWayland::Client::Seat::hasKeyboardChanged);
335 QSignalSpy touchSpy(m_seat, &KWayland::Client::Seat::hasTouchChanged);
344 QCOMPARE(pointerSpy.isEmpty(), !pointer);
345 if (!pointerSpy.isEmpty()) {
346 QCOMPARE(pointerSpy.first().first().toBool(), pointer);
349 QCOMPARE(keyboardSpy.isEmpty(), !keyboard);
350 if (!keyboardSpy.isEmpty()) {
351 QCOMPARE(keyboardSpy.first().first().toBool(), keyboard);
354 QCOMPARE(touchSpy.isEmpty(), !touch);
355 if (!touchSpy.isEmpty()) {
356 QCOMPARE(touchSpy.first().first().toBool(), touch);
359 QCOMPARE(m_seat->hasPointer(), pointer);
360 QCOMPARE(m_seat->hasKeyboard(), keyboard);
361 QCOMPARE(m_seat->hasTouch(), touch);
364void TestWaylandSeat::testPointer()
366 using namespace KWin;
368 QSignalSpy pointerSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
370 QVERIFY(pointerSpy.wait());
373 KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
374 QVERIFY(surfaceCreatedSpy.wait());
376 QVERIFY(serverSurface);
378 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
379 image.fill(Qt::black);
380 s->attachBuffer(m_shm->createBuffer(image));
381 s->damage(image.rect());
382 s->commit(KWayland::Client::Surface::CommitFlag::None);
384 QVERIFY(committedSpy.wait());
388 KWayland::Client::Pointer *p = m_seat->createPointer(m_seat);
389 QSignalSpy frameSpy(p, &KWayland::Client::Pointer::frame);
390 const KWayland::Client::Pointer &cp = *p;
391 QVERIFY(p->isValid());
392 std::unique_ptr<KWayland::Client::RelativePointer> relativePointer(m_relativePointerManager->createRelativePointer(p));
393 QVERIFY(relativePointer->isValid());
394 QVERIFY(frameSpy.wait());
395 QCOMPARE(frameSpy.count(), 1);
399 QVERIFY(frameSpy.wait());
400 QCOMPARE(frameSpy.count(), 2);
402 QSignalSpy enteredSpy(p, &KWayland::Client::Pointer::entered);
404 QSignalSpy leftSpy(p, &KWayland::Client::Pointer::left);
406 QSignalSpy motionSpy(p, &KWayland::Client::Pointer::motion);
408 QSignalSpy axisSpy(p, &KWayland::Client::Pointer::axisChanged);
410 QSignalSpy buttonSpy(p, &KWayland::Client::Pointer::buttonStateChanged);
412 QSignalSpy relativeMotionSpy(relativePointer.get(), &KWayland::Client::RelativePointer::relativeMotion);
414 QVERIFY(!p->enteredSurface());
415 QVERIFY(!cp.enteredSurface());
416 uint32_t serial = m_display->
serial();
419 QVERIFY(enteredSpy.wait());
420 QCOMPARE_GT(enteredSpy.first().first().value<quint32>(), serial);
421 QCOMPARE(enteredSpy.first().last().toPoint(), QPoint(10, 3));
422 QCOMPARE(frameSpy.count(), 3);
423 QCOMPARE(p->enteredSurface(), s);
424 QCOMPARE(cp.enteredSurface(), s);
426 auto timestamp = 1ms;
431 QVERIFY(motionSpy.wait());
432 QCOMPARE(frameSpy.count(), 4);
433 QCOMPARE(motionSpy.first().first().toPoint(), QPoint(0, 1));
434 QCOMPARE(motionSpy.first().last().value<quint32>(), quint32(1));
439 QVERIFY(relativeMotionSpy.wait());
440 QCOMPARE(relativeMotionSpy.count(), 1);
441 QCOMPARE(frameSpy.count(), 5);
442 QCOMPARE(relativeMotionSpy.first().at(0).toSizeF(), QSizeF(1, 2));
443 QCOMPARE(relativeMotionSpy.first().at(1).toSizeF(), QSizeF(3, 4));
444 QCOMPARE(relativeMotionSpy.first().at(2).value<quint64>(), 1234);
448 m_seatInterface->
notifyPointerAxis(Qt::Horizontal, 10, 120, PointerAxisSource::Wheel);
450 QVERIFY(axisSpy.wait());
451 QCOMPARE(frameSpy.count(), 6);
453 m_seatInterface->
notifyPointerAxis(Qt::Vertical, 20, 240, PointerAxisSource::Wheel);
455 QVERIFY(axisSpy.wait());
456 QCOMPARE(frameSpy.count(), 7);
457 QCOMPARE(axisSpy.first().at(0).value<quint32>(), quint32(2));
458 QCOMPARE(axisSpy.first().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Horizontal);
459 QCOMPARE(axisSpy.first().at(2).value<qreal>(), qreal(10));
461 QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(3));
462 QCOMPARE(axisSpy.last().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Vertical);
463 QCOMPARE(axisSpy.last().at(2).value<qreal>(), qreal(20));
469 QVERIFY(buttonSpy.wait());
470 QCOMPARE(frameSpy.count(), 8);
471 QCOMPARE(buttonSpy.at(0).at(0).value<quint32>(), m_display->
serial());
475 QVERIFY(buttonSpy.wait());
476 QCOMPARE(frameSpy.count(), 9);
477 QCOMPARE(buttonSpy.at(1).at(0).value<quint32>(), m_display->
serial());
481 QVERIFY(buttonSpy.wait());
482 QCOMPARE(frameSpy.count(), 10);
483 QCOMPARE(buttonSpy.at(2).at(0).value<quint32>(), m_display->
serial());
487 QVERIFY(buttonSpy.wait());
488 QCOMPARE(frameSpy.count(), 11);
489 QCOMPARE(buttonSpy.count(), 4);
492 QCOMPARE(buttonSpy.at(0).at(1).value<quint32>(), quint32(4));
494 QCOMPARE(buttonSpy.at(0).at(2).value<quint32>(), quint32(1));
495 QCOMPARE(buttonSpy.at(0).at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Pressed);
498 QCOMPARE(buttonSpy.at(1).at(1).value<quint32>(), quint32(5));
500 QCOMPARE(buttonSpy.at(1).at(2).value<quint32>(), quint32(2));
501 QCOMPARE(buttonSpy.at(1).at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Pressed);
505 QCOMPARE(buttonSpy.at(2).at(1).value<quint32>(), quint32(6));
507 QCOMPARE(buttonSpy.at(2).at(2).value<quint32>(), quint32(2));
508 QCOMPARE(buttonSpy.at(2).at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Released);
512 QCOMPARE(buttonSpy.at(3).at(1).value<quint32>(), quint32(7));
514 QCOMPARE(buttonSpy.at(3).at(2).value<quint32>(), quint32(1));
515 QCOMPARE(buttonSpy.at(3).at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Released);
518 serial = m_display->
serial();
520 QVERIFY(leftSpy.wait());
521 QCOMPARE(frameSpy.count(), 12);
522 QCOMPARE_GT(leftSpy.first().first().value<quint32>(), serial);
523 QVERIFY(!p->enteredSurface());
524 QVERIFY(!cp.enteredSurface());
527 m_seatInterface->
relativePointerMotion(QPointF(1, 2), QPointF(3, 4), std::chrono::milliseconds::zero());
529 QCOMPARE(relativeMotionSpy.count(), 1);
533 QVERIFY(enteredSpy.wait());
534 QCOMPARE(frameSpy.count(), 13);
535 QCOMPARE(p->enteredSurface(), s);
536 QCOMPARE(cp.enteredSurface(), s);
540 QVERIFY(relativeMotionSpy.wait());
541 QCOMPARE(relativeMotionSpy.count(), 2);
542 QCOMPARE(relativeMotionSpy.last().at(0).toSizeF(), QSizeF(4, 5));
543 QCOMPARE(relativeMotionSpy.last().at(1).toSizeF(), QSizeF(6, 7));
544 QCOMPARE(relativeMotionSpy.last().at(2).value<quint64>(), 1234);
547void TestWaylandSeat::testPointerTransformation_data()
549 QTest::addColumn<QMatrix4x4>(
"enterTransformation");
551 QTest::addColumn<QPointF>(
"expectedEnterPoint");
553 QTest::addColumn<QPointF>(
"expectedMovePoint");
556 tm.translate(-10, -15);
557 QTest::newRow(
"translation") << tm << QPointF(10, 3) << QPointF(0, 1);
560 QTest::newRow(
"scale") << sm << QPointF(40, 36) << QPointF(20, 32);
562 rotate.rotate(90, 0, 0, 1);
563 QTest::newRow(
"rotate") << rotate << QPointF(-18, 20) << QPointF(-16, 10);
566void TestWaylandSeat::testPointerTransformation()
568 using namespace KWin;
570 QSignalSpy pointerSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
572 QVERIFY(pointerSpy.wait());
574 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
575 KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
576 QVERIFY(surfaceCreatedSpy.wait());
578 QVERIFY(serverSurface);
580 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
581 image.fill(Qt::black);
582 s->attachBuffer(m_shm->createBuffer(image));
583 s->damage(image.rect());
584 s->commit(KWayland::Client::Surface::CommitFlag::None);
586 QVERIFY(committedSpy.wait());
588 KWayland::Client::Pointer *p = m_seat->createPointer(m_seat);
589 QVERIFY(p->isValid());
590 const KWayland::Client::Pointer &cp = *p;
592 QSignalSpy enteredSpy(p, &KWayland::Client::Pointer::entered);
593 QSignalSpy leftSpy(p, &KWayland::Client::Pointer::left);
594 QSignalSpy motionSpy(p, &KWayland::Client::Pointer::motion);
596 QVERIFY(!p->enteredSurface());
597 QVERIFY(!cp.enteredSurface());
598 uint32_t serial = m_display->
serial();
599 QFETCH(QMatrix4x4, enterTransformation);
600 m_seatInterface->
notifyPointerEnter(serverSurface, QPointF(20, 18), enterTransformation);
602 QVERIFY(enteredSpy.wait());
603 QCOMPARE_GT(enteredSpy.first().first().value<quint32>(), serial);
604 QTEST(enteredSpy.first().last().toPointF(),
"expectedEnterPoint");
605 QCOMPARE(p->enteredSurface(), s);
606 QCOMPARE(cp.enteredSurface(), s);
609 m_seatInterface->
setTimestamp(std::chrono::milliseconds(1));
612 QVERIFY(motionSpy.wait());
613 QTEST(motionSpy.first().first().toPointF(),
"expectedMovePoint");
614 QCOMPARE(motionSpy.first().last().value<quint32>(), quint32(1));
617 serial = m_display->
serial();
619 QVERIFY(leftSpy.wait());
620 QCOMPARE_GT(leftSpy.first().first().value<quint32>(), serial);
621 QVERIFY(!p->enteredSurface());
622 QVERIFY(!cp.enteredSurface());
626 QVERIFY(enteredSpy.wait());
627 QCOMPARE(p->enteredSurface(), s);
628 QCOMPARE(cp.enteredSurface(), s);
630 QSignalSpy serverSurfaceDestroyedSpy(serverSurface, &QObject::destroyed);
632 QVERIFY(serverSurfaceDestroyedSpy.wait());
638void TestWaylandSeat::testPointerButton_data()
640 QTest::addColumn<Qt::MouseButton>(
"qtButton");
641 QTest::addColumn<quint32>(
"waylandButton");
643 QTest::newRow(
"left") << Qt::LeftButton << quint32(BTN_LEFT);
644 QTest::newRow(
"right") << Qt::RightButton << quint32(BTN_RIGHT);
645 QTest::newRow(
"middle") << Qt::MiddleButton << quint32(BTN_MIDDLE);
646 QTest::newRow(
"back") << Qt::BackButton << quint32(BTN_BACK);
647 QTest::newRow(
"x1") << Qt::XButton1 << quint32(BTN_BACK);
648 QTest::newRow(
"extra1") << Qt::ExtraButton1 << quint32(BTN_BACK);
649 QTest::newRow(
"forward") << Qt::ForwardButton << quint32(BTN_FORWARD);
650 QTest::newRow(
"x2") << Qt::XButton2 << quint32(BTN_FORWARD);
651 QTest::newRow(
"extra2") << Qt::ExtraButton2 << quint32(BTN_FORWARD);
652 QTest::newRow(
"task") << Qt::TaskButton << quint32(BTN_TASK);
653 QTest::newRow(
"extra3") << Qt::ExtraButton3 << quint32(BTN_TASK);
654 QTest::newRow(
"extra4") << Qt::ExtraButton4 << quint32(BTN_EXTRA);
655 QTest::newRow(
"extra5") << Qt::ExtraButton5 << quint32(BTN_SIDE);
656 QTest::newRow(
"extra6") << Qt::ExtraButton6 << quint32(0x118);
657 QTest::newRow(
"extra7") << Qt::ExtraButton7 << quint32(0x119);
658 QTest::newRow(
"extra8") << Qt::ExtraButton8 << quint32(0x11a);
659 QTest::newRow(
"extra9") << Qt::ExtraButton9 << quint32(0x11b);
660 QTest::newRow(
"extra10") << Qt::ExtraButton10 << quint32(0x11c);
661 QTest::newRow(
"extra11") << Qt::ExtraButton11 << quint32(0x11d);
662 QTest::newRow(
"extra12") << Qt::ExtraButton12 << quint32(0x11e);
663 QTest::newRow(
"extra13") << Qt::ExtraButton13 << quint32(0x11f);
666void TestWaylandSeat::testPointerButton()
668 using namespace KWin;
670 QSignalSpy pointerSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
672 QVERIFY(pointerSpy.wait());
675 KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
676 QVERIFY(surfaceCreatedSpy.wait());
678 QVERIFY(serverSurface);
680 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
681 image.fill(Qt::black);
682 s->attachBuffer(m_shm->createBuffer(image));
683 s->damage(image.rect());
684 s->commit(KWayland::Client::Surface::CommitFlag::None);
686 QVERIFY(committedSpy.wait());
688 std::unique_ptr<KWayland::Client::Pointer> p(m_seat->createPointer());
689 QVERIFY(p->isValid());
690 QSignalSpy buttonChangedSpy(p.get(), &KWayland::Client::Pointer::buttonStateChanged);
691 wl_display_flush(m_connection->display());
692 QCoreApplication::processEvents();
697 QCoreApplication::processEvents();
699 QFETCH(Qt::MouseButton, qtButton);
700 QFETCH(quint32, waylandButton);
701 std::chrono::milliseconds timestamp(1);
709 QVERIFY(buttonChangedSpy.wait());
710 QCOMPARE(buttonChangedSpy.count(), 1);
711 QCOMPARE(buttonChangedSpy.last().at(0).value<quint32>(), m_seatInterface->
pointerButtonSerial(waylandButton));
712 QCOMPARE(buttonChangedSpy.last().at(0).value<quint32>(), m_seatInterface->
pointerButtonSerial(qtButton));
713 QCOMPARE(buttonChangedSpy.last().at(1).value<quint32>(), timestamp.count());
714 QCOMPARE(buttonChangedSpy.last().at(2).value<quint32>(), waylandButton);
715 QCOMPARE(buttonChangedSpy.last().at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Pressed);
722 QVERIFY(buttonChangedSpy.wait());
723 QCOMPARE(buttonChangedSpy.count(), 2);
724 QCOMPARE(buttonChangedSpy.last().at(0).value<quint32>(), m_seatInterface->
pointerButtonSerial(waylandButton));
725 QCOMPARE(buttonChangedSpy.last().at(0).value<quint32>(), m_seatInterface->
pointerButtonSerial(qtButton));
726 QCOMPARE(buttonChangedSpy.last().at(1).value<quint32>(), timestamp.count());
727 QCOMPARE(buttonChangedSpy.last().at(2).value<quint32>(), waylandButton);
728 QCOMPARE(buttonChangedSpy.last().at(3).value<KWayland::Client::Pointer::ButtonState>(), KWayland::Client::Pointer::ButtonState::Released);
731void TestWaylandSeat::testPointerSubSurfaceTree()
734 using namespace KWin;
737 QSignalSpy hasPointerChangedSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
739 QVERIFY(hasPointerChangedSpy.wait());
740 std::unique_ptr<KWayland::Client::Pointer> pointer(m_seat->createPointer());
745 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
746 std::unique_ptr<KWayland::Client::Surface> parentSurface(m_compositor->createSurface());
747 std::unique_ptr<KWayland::Client::Surface> childSurface(m_compositor->createSurface());
748 std::unique_ptr<KWayland::Client::Surface> grandChild1Surface(m_compositor->createSurface());
749 std::unique_ptr<KWayland::Client::Surface> grandChild2Surface(m_compositor->createSurface());
750 std::unique_ptr<KWayland::Client::SubSurface> childSubSurface(m_subCompositor->createSubSurface(childSurface.get(), parentSurface.get()));
751 std::unique_ptr<KWayland::Client::SubSurface> grandChild1SubSurface(m_subCompositor->createSubSurface(grandChild1Surface.get(), childSurface.get()));
752 std::unique_ptr<KWayland::Client::SubSurface> grandChild2SubSurface(m_subCompositor->createSubSurface(grandChild2Surface.get(), childSurface.get()));
753 grandChild2SubSurface->setPosition(QPoint(0, 25));
756 auto render = [
this](KWayland::Client::Surface *s,
const QSize &size) {
757 QImage image(size, QImage::Format_ARGB32_Premultiplied);
758 image.fill(Qt::black);
759 s->attachBuffer(m_shm->createBuffer(image));
760 s->damage(QRect(QPoint(0, 0), size));
761 s->commit(KWayland::Client::Surface::CommitFlag::None);
763 render(grandChild2Surface.get(), QSize(50, 50));
764 render(grandChild1Surface.get(), QSize(50, 50));
765 render(childSurface.get(), QSize(50, 100));
766 render(parentSurface.get(), QSize(100, 100));
768 QVERIFY(surfaceCreatedSpy.wait());
769 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
773 QSignalSpy enteredSpy(pointer.get(), &KWayland::Client::Pointer::entered);
774 QSignalSpy leftSpy(pointer.get(), &KWayland::Client::Pointer::left);
775 QSignalSpy motionSpy(pointer.get(), &KWayland::Client::Pointer::motion);
777 std::chrono::milliseconds timestamp(1);
780 QVERIFY(enteredSpy.wait());
781 QCOMPARE(enteredSpy.count(), 1);
782 QCOMPARE(leftSpy.count(), 0);
783 QCOMPARE(motionSpy.count(), 0);
784 QCOMPARE(enteredSpy.last().last().toPointF(), QPointF(25, 25));
785 QCOMPARE(pointer->enteredSurface(), grandChild2Surface.get());
790 QVERIFY(motionSpy.wait());
791 QCOMPARE(enteredSpy.count(), 1);
792 QCOMPARE(leftSpy.count(), 0);
793 QCOMPARE(motionSpy.count(), 1);
794 QCOMPARE(motionSpy.last().first().toPointF(), QPointF(25, 35));
799 QVERIFY(enteredSpy.wait());
800 QCOMPARE(enteredSpy.count(), 2);
801 QCOMPARE(leftSpy.count(), 1);
802 QCOMPARE(motionSpy.count(), 2);
803 QCOMPARE(enteredSpy.last().last().toPointF(), QPointF(25, 80));
804 QCOMPARE(pointer->enteredSurface(), childSurface.get());
808 QVERIFY(leftSpy.wait());
809 QCOMPARE(enteredSpy.count(), 2);
810 QCOMPARE(leftSpy.count(), 2);
811 QCOMPARE(motionSpy.count(), 2);
815 QVERIFY(enteredSpy.wait());
816 QCOMPARE(enteredSpy.count(), 3);
817 QCOMPARE(leftSpy.count(), 2);
818 QCOMPARE(motionSpy.count(), 2);
819 QCOMPARE(enteredSpy.last().last().toPointF(), QPointF(75, 50));
820 QCOMPARE(pointer->enteredSurface(), parentSurface.get());
823void TestWaylandSeat::testPointerSwipeGesture_data()
825 QTest::addColumn<bool>(
"cancel");
826 QTest::addColumn<int>(
"expectedEndCount");
827 QTest::addColumn<int>(
"expectedCancelCount");
829 QTest::newRow(
"end") <<
false << 1 << 0;
830 QTest::newRow(
"cancel") <<
true << 0 << 1;
833void TestWaylandSeat::testPointerSwipeGesture()
835 using namespace KWin;
838 QSignalSpy hasPointerChangedSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
840 QVERIFY(hasPointerChangedSpy.wait());
841 std::unique_ptr<KWayland::Client::Pointer> pointer(m_seat->createPointer());
842 std::unique_ptr<KWayland::Client::PointerSwipeGesture> gesture(m_pointerGestures->createSwipeGesture(pointer.get()));
844 QVERIFY(gesture->isValid());
845 QVERIFY(gesture->surface().isNull());
846 QCOMPARE(gesture->fingerCount(), 0u);
848 QSignalSpy startSpy(gesture.get(), &KWayland::Client::PointerSwipeGesture::started);
849 QSignalSpy updateSpy(gesture.get(), &KWayland::Client::PointerSwipeGesture::updated);
850 QSignalSpy endSpy(gesture.get(), &KWayland::Client::PointerSwipeGesture::ended);
851 QSignalSpy cancelledSpy(gesture.get(), &KWayland::Client::PointerSwipeGesture::cancelled);
854 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
855 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
856 QVERIFY(surfaceCreatedSpy.wait());
857 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
858 QVERIFY(serverSurface);
860 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
861 image.fill(Qt::black);
862 surface->attachBuffer(m_shm->createBuffer(image));
863 surface->damage(image.rect());
864 surface->commit(KWayland::Client::Surface::CommitFlag::None);
866 QVERIFY(committedSpy.wait());
870 QVERIFY(m_seatInterface->
pointer());
873 std::chrono::milliseconds timestamp(1);
876 QVERIFY(startSpy.wait());
877 QCOMPARE(startSpy.count(), 1);
878 QCOMPARE(startSpy.first().at(0).value<quint32>(), m_display->
serial());
879 QCOMPARE(startSpy.first().at(1).value<quint32>(), 1u);
880 QCOMPARE(gesture->fingerCount(), 2u);
881 QCOMPARE(gesture->surface().data(), surface.get());
886 QCOMPARE(startSpy.count(), 1);
891 QVERIFY(updateSpy.wait());
894 QVERIFY(updateSpy.wait());
895 QCOMPARE(updateSpy.count(), 2);
896 QCOMPARE(updateSpy.at(0).at(0).toSizeF(), QSizeF(2, 3));
897 QCOMPARE(updateSpy.at(0).at(1).value<quint32>(), 2u);
898 QCOMPARE(updateSpy.at(1).at(0).toSizeF(), QSizeF(4, 5));
899 QCOMPARE(updateSpy.at(1).at(1).value<quint32>(), 3u);
902 QFETCH(
bool, cancel);
912 QVERIFY(spy->wait());
913 QFETCH(
int, expectedEndCount);
914 QCOMPARE(endSpy.count(), expectedEndCount);
915 QFETCH(
int, expectedCancelCount);
916 QCOMPARE(cancelledSpy.count(), expectedCancelCount);
917 QCOMPARE(spy->count(), 1);
918 QCOMPARE(spy->first().at(0).value<quint32>(), m_display->
serial());
919 QCOMPARE(spy->first().at(1).value<quint32>(), 4u);
921 QCOMPARE(gesture->fingerCount(), 0u);
922 QVERIFY(gesture->surface().isNull());
927 QVERIFY(startSpy.wait());
933 QVERIFY(updateSpy.wait());
941 QVERIFY(spy->wait());
944void TestWaylandSeat::testPointerPinchGesture_data()
946 QTest::addColumn<bool>(
"cancel");
947 QTest::addColumn<int>(
"expectedEndCount");
948 QTest::addColumn<int>(
"expectedCancelCount");
950 QTest::newRow(
"end") <<
false << 1 << 0;
951 QTest::newRow(
"cancel") <<
true << 0 << 1;
954void TestWaylandSeat::testPointerPinchGesture()
956 using namespace KWin;
959 QSignalSpy hasPointerChangedSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
961 QVERIFY(hasPointerChangedSpy.wait());
962 std::unique_ptr<KWayland::Client::Pointer> pointer(m_seat->createPointer());
963 std::unique_ptr<KWayland::Client::PointerPinchGesture> gesture(m_pointerGestures->createPinchGesture(pointer.get()));
965 QVERIFY(gesture->isValid());
966 QVERIFY(gesture->surface().isNull());
967 QCOMPARE(gesture->fingerCount(), 0u);
969 QSignalSpy startSpy(gesture.get(), &KWayland::Client::PointerPinchGesture::started);
970 QSignalSpy updateSpy(gesture.get(), &KWayland::Client::PointerPinchGesture::updated);
971 QSignalSpy endSpy(gesture.get(), &KWayland::Client::PointerPinchGesture::ended);
972 QSignalSpy cancelledSpy(gesture.get(), &KWayland::Client::PointerPinchGesture::cancelled);
975 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
976 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
977 QVERIFY(surfaceCreatedSpy.wait());
978 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
979 QVERIFY(serverSurface);
981 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
982 image.fill(Qt::black);
983 surface->attachBuffer(m_shm->createBuffer(image));
984 surface->damage(image.rect());
985 surface->commit(KWayland::Client::Surface::CommitFlag::None);
987 QVERIFY(committedSpy.wait());
991 QVERIFY(m_seatInterface->
pointer());
994 std::chrono::milliseconds timestamp(1);
997 QVERIFY(startSpy.wait());
998 QCOMPARE(startSpy.count(), 1);
999 QCOMPARE(startSpy.first().at(0).value<quint32>(), m_display->
serial());
1000 QCOMPARE(startSpy.first().at(1).value<quint32>(), 1u);
1001 QCOMPARE(gesture->fingerCount(), 3u);
1002 QCOMPARE(gesture->surface().data(), surface.get());
1007 QCOMPARE(startSpy.count(), 1);
1012 QVERIFY(updateSpy.wait());
1015 QVERIFY(updateSpy.wait());
1016 QCOMPARE(updateSpy.count(), 2);
1017 QCOMPARE(updateSpy.at(0).at(0).toSizeF(), QSizeF(2, 3));
1018 QCOMPARE(updateSpy.at(0).at(1).value<quint32>(), 2u);
1019 QCOMPARE(updateSpy.at(0).at(2).value<quint32>(), 45u);
1020 QCOMPARE(updateSpy.at(0).at(3).value<quint32>(), 2u);
1021 QCOMPARE(updateSpy.at(1).at(0).toSizeF(), QSizeF(4, 5));
1022 QCOMPARE(updateSpy.at(1).at(1).value<quint32>(), 1u);
1023 QCOMPARE(updateSpy.at(1).at(2).value<quint32>(), 90u);
1024 QCOMPARE(updateSpy.at(1).at(3).value<quint32>(), 3u);
1027 QFETCH(
bool, cancel);
1032 spy = &cancelledSpy;
1037 QVERIFY(spy->wait());
1038 QFETCH(
int, expectedEndCount);
1039 QCOMPARE(endSpy.count(), expectedEndCount);
1040 QFETCH(
int, expectedCancelCount);
1041 QCOMPARE(cancelledSpy.count(), expectedCancelCount);
1042 QCOMPARE(spy->count(), 1);
1043 QCOMPARE(spy->first().at(0).value<quint32>(), m_display->
serial());
1044 QCOMPARE(spy->first().at(1).value<quint32>(), 4u);
1046 QCOMPARE(gesture->fingerCount(), 0u);
1047 QVERIFY(gesture->surface().isNull());
1052 QVERIFY(startSpy.wait());
1058 QVERIFY(updateSpy.wait());
1066 QVERIFY(spy->wait());
1069void TestWaylandSeat::testPointerHoldGesture_data()
1071 QTest::addColumn<bool>(
"cancel");
1072 QTest::addColumn<int>(
"expectedEndCount");
1073 QTest::addColumn<int>(
"expectedCancelCount");
1075 QTest::newRow(
"end") <<
false << 1 << 0;
1076 QTest::newRow(
"cancel") <<
true << 0 << 1;
1081 using zwp_pointer_gesture_hold_v1::zwp_pointer_gesture_hold_v1;
1083 void zwp_pointer_gesture_hold_v1_begin(uint32_t serial, uint32_t time, wl_surface *surface, uint32_t fingers)
override
1085 Q_EMIT
started(serial, time, surface, fingers);
1088 void zwp_pointer_gesture_hold_v1_end(uint32_t serial, uint32_t time, int32_t
cancelled)
override
1093 void started(quint32 serial, quint32 time,
void *surface, quint32 fingers);
1094 void ended(quint32 serial, quint32 time);
1098void TestWaylandSeat::testPointerHoldGesture()
1100 using namespace KWin;
1103 QSignalSpy hasPointerChangedSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
1105 QVERIFY(hasPointerChangedSpy.wait());
1106 std::unique_ptr<KWayland::Client::Pointer> pointer(m_seat->createPointer());
1107 KWayland::Client::Registry registry;
1108 QSignalSpy gesturesAnnoucedSpy(®istry, &KWayland::Client::Registry::pointerGesturesUnstableV1Announced);
1109 registry.create(m_connection);
1111 QVERIFY(gesturesAnnoucedSpy.wait());
1112 QtWayland::zwp_pointer_gestures_v1 gestures(registry, gesturesAnnoucedSpy.first().at(0).value<
int>(), gesturesAnnoucedSpy.first().at(1).value<
int>());
1114 QVERIFY(gesture.isInitialized());
1121 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
1122 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
1123 QVERIFY(surfaceCreatedSpy.wait());
1124 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
1125 QVERIFY(serverSurface);
1127 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
1128 image.fill(Qt::black);
1129 surface->attachBuffer(m_shm->createBuffer(image));
1130 surface->damage(image.rect());
1131 surface->commit(KWayland::Client::Surface::CommitFlag::None);
1133 QVERIFY(committedSpy.wait());
1137 QVERIFY(m_seatInterface->
pointer());
1140 std::chrono::milliseconds timestamp(1);
1143 QVERIFY(startSpy.wait());
1144 QCOMPARE(startSpy.count(), 1);
1145 QCOMPARE(startSpy.first().at(0).value<quint32>(), m_display->
serial());
1146 QCOMPARE(startSpy.first().at(1).value<quint32>(), 1u);
1147 QCOMPARE(startSpy.first().at(2).value<
void *>(), *surface.get());
1148 QCOMPARE(startSpy.first().at(3).value<quint32>(), 3);
1153 QCOMPARE(startSpy.count(), 1);
1156 QFETCH(
bool, cancel);
1161 spy = &cancelledSpy;
1166 QVERIFY(spy->wait());
1167 QFETCH(
int, expectedEndCount);
1168 QCOMPARE(endSpy.count(), expectedEndCount);
1169 QFETCH(
int, expectedCancelCount);
1170 QCOMPARE(cancelledSpy.count(), expectedCancelCount);
1171 QCOMPARE(spy->count(), 1);
1172 QCOMPARE(spy->first().at(0).value<quint32>(), m_display->
serial());
1173 QCOMPARE(spy->first().at(1).value<quint32>(), 2);
1178 QVERIFY(startSpy.wait());
1187 QVERIFY(spy->wait());
1190void TestWaylandSeat::testPointerAxis()
1192 using namespace KWin;
1195 QSignalSpy hasPointerChangedSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
1197 QVERIFY(hasPointerChangedSpy.wait());
1198 std::unique_ptr<KWayland::Client::Pointer> pointer(m_seat->createPointer());
1202 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
1203 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
1204 QVERIFY(surfaceCreatedSpy.wait());
1205 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
1206 QVERIFY(serverSurface);
1208 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
1209 image.fill(Qt::black);
1210 surface->attachBuffer(m_shm->createBuffer(image));
1211 surface->damage(image.rect());
1212 surface->commit(KWayland::Client::Surface::CommitFlag::None);
1214 QVERIFY(committedSpy.wait());
1218 QSignalSpy frameSpy(pointer.get(), &KWayland::Client::Pointer::frame);
1219 QVERIFY(frameSpy.wait());
1220 QCOMPARE(frameSpy.count(), 1);
1223 QSignalSpy axisSourceSpy(pointer.get(), &KWayland::Client::Pointer::axisSourceChanged);
1224 QSignalSpy axisSpy(pointer.get(), &KWayland::Client::Pointer::axisChanged);
1225 QSignalSpy axisDiscreteSpy(pointer.get(), &KWayland::Client::Pointer::axisDiscreteChanged);
1226 QSignalSpy axisStoppedSpy(pointer.get(), &KWayland::Client::Pointer::axisStopped);
1228 std::chrono::milliseconds timestamp(1);
1230 m_seatInterface->
notifyPointerAxis(Qt::Vertical, 10, 120, PointerAxisSource::Wheel);
1232 QVERIFY(frameSpy.wait());
1233 QCOMPARE(frameSpy.count(), 2);
1234 QCOMPARE(axisSourceSpy.count(), 1);
1235 QCOMPARE(axisSourceSpy.last().at(0).value<KWayland::Client::Pointer::AxisSource>(), KWayland::Client::Pointer::AxisSource::Wheel);
1236 QCOMPARE(axisDiscreteSpy.count(), 1);
1237 QCOMPARE(axisDiscreteSpy.last().at(0).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Vertical);
1238 QCOMPARE(axisDiscreteSpy.last().at(1).value<qint32>(), 1);
1239 QCOMPARE(axisSpy.count(), 1);
1240 QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(1));
1241 QCOMPARE(axisSpy.last().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Vertical);
1242 QCOMPARE(axisSpy.last().at(2).value<qreal>(), 10.0);
1243 QCOMPARE(axisStoppedSpy.count(), 0);
1247 m_seatInterface->
notifyPointerAxis(Qt::Horizontal, 42, 0, PointerAxisSource::Finger);
1249 QVERIFY(frameSpy.wait());
1250 QCOMPARE(frameSpy.count(), 3);
1251 QCOMPARE(axisSourceSpy.count(), 2);
1252 QCOMPARE(axisSourceSpy.last().at(0).value<KWayland::Client::Pointer::AxisSource>(), KWayland::Client::Pointer::AxisSource::Finger);
1253 QCOMPARE(axisDiscreteSpy.count(), 1);
1254 QCOMPARE(axisSpy.count(), 2);
1255 QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(2));
1256 QCOMPARE(axisSpy.last().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Horizontal);
1257 QCOMPARE(axisSpy.last().at(2).value<qreal>(), 42.0);
1258 QCOMPARE(axisStoppedSpy.count(), 0);
1262 m_seatInterface->
notifyPointerAxis(Qt::Horizontal, 0, 0, PointerAxisSource::Finger);
1264 QVERIFY(frameSpy.wait());
1265 QCOMPARE(frameSpy.count(), 4);
1266 QCOMPARE(axisSourceSpy.count(), 3);
1267 QCOMPARE(axisSourceSpy.last().at(0).value<KWayland::Client::Pointer::AxisSource>(), KWayland::Client::Pointer::AxisSource::Finger);
1268 QCOMPARE(axisDiscreteSpy.count(), 1);
1269 QCOMPARE(axisSpy.count(), 2);
1270 QCOMPARE(axisStoppedSpy.count(), 1);
1271 QCOMPARE(axisStoppedSpy.last().at(0).value<quint32>(), 3);
1272 QCOMPARE(axisStoppedSpy.last().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Horizontal);
1276 m_seatInterface->
notifyPointerAxis(Qt::Horizontal, 42, 120, PointerAxisSource::Unknown);
1278 QVERIFY(frameSpy.wait());
1279 QCOMPARE(frameSpy.count(), 5);
1280 QCOMPARE(axisSourceSpy.count(), 3);
1281 QCOMPARE(axisDiscreteSpy.count(), 2);
1282 QCOMPARE(axisDiscreteSpy.last().at(0).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Horizontal);
1283 QCOMPARE(axisDiscreteSpy.last().at(1).value<qint32>(), 1);
1284 QCOMPARE(axisSpy.count(), 3);
1285 QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(4));
1286 QCOMPARE(axisSpy.last().at(1).value<KWayland::Client::Pointer::Axis>(), KWayland::Client::Pointer::Axis::Horizontal);
1287 QCOMPARE(axisSpy.last().at(2).value<qreal>(), 42.0);
1288 QCOMPARE(axisStoppedSpy.count(), 1);
1291void TestWaylandSeat::testCursor()
1293 using namespace KWin;
1295 QSignalSpy pointerSpy(m_seat, &KWayland::Client::Seat::hasPointerChanged);
1297 QVERIFY(pointerSpy.wait());
1300 KWayland::Client::Surface *surface = m_compositor->createSurface(m_compositor);
1301 QVERIFY(surfaceCreatedSpy.wait());
1303 QVERIFY(serverSurface);
1305 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
1306 image.fill(Qt::black);
1307 surface->attachBuffer(m_shm->createBuffer(image));
1308 surface->damage(image.rect());
1309 surface->commit(KWayland::Client::Surface::CommitFlag::None);
1311 QVERIFY(committedSpy.wait());
1313 std::unique_ptr<KWayland::Client::Pointer> p(m_seat->createPointer());
1314 QVERIFY(p->isValid());
1315 wl_display_flush(m_connection->display());
1316 QCoreApplication::processEvents();
1318 QSignalSpy enteredSpy(p.get(), &KWayland::Client::Pointer::entered);
1321 m_seatInterface->
notifyPointerEnter(serverSurface, QPointF(20, 18), QPointF(10, 15));
1322 QVERIFY(enteredSpy.wait());
1323 QCOMPARE_GT(enteredSpy.first().first().value<quint32>(), serial);
1328 p->setCursor(
nullptr);
1329 QVERIFY(cursorChangedSpy.wait());
1330 QCOMPARE(cursorChangedSpy.count(), 1);
1331 auto cursor = std::get<KWin::PointerSurfaceCursor *>(cursorChangedSpy.last().first().value<
KWin::PointerCursor>());
1333 QVERIFY(!cursor->surface());
1334 QCOMPARE(cursor->hotspot(), QPoint());
1337 p->setCursor(
nullptr, QPoint(1, 2));
1338 QVERIFY(cursorChangedSpy.wait());
1339 QCOMPARE(cursorChangedSpy.count(), 2);
1340 QCOMPARE(cursor->surface(),
nullptr);
1341 QCOMPARE(cursor->hotspot(), QPoint(1, 2));
1344 QImage img(QSize(10, 20), QImage::Format_RGB32);
1346 auto cursorSurface = m_compositor->createSurface(m_compositor);
1347 cursorSurface->attachBuffer(m_shm->createBuffer(img));
1348 cursorSurface->damage(QRect(0, 0, 10, 20));
1349 cursorSurface->commit(KWayland::Client::Surface::CommitFlag::None);
1350 p->setCursor(cursorSurface, QPoint(1, 2));
1351 QVERIFY(cursorChangedSpy.wait());
1352 QCOMPARE(cursorChangedSpy.count(), 3);
1353 QCOMPARE(cursor->hotspot(), QPoint(1, 2));
1354 QVERIFY(cursor->surface());
1357 QVERIFY(cursorChangedSpy.wait());
1358 QCOMPARE(cursorChangedSpy.count(), 4);
1359 QVERIFY(!cursor->surface());
1362void TestWaylandSeat::testKeyboard()
1364 using namespace KWin;
1366 QSignalSpy keyboardSpy(m_seat, &KWayland::Client::Seat::hasKeyboardChanged);
1368 QVERIFY(keyboardSpy.wait());
1375 KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
1376 QVERIFY(surfaceCreatedSpy.wait());
1378 QVERIFY(serverSurface);
1380 KWayland::Client::Keyboard *keyboard = m_seat->createKeyboard(m_seat);
1381 QSignalSpy repeatInfoSpy(keyboard, &KWayland::Client::Keyboard::keyRepeatChanged);
1382 const KWayland::Client::Keyboard &ckeyboard = *keyboard;
1383 QVERIFY(keyboard->isValid());
1384 QCOMPARE(keyboard->isKeyRepeatEnabled(),
false);
1385 QCOMPARE(keyboard->keyRepeatDelay(), 0);
1386 QCOMPARE(keyboard->keyRepeatRate(), 0);
1387 QVERIFY(repeatInfoSpy.wait());
1389 auto serverKeyboard = m_seatInterface->
keyboard();
1390 QVERIFY(serverKeyboard);
1393 QCOMPARE(repeatInfoSpy.count(), 1);
1394 QCOMPARE(keyboard->isKeyRepeatEnabled(),
false);
1395 QCOMPARE(keyboard->keyRepeatDelay(), 0);
1396 QCOMPARE(keyboard->keyRepeatRate(), 0);
1400 QVERIFY(repeatInfoSpy.wait());
1401 QCOMPARE(repeatInfoSpy.count(), 2);
1402 QCOMPARE(keyboard->isKeyRepeatEnabled(),
true);
1403 QCOMPARE(keyboard->keyRepeatRate(), 25);
1404 QCOMPARE(keyboard->keyRepeatDelay(), 660);
1406 std::chrono::milliseconds time(1);
1415 QSignalSpy modifierSpy(keyboard, &KWayland::Client::Keyboard::modifiersChanged);
1417 QSignalSpy enteredSpy(keyboard, &KWayland::Client::Keyboard::entered);
1423 QVERIFY(modifierSpy.wait());
1424 QCOMPARE(modifierSpy.count(), 1);
1425 QCOMPARE(modifierSpy.first().at(0).value<quint32>(), quint32(4));
1426 QCOMPARE(modifierSpy.first().at(1).value<quint32>(), quint32(3));
1427 QCOMPARE(modifierSpy.first().at(2).value<quint32>(), quint32(2));
1428 QCOMPARE(modifierSpy.first().at(3).value<quint32>(), quint32(1));
1429 QCOMPARE(enteredSpy.count(), 1);
1431 QCOMPARE(enteredSpy.first().first().value<quint32>(), m_display->
serial() - 1);
1433 QSignalSpy keyChangedSpy(keyboard, &KWayland::Client::Keyboard::keyChanged);
1437 QVERIFY(keyChangedSpy.wait());
1440 QVERIFY(keyChangedSpy.wait());
1443 QVERIFY(keyChangedSpy.wait());
1446 QVERIFY(keyChangedSpy.wait());
1449 QVERIFY(keyChangedSpy.wait());
1451 QCOMPARE(keyChangedSpy.count(), 5);
1452 QCOMPARE(keyChangedSpy.at(0).at(0).value<quint32>(), quint32(KEY_E));
1453 QCOMPARE(keyChangedSpy.at(0).at(1).value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
1454 QCOMPARE(keyChangedSpy.at(0).at(2).value<quint32>(), quint32(4));
1455 QCOMPARE(keyChangedSpy.at(1).at(0).value<quint32>(), quint32(KEY_D));
1456 QCOMPARE(keyChangedSpy.at(1).at(1).value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
1457 QCOMPARE(keyChangedSpy.at(1).at(2).value<quint32>(), quint32(5));
1458 QCOMPARE(keyChangedSpy.at(2).at(0).value<quint32>(), quint32(KEY_K));
1459 QCOMPARE(keyChangedSpy.at(2).at(1).value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
1460 QCOMPARE(keyChangedSpy.at(2).at(2).value<quint32>(), quint32(6));
1461 QCOMPARE(keyChangedSpy.at(3).at(0).value<quint32>(), quint32(KEY_F1));
1462 QCOMPARE(keyChangedSpy.at(3).at(1).value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Pressed);
1463 QCOMPARE(keyChangedSpy.at(3).at(2).value<quint32>(), quint32(7));
1464 QCOMPARE(keyChangedSpy.at(4).at(0).value<quint32>(), quint32(KEY_F1));
1465 QCOMPARE(keyChangedSpy.at(4).at(1).value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
1466 QCOMPARE(keyChangedSpy.at(4).at(2).value<quint32>(), quint32(8));
1471 QCOMPARE(keyChangedSpy.count(), 5);
1474 QVERIFY(keyChangedSpy.wait());
1475 QCOMPARE(keyChangedSpy.count(), 6);
1479 QCOMPARE(keyChangedSpy.count(), 6);
1482 QVERIFY(keyChangedSpy.wait());
1483 QCOMPARE(keyChangedSpy.count(), 7);
1486 QVERIFY(modifierSpy.wait());
1487 QCOMPARE(modifierSpy.count(), 2);
1488 QCOMPARE(modifierSpy.last().at(0).value<quint32>(), quint32(1));
1489 QCOMPARE(modifierSpy.last().at(1).value<quint32>(), quint32(2));
1490 QCOMPARE(modifierSpy.last().at(2).value<quint32>(), quint32(3));
1491 QCOMPARE(modifierSpy.last().at(3).value<quint32>(), quint32(4));
1493 QSignalSpy leftSpy(keyboard, &KWayland::Client::Keyboard::left);
1496 QVERIFY(leftSpy.wait());
1497 QCOMPARE(leftSpy.count(), 1);
1499 QCOMPARE(leftSpy.first().first().value<quint32>(), m_display->
serial() - 1);
1501 QVERIFY(!keyboard->enteredSurface());
1502 QVERIFY(!ckeyboard.enteredSurface());
1506 QVERIFY(modifierSpy.wait());
1509 QCOMPARE(enteredSpy.count(), 2);
1511 QCOMPARE(keyboard->enteredSurface(), s);
1512 QCOMPARE(ckeyboard.enteredSurface(), s);
1514 QSignalSpy serverSurfaceDestroyedSpy(serverSurface, &QObject::destroyed);
1515 QCOMPARE(keyboard->enteredSurface(), s);
1517 QVERIFY(!keyboard->enteredSurface());
1518 QVERIFY(leftSpy.wait());
1519 QCOMPARE(serverSurfaceDestroyedSpy.count(), 1);
1521 QVERIFY(!serverKeyboard->focusedSurface());
1524 std::unique_ptr<KWayland::Client::Surface> s2(m_compositor->createSurface());
1525 QVERIFY(surfaceCreatedSpy.wait());
1526 QCOMPARE(surfaceCreatedSpy.count(), 2);
1527 serverSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
1528 QVERIFY(serverSurface);
1531 QCOMPARE(m_seatInterface->
keyboard(), serverKeyboard);
1534void TestWaylandSeat::testSelection()
1536 using namespace KWin;
1538 KWayland::Client::Registry
registry;
1539 QSignalSpy dataDeviceManagerSpy(®istry, &KWayland::Client::Registry::dataDeviceManagerAnnounced);
1542 registry.create(m_connection->display());
1546 QVERIFY(dataDeviceManagerSpy.wait());
1547 std::unique_ptr<KWayland::Client::DataDeviceManager> ddm(
1548 registry.createDataDeviceManager(dataDeviceManagerSpy.first().first().value<quint32>(), dataDeviceManagerSpy.first().last().value<quint32>()));
1549 QVERIFY(ddm->isValid());
1551 std::unique_ptr<KWayland::Client::DataDevice> dd1(ddm->getDataDevice(m_seat));
1552 QVERIFY(dd1->isValid());
1553 QSignalSpy selectionSpy(dd1.get(), &KWayland::Client::DataDevice::selectionOffered);
1554 QSignalSpy selectionClearedSpy(dd1.get(), &KWayland::Client::DataDevice::selectionCleared);
1557 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
1558 QVERIFY(surface->isValid());
1559 QVERIFY(surfaceCreatedSpy.wait());
1560 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
1564 QVERIFY(selectionClearedSpy.wait());
1565 QVERIFY(selectionSpy.isEmpty());
1566 QVERIFY(!selectionClearedSpy.isEmpty());
1567 selectionClearedSpy.clear();
1571 std::unique_ptr<KWayland::Client::DataSource> ds(ddm->createDataSource());
1572 QVERIFY(ds->isValid());
1573 ds->offer(QStringLiteral(
"text/plain"));
1574 dd1->setSelection(0, ds.get());
1575 QVERIFY(selectionSpy.wait());
1576 QCOMPARE(selectionSpy.count(), 1);
1577 auto ddi = m_seatInterface->
selection();
1579 auto df = selectionSpy.first().first().value<KWayland::Client::DataOffer *>();
1580 QCOMPARE(df->offeredMimeTypes().count(), 1);
1581 QCOMPARE(df->offeredMimeTypes().first().name(), QStringLiteral(
"text/plain"));
1584 dd1->setSelection(0);
1585 QVERIFY(selectionClearedSpy.wait());
1586 QCOMPARE(selectionClearedSpy.count(), 1);
1587 QCOMPARE(selectionSpy.count(), 1);
1593 QCoreApplication::processEvents();
1594 QCoreApplication::processEvents();
1597 dd1->setSelection(0, ds.get());
1598 wl_display_flush(m_connection->display());
1599 QCoreApplication::processEvents();
1600 QCoreApplication::processEvents();
1601 QCOMPARE(selectionSpy.count(), 1);
1609 QCOMPARE(selectionSpy.count(), 1);
1612 QCOMPARE(m_seatInterface->
selection(), ddi);
1613 QVERIFY(selectionSpy.wait());
1614 QCOMPARE(selectionSpy.count(), 2);
1618 QCOMPARE(selectionSpy.count(), 2);
1621 QVERIFY(selectionClearedSpy.wait());
1622 QCOMPARE(selectionSpy.count(), 2);
1625 std::unique_ptr<KWayland::Client::DataDevice> dd2(ddm->getDataDevice(m_seat));
1626 QVERIFY(dd2->isValid());
1627 std::unique_ptr<KWayland::Client::DataSource> ds2(ddm->createDataSource());
1628 QVERIFY(ds2->isValid());
1629 ds2->offer(QStringLiteral(
"text/plain"));
1630 dd2->setSelection(0, ds2.get());
1631 QVERIFY(selectionSpy.wait());
1632 QSignalSpy cancelledSpy(ds2.get(), &KWayland::Client::DataSource::cancelled);
1634 QVERIFY(cancelledSpy.wait());
1637void TestWaylandSeat::testDataDeviceForKeyboardSurface()
1642 using namespace KWin;
1645 QSignalSpy ddiCreatedSpy(ddmi.get(), &DataDeviceManagerInterface::dataDeviceCreated);
1649 auto c =
new KWayland::Client::ConnectionThread;
1650 QSignalSpy connectedSpy(c, &KWayland::Client::ConnectionThread::connected);
1651 c->setSocketName(s_socketName);
1653 auto thread =
new QThread(
this);
1654 c->moveToThread(thread);
1657 c->initConnection();
1658 QVERIFY(connectedSpy.wait());
1660 std::unique_ptr<KWayland::Client::EventQueue>
queue(
new KWayland::Client::EventQueue);
1663 std::unique_ptr<KWayland::Client::Registry>
registry(
new KWayland::Client::Registry);
1664 QSignalSpy interfacesAnnouncedSpy(
registry.get(), &KWayland::Client::Registry::interfacesAnnounced);
1670 QVERIFY(interfacesAnnouncedSpy.wait());
1671 std::unique_ptr<KWayland::Client::Seat>
seat(
1672 registry->createSeat(
registry->interface(KWayland::Client::Registry::Interface::Seat).name,
registry->interface(KWayland::Client::Registry::Interface::Seat).version));
1673 QVERIFY(
seat->isValid());
1674 std::unique_ptr<KWayland::Client::DataDeviceManager> ddm1(
registry->createDataDeviceManager(
registry->interface(KWayland::Client::Registry::Interface::DataDeviceManager).name,
1675 registry->interface(KWayland::Client::Registry::Interface::DataDeviceManager).version));
1676 QVERIFY(ddm1->isValid());
1679 std::unique_ptr<KWayland::Client::DataDevice> dd1(ddm1->getDataDevice(
seat.get()));
1680 QVERIFY(ddiCreatedSpy.wait());
1687 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
1688 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
1689 QVERIFY(surface->isValid());
1690 QVERIFY(surfaceCreatedSpy.wait());
1691 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
1696 KWayland::Client::Registry registry2;
1697 QSignalSpy dataDeviceManagerSpy(®istry2, &KWayland::Client::Registry::dataDeviceManagerAnnounced);
1698 registry2.setEventQueue(m_queue);
1699 registry2.create(m_connection->display());
1700 QVERIFY(registry2.isValid());
1703 QVERIFY(dataDeviceManagerSpy.wait());
1704 std::unique_ptr<KWayland::Client::DataDeviceManager> ddm(
1705 registry2.createDataDeviceManager(dataDeviceManagerSpy.first().first().value<quint32>(), dataDeviceManagerSpy.first().last().value<quint32>()));
1706 QVERIFY(ddm->isValid());
1708 std::unique_ptr<KWayland::Client::DataDevice> dd(ddm->getDataDevice(m_seat));
1709 QVERIFY(dd->isValid());
1710 QVERIFY(ddiCreatedSpy.wait());
1728void TestWaylandSeat::testTouch()
1730 using namespace KWin;
1732 QSignalSpy touchSpy(m_seat, &KWayland::Client::Seat::hasTouchChanged);
1734 QVERIFY(touchSpy.wait());
1738 KWayland::Client::Surface *s = m_compositor->createSurface(m_compositor);
1739 QVERIFY(surfaceCreatedSpy.wait());
1741 QVERIFY(serverSurface);
1747 KWayland::Client::Touch *touch = m_seat->createTouch(m_seat);
1748 QVERIFY(touch->isValid());
1751 wl_display_flush(m_connection->display());
1752 QCoreApplication::processEvents();
1754 QSignalSpy sequenceStartedSpy(touch, &KWayland::Client::Touch::sequenceStarted);
1755 QSignalSpy sequenceEndedSpy(touch, &KWayland::Client::Touch::sequenceEnded);
1756 QSignalSpy sequenceCanceledSpy(touch, &KWayland::Client::Touch::sequenceCanceled);
1757 QSignalSpy frameEndedSpy(touch, &KWayland::Client::Touch::frameEnded);
1758 QSignalSpy pointAddedSpy(touch, &KWayland::Client::Touch::pointAdded);
1759 QSignalSpy pointMovedSpy(touch, &KWayland::Client::Touch::pointMoved);
1760 QSignalSpy pointRemovedSpy(touch, &KWayland::Client::Touch::pointRemoved);
1762 std::chrono::milliseconds timestamp(1);
1769 QVERIFY(sequenceStartedSpy.wait());
1770 QCOMPARE(sequenceStartedSpy.count(), 1);
1771 QCOMPARE(sequenceEndedSpy.count(), 0);
1772 QCOMPARE(sequenceCanceledSpy.count(), 0);
1773 QCOMPARE(frameEndedSpy.count(), 0);
1774 QCOMPARE(pointAddedSpy.count(), 0);
1775 QCOMPARE(pointMovedSpy.count(), 0);
1776 QCOMPARE(pointRemovedSpy.count(), 0);
1777 KWayland::Client::TouchPoint *tp = sequenceStartedSpy.first().first().value<KWayland::Client::TouchPoint *>();
1779 QCOMPARE(tp->downSerial(), m_seatInterface->
display()->
serial());
1780 QCOMPARE(tp->id(), 0);
1781 QVERIFY(tp->isDown());
1782 QCOMPARE(tp->position(), QPointF(5, 6));
1783 QCOMPARE(tp->positions().size(), 1);
1784 QCOMPARE(tp->time(), 1u);
1785 QCOMPARE(tp->timestamps().count(), 1);
1786 QCOMPARE(tp->upSerial(), 0u);
1787 QCOMPARE(tp->surface().data(), s);
1788 QCOMPARE(touch->sequence().count(), 1);
1789 QCOMPARE(touch->sequence().first(), tp);
1793 QVERIFY(frameEndedSpy.wait());
1794 QCOMPARE(frameEndedSpy.count(), 1);
1800 QVERIFY(frameEndedSpy.wait());
1801 QCOMPARE(sequenceStartedSpy.count(), 1);
1802 QCOMPARE(sequenceEndedSpy.count(), 0);
1803 QCOMPARE(sequenceCanceledSpy.count(), 0);
1804 QCOMPARE(frameEndedSpy.count(), 2);
1805 QCOMPARE(pointAddedSpy.count(), 0);
1806 QCOMPARE(pointMovedSpy.count(), 1);
1807 QCOMPARE(pointRemovedSpy.count(), 0);
1808 QCOMPARE(pointMovedSpy.first().first().value<KWayland::Client::TouchPoint *>(), tp);
1810 QCOMPARE(tp->id(), 0);
1811 QVERIFY(tp->isDown());
1812 QCOMPARE(tp->position(), QPointF(0, 0));
1813 QCOMPARE(tp->positions().size(), 2);
1814 QCOMPARE(tp->time(), 2u);
1815 QCOMPARE(tp->timestamps().count(), 2);
1816 QCOMPARE(tp->upSerial(), 0u);
1817 QCOMPARE(tp->surface().data(), s);
1823 QVERIFY(frameEndedSpy.wait());
1824 QCOMPARE(sequenceStartedSpy.count(), 1);
1825 QCOMPARE(sequenceEndedSpy.count(), 0);
1826 QCOMPARE(sequenceCanceledSpy.count(), 0);
1827 QCOMPARE(frameEndedSpy.count(), 3);
1828 QCOMPARE(pointAddedSpy.count(), 1);
1829 QCOMPARE(pointMovedSpy.count(), 1);
1830 QCOMPARE(pointRemovedSpy.count(), 0);
1831 QCOMPARE(touch->sequence().count(), 2);
1832 QCOMPARE(touch->sequence().first(), tp);
1833 KWayland::Client::TouchPoint *tp2 = pointAddedSpy.first().first().value<KWayland::Client::TouchPoint *>();
1835 QCOMPARE(touch->sequence().last(), tp2);
1836 QCOMPARE(tp2->id(), 1);
1837 QVERIFY(tp2->isDown());
1838 QCOMPARE(tp2->position(), QPointF(5, 6));
1839 QCOMPARE(tp2->positions().size(), 1);
1840 QCOMPARE(tp2->time(), 3u);
1841 QCOMPARE(tp2->timestamps().count(), 1);
1842 QCOMPARE(tp2->upSerial(), 0u);
1843 QCOMPARE(tp2->surface().data(), s);
1849 QVERIFY(frameEndedSpy.wait());
1850 QCOMPARE(sequenceStartedSpy.count(), 1);
1851 QCOMPARE(sequenceEndedSpy.count(), 0);
1852 QCOMPARE(sequenceCanceledSpy.count(), 0);
1853 QCOMPARE(frameEndedSpy.count(), 4);
1854 QCOMPARE(pointAddedSpy.count(), 1);
1855 QCOMPARE(pointMovedSpy.count(), 1);
1856 QCOMPARE(pointRemovedSpy.count(), 1);
1857 QCOMPARE(pointRemovedSpy.first().first().value<KWayland::Client::TouchPoint *>(), tp2);
1858 QCOMPARE(tp2->id(), 1);
1859 QVERIFY(!tp2->isDown());
1860 QCOMPARE(tp2->position(), QPointF(5, 6));
1861 QCOMPARE(tp2->positions().size(), 1);
1862 QCOMPARE(tp2->time(), 4u);
1863 QCOMPARE(tp2->timestamps().count(), 2);
1864 QCOMPARE(tp2->upSerial(), m_seatInterface->
display()->
serial());
1865 QCOMPARE(tp2->surface().data(), s);
1876 QVERIFY(frameEndedSpy.wait());
1877 QCOMPARE(sequenceStartedSpy.count(), 1);
1878 QCOMPARE(sequenceEndedSpy.count(), 1);
1879 QCOMPARE(sequenceCanceledSpy.count(), 0);
1880 QCOMPARE(frameEndedSpy.count(), 6);
1881 QCOMPARE(pointAddedSpy.count(), 2);
1882 QCOMPARE(pointMovedSpy.count(), 1);
1883 QCOMPARE(pointRemovedSpy.count(), 3);
1884 QCOMPARE(touch->sequence().count(), 3);
1885 QVERIFY(!touch->sequence().at(0)->isDown());
1886 QVERIFY(!touch->sequence().at(1)->isDown());
1887 QVERIFY(!touch->sequence().at(2)->isDown());
1896 QVERIFY(sequenceCanceledSpy.wait());
1897 QCOMPARE(sequenceStartedSpy.count(), 2);
1898 QCOMPARE(sequenceEndedSpy.count(), 1);
1899 QCOMPARE(sequenceCanceledSpy.count(), 1);
1900 QCOMPARE(frameEndedSpy.count(), 7);
1901 QCOMPARE(pointAddedSpy.count(), 2);
1902 QCOMPARE(pointMovedSpy.count(), 1);
1903 QCOMPARE(pointRemovedSpy.count(), 3);
1904 QCOMPARE(touch->sequence().first()->position(), QPointF(0, 0));
1907void TestWaylandSeat::testKeymap()
1909 using namespace KWin;
1912 QSignalSpy keyboardChangedSpy(m_seat, &KWayland::Client::Seat::hasKeyboardChanged);
1913 QVERIFY(keyboardChangedSpy.wait());
1915 std::unique_ptr<KWayland::Client::Keyboard> keyboard(m_seat->createKeyboard());
1919 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
1920 QVERIFY(surface->isValid());
1921 QVERIFY(surfaceCreatedSpy.wait());
1922 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
1926 QSignalSpy keymapChangedSpy(keyboard.get(), &KWayland::Client::Keyboard::keymapChanged);
1929 QVERIFY(keymapChangedSpy.wait());
1930 int fd = keymapChangedSpy.first().first().toInt();
1933 QCOMPARE(keymapChangedSpy.first().last().value<quint32>(), 4u);
1935 QVERIFY(file.open(fd, QIODevice::ReadOnly));
1936 const char *address =
reinterpret_cast<char *
>(file.map(0, keymapChangedSpy.first().last().value<quint32>()));
1938 QCOMPARE(qstrcmp(address,
"foo"), 0);
1942 keymapChangedSpy.clear();
1944 QVERIFY(keymapChangedSpy.wait());
1945 fd = keymapChangedSpy.first().first().toInt();
1948 QCOMPARE(keymapChangedSpy.first().last().value<quint32>(), 4u);
1949 QVERIFY(file.open(fd, QIODevice::ReadWrite));
1950 address =
reinterpret_cast<char *
>(file.map(0, keymapChangedSpy.first().last().value<quint32>()));
1952 QCOMPARE(qstrcmp(address,
"bar"), 0);
1956#include "test_wayland_seat.moc"
void surfaceCreated(KWin::SurfaceInterface *surface)
DataDeviceInterface allows clients to share data by copy-and-paste and drag-and-drop.
Represents the Global for wl_data_device_manager interface.
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
SurfaceInterface * focusedSurface() const
void setRepeatInfo(qint32 charactersPerSecond, qint32 delay)
void setKeymap(const QByteArray &content)
void cursorChanged(const PointerCursor &cursor)
Represents a Seat on the Wayland Display.
void endPointerHoldGesture()
void setFocusedTouchSurface(SurfaceInterface *surface, const QPointF &surfacePosition=QPointF())
quint32 pointerButtonSerial(quint32 button) const
void setHasTouch(bool has)
void cancelPointerHoldGesture()
Display * display() const
void updatePointerSwipeGesture(const QPointF &delta)
SurfaceInterface * focusedTouchSurface() const
void endPointerPinchGesture()
void setHasKeyboard(bool has)
void setTimestamp(std::chrono::microseconds time)
void setSelection(AbstractDataSource *selection)
bool isTouchSequence() const
void notifyKeyboardKey(quint32 keyCode, KeyboardKeyState state)
void notifyPointerMotion(const QPointF &pos)
void cancelPointerSwipeGesture()
void setName(const QString &name)
void startPointerHoldGesture(quint32 fingerCount)
void setHasPointer(bool has)
void notifyTouchMotion(qint32 id, const QPointF &globalPosition)
SurfaceInterface * focusedPointerSurface() const
SurfaceInterface * focusedKeyboardSurface() const
void updatePointerPinchGesture(const QPointF &delta, qreal scale, qreal rotation)
PointerInterface * pointer() const
void notifyPointerEnter(SurfaceInterface *surface, const QPointF &position, const QPointF &surfacePosition=QPointF())
void notifyPointerLeave()
bool isPointerButtonPressed(quint32 button) const
void startPointerPinchGesture(quint32 fingerCount)
void endPointerSwipeGesture()
void notifyPointerAxis(Qt::Orientation orientation, qreal delta, qint32 deltaV120, PointerAxisSource source, PointerAxisRelativeDirection direction=PointerAxisRelativeDirection::Normal)
KeyboardInterface * keyboard() const
void notifyKeyboardModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group)
QPointF focusedTouchSurfacePosition() const
void notifyPointerFrame()
void startPointerSwipeGesture(quint32 fingerCount)
void notifyTouchUp(qint32 id)
void relativePointerMotion(const QPointF &delta, const QPointF &deltaNonAccelerated, std::chrono::microseconds timestamp)
AbstractDataSource * selection() const
void setFocusedTouchSurfacePosition(const QPointF &surfacePosition)
void notifyPointerButton(quint32 button, PointerButtonState state)
void setFocusedKeyboardSurface(SurfaceInterface *surface)
void cancelPointerPinchGesture()
void notifyTouchDown(qint32 id, const QPointF &globalPosition)
Resource representing a wl_surface.
ClientConnection * client() const
void ended(quint32 serial, quint32 time)
void cancelled(quint32 serial, quint32 time)
void started(quint32 serial, quint32 time, void *surface, quint32 fingers)
TestWaylandSeat(QObject *parent=nullptr)
~WaylandSyncPoint() override
WaylandSyncPoint(KWayland::Client::ConnectionThread *connection, KWayland::Client::EventQueue *eventQueue)
KWayland::Client::Seat * seat
KWayland::Client::EventQueue * queue
void render(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32_Premultiplied)
KWayland::Client::Registry * registry
std::variant< PointerSurfaceCursor *, QByteArray > PointerCursor