void InputStackingOrderTest::init() { using namespace KWayland::Client; // setup connection m_connection = new ConnectionThread; QSignalSpy connectedSpy(m_connection, &ConnectionThread::connected); QVERIFY(connectedSpy.isValid()); m_connection->setSocketName(s_socketName); m_thread = new QThread(this); m_connection->moveToThread(m_thread); m_thread->start(); m_connection->initConnection(); QVERIFY(connectedSpy.wait()); m_queue = new EventQueue(this); QVERIFY(!m_queue->isValid()); m_queue->setup(m_connection); QVERIFY(m_queue->isValid()); Registry registry; registry.setEventQueue(m_queue); QSignalSpy compositorSpy(®istry, &Registry::compositorAnnounced); QSignalSpy shmSpy(®istry, &Registry::shmAnnounced); QSignalSpy shellSpy(®istry, &Registry::shellAnnounced); QSignalSpy seatSpy(®istry, &Registry::seatAnnounced); QSignalSpy allAnnounced(®istry, &Registry::interfacesAnnounced); QVERIFY(allAnnounced.isValid()); QVERIFY(shmSpy.isValid()); QVERIFY(shellSpy.isValid()); QVERIFY(compositorSpy.isValid()); QVERIFY(seatSpy.isValid()); registry.create(m_connection->display()); QVERIFY(registry.isValid()); registry.setup(); QVERIFY(allAnnounced.wait()); QVERIFY(!compositorSpy.isEmpty()); QVERIFY(!shmSpy.isEmpty()); QVERIFY(!shellSpy.isEmpty()); QVERIFY(!seatSpy.isEmpty()); m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this); QVERIFY(m_compositor->isValid()); m_shm = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this); QVERIFY(m_shm->isValid()); m_shell = registry.createShell(shellSpy.first().first().value<quint32>(), shellSpy.first().last().value<quint32>(), this); QVERIFY(m_shell->isValid()); m_seat = registry.createSeat(seatSpy.first().first().value<quint32>(), seatSpy.first().last().value<quint32>(), this); QVERIFY(m_seat->isValid()); QSignalSpy hasPointerSpy(m_seat, &Seat::hasPointerChanged); QVERIFY(hasPointerSpy.isValid()); QVERIFY(hasPointerSpy.wait()); screens()->setCurrent(0); Cursor::setPos(QPoint(640, 512)); }
void ScreenChangesTest::testScreenAddRemove() { // this test verifies that when a new screen is added it gets synced to Wayland // first create a registry to get signals about Outputs announced/removed Registry registry; QSignalSpy allAnnounced(®istry, &Registry::interfacesAnnounced); QVERIFY(allAnnounced.isValid()); QSignalSpy outputAnnouncedSpy(®istry, &Registry::outputAnnounced); QVERIFY(outputAnnouncedSpy.isValid()); QSignalSpy outputRemovedSpy(®istry, &Registry::outputRemoved); QVERIFY(outputRemovedSpy.isValid()); registry.create(Test::waylandConnection()); QVERIFY(registry.isValid()); registry.setup(); QVERIFY(allAnnounced.wait()); // should be one output QCOMPARE(screens()->count(), 1); QCOMPARE(outputAnnouncedSpy.count(), 1); const quint32 firstOutputId = outputAnnouncedSpy.first().first().value<quint32>(); QVERIFY(firstOutputId != 0u); outputAnnouncedSpy.clear(); // let's announce a new output QSignalSpy screensChangedSpy(screens(), &Screens::changed); QVERIFY(screensChangedSpy.isValid()); const QVector<QRect> geometries{QRect(0, 0, 1280, 1024), QRect(1280, 0, 1280, 1024)}; QMetaObject::invokeMethod(kwinApp()->platform(), "outputGeometriesChanged", Qt::DirectConnection, Q_ARG(QVector<QRect>, geometries)); QVERIFY(screensChangedSpy.wait()); QCOMPARE(screensChangedSpy.count(), 1); QCOMPARE(screens()->count(), 2); QCOMPARE(screens()->geometry(0), geometries.at(0)); QCOMPARE(screens()->geometry(1), geometries.at(1)); // this should result in it getting announced, two new outputs are added... QVERIFY(outputAnnouncedSpy.wait()); if (outputAnnouncedSpy.count() < 2) { QVERIFY(outputAnnouncedSpy.wait()); } QCOMPARE(outputAnnouncedSpy.count(), 2); // ... and afterward the previous output gets removed if (outputRemovedSpy.isEmpty()) { QVERIFY(outputRemovedSpy.wait()); } QCOMPARE(outputRemovedSpy.count(), 1); QCOMPARE(outputRemovedSpy.first().first().value<quint32>(), firstOutputId); // let's wait a little bit to ensure we don't get more events QTest::qWait(100); QCOMPARE(outputAnnouncedSpy.count(), 2); QCOMPARE(outputRemovedSpy.count(), 1); // let's create the output objects to ensure they are correct QScopedPointer<Output> o1(registry.createOutput(outputAnnouncedSpy.first().first().value<quint32>(), outputAnnouncedSpy.first().last().value<quint32>())); QVERIFY(o1->isValid()); QSignalSpy o1ChangedSpy(o1.data(), &Output::changed); QVERIFY(o1ChangedSpy.isValid()); QVERIFY(o1ChangedSpy.wait()); QCOMPARE(o1->geometry(), geometries.at(0)); QScopedPointer<Output> o2(registry.createOutput(outputAnnouncedSpy.last().first().value<quint32>(), outputAnnouncedSpy.last().last().value<quint32>())); QVERIFY(o2->isValid()); QSignalSpy o2ChangedSpy(o2.data(), &Output::changed); QVERIFY(o2ChangedSpy.isValid()); QVERIFY(o2ChangedSpy.wait()); QCOMPARE(o2->geometry(), geometries.at(1)); // now let's try to remove one output again outputAnnouncedSpy.clear(); outputRemovedSpy.clear(); screensChangedSpy.clear(); QSignalSpy o1RemovedSpy(o1.data(), &Output::removed); QVERIFY(o1RemovedSpy.isValid()); QSignalSpy o2RemovedSpy(o2.data(), &Output::removed); QVERIFY(o2RemovedSpy.isValid()); const QVector<QRect> geometries2{QRect(0, 0, 1280, 1024)}; QMetaObject::invokeMethod(kwinApp()->platform(), "outputGeometriesChanged", Qt::DirectConnection, Q_ARG(QVector<QRect>, geometries2)); QVERIFY(screensChangedSpy.wait()); QCOMPARE(screensChangedSpy.count(), 1); QCOMPARE(screens()->count(), 1); QCOMPARE(screens()->geometry(0), geometries2.at(0)); QVERIFY(outputAnnouncedSpy.wait()); QCOMPARE(outputAnnouncedSpy.count(), 1); if (o1RemovedSpy.isEmpty()) { QVERIFY(o1RemovedSpy.wait()); } if (o2RemovedSpy.isEmpty()) { QVERIFY(o2RemovedSpy.wait()); } // now wait a bit to ensure we don't get more events QTest::qWait(100); QCOMPARE(outputAnnouncedSpy.count(), 1); QCOMPARE(o1RemovedSpy.count(), 1); QCOMPARE(o2RemovedSpy.count(), 1); QCOMPARE(outputRemovedSpy.count(), 2); }