diff --git a/src/wayland/autotests/client/test_plasma_window_model.cpp b/src/wayland/autotests/client/test_plasma_window_model.cpp index 9b842b51ee..74212ea365 100644 --- a/src/wayland/autotests/client/test_plasma_window_model.cpp +++ b/src/wayland/autotests/client/test_plasma_window_model.cpp @@ -35,6 +35,16 @@ using namespace KWayland::Client; using namespace KWayland::Server; Q_DECLARE_METATYPE(Qt::MouseButton) +typedef void (KWayland::Client::PlasmaWindow::*ClientWindowSignal)(); +Q_DECLARE_METATYPE(ClientWindowSignal) +typedef void (KWayland::Server::PlasmaWindowInterface::*ServerWindowBoolSetter)(bool); +Q_DECLARE_METATYPE(ServerWindowBoolSetter) +typedef void (KWayland::Server::PlasmaWindowInterface::*ServerWindowStringSetter)(const QString&); +Q_DECLARE_METATYPE(ServerWindowStringSetter) +typedef void (KWayland::Server::PlasmaWindowInterface::*ServerWindowQuint32Setter)(quint32); +Q_DECLARE_METATYPE(ServerWindowQuint32Setter) +typedef void (KWayland::Server::PlasmaWindowInterface::*ServerWindowVoidSetter)(); +Q_DECLARE_METATYPE(ServerWindowVoidSetter) class PlasmaWindowModelTest : public QObject { @@ -74,6 +84,9 @@ private Q_SLOTS: // TODO: minimized geometry // TODO: model reset void testCreateWithUnmappedWindow(); + void testChangeWindowAfterModelDestroy_data(); + void testChangeWindowAfterModelDestroy(); + void testCreateWindowAfterModelDestroy(); private: bool testBooleanData(PlasmaWindowModel::AdditionalRoles role, void (PlasmaWindowInterface::*function)(bool)); @@ -715,5 +728,79 @@ void PlasmaWindowModelTest::testCreateWithUnmappedWindow() QCOMPARE(destroyedSpy.count(), 1); } +void PlasmaWindowModelTest::testChangeWindowAfterModelDestroy_data() +{ + QTest::addColumn("changedSignal"); + QTest::addColumn("setter"); + QTest::addColumn("value"); + + QTest::newRow("active") << &PlasmaWindow::activeChanged << qVariantFromValue(&PlasmaWindowInterface::setActive) << QVariant(true); + QTest::newRow("minimized") << &PlasmaWindow::minimizedChanged << qVariantFromValue(&PlasmaWindowInterface::setMinimized) << QVariant(true); + QTest::newRow("fullscreen") << &PlasmaWindow::fullscreenChanged << qVariantFromValue(&PlasmaWindowInterface::setFullscreen) << QVariant(true); + QTest::newRow("keepAbove") << &PlasmaWindow::keepAboveChanged << qVariantFromValue(&PlasmaWindowInterface::setKeepAbove) << QVariant(true); + QTest::newRow("keepBelow") << &PlasmaWindow::keepBelowChanged << qVariantFromValue(&PlasmaWindowInterface::setKeepBelow) << QVariant(true); + QTest::newRow("maximized") << &PlasmaWindow::maximizedChanged << qVariantFromValue(&PlasmaWindowInterface::setMaximized) << QVariant(true); + QTest::newRow("demandsAttention") << &PlasmaWindow::demandsAttentionChanged << qVariantFromValue(&PlasmaWindowInterface::setDemandsAttention) << QVariant(true); + QTest::newRow("closeable") << &PlasmaWindow::closeableChanged << qVariantFromValue(&PlasmaWindowInterface::setCloseable) << QVariant(true); + QTest::newRow("minimizeable") << &PlasmaWindow::minimizeableChanged << qVariantFromValue(&PlasmaWindowInterface::setMinimizeable) << QVariant(true); + QTest::newRow("maximizeable") << &PlasmaWindow::maximizeableChanged << qVariantFromValue(&PlasmaWindowInterface::setMaximizeable) << QVariant(true); + QTest::newRow("fullscreenable") << &PlasmaWindow::fullscreenableChanged << qVariantFromValue(&PlasmaWindowInterface::setFullscreenable) << QVariant(true); + QTest::newRow("skipTaskbar") << &PlasmaWindow::skipTaskbarChanged << qVariantFromValue(&PlasmaWindowInterface::setSkipTaskbar) << QVariant(true); + QTest::newRow("shadeable") << &PlasmaWindow::shadeableChanged << qVariantFromValue(&PlasmaWindowInterface::setShadeable) << QVariant(true); + QTest::newRow("shaded") << &PlasmaWindow::shadedChanged << qVariantFromValue(&PlasmaWindowInterface::setShaded) << QVariant(true); + QTest::newRow("movable") << &PlasmaWindow::movableChanged << qVariantFromValue(&PlasmaWindowInterface::setMovable) << QVariant(true); + QTest::newRow("resizable") << &PlasmaWindow::resizableChanged << qVariantFromValue(&PlasmaWindowInterface::setResizable) << QVariant(true); + QTest::newRow("vdChangeable") << &PlasmaWindow::virtualDesktopChangeableChanged << qVariantFromValue(&PlasmaWindowInterface::setVirtualDesktopChangeable) << QVariant(true); + QTest::newRow("onallDesktop") << &PlasmaWindow::onAllDesktopsChanged << qVariantFromValue(&PlasmaWindowInterface::setOnAllDesktops) << QVariant(true); + QTest::newRow("title") << &PlasmaWindow::titleChanged << qVariantFromValue(&PlasmaWindowInterface::setTitle) << QVariant(QStringLiteral("foo")); + QTest::newRow("appId") << &PlasmaWindow::appIdChanged << qVariantFromValue(&PlasmaWindowInterface::setAppId) << QVariant(QStringLiteral("foo")); + QTest::newRow("icon" ) << &PlasmaWindow::iconChanged << qVariantFromValue(&PlasmaWindowInterface::setThemedIconName) << QVariant(QStringLiteral("foo")); + QTest::newRow("vd") << &PlasmaWindow::virtualDesktopChanged << qVariantFromValue(&PlasmaWindowInterface::setVirtualDesktop) << QVariant(2u); + QTest::newRow("unmapped") << &PlasmaWindow::unmapped << qVariantFromValue(&PlasmaWindowInterface::unmap) << QVariant(); +} + +void PlasmaWindowModelTest::testChangeWindowAfterModelDestroy() +{ + // this test verifies that changes in a window after the model got destroyed doesn't crash + auto model = m_pw->createWindowModel(); + QVERIFY(model); + QSignalSpy windowCreatedSpy(m_pw, &PlasmaWindowManagement::windowCreated); + QVERIFY(windowCreatedSpy.isValid()); + auto w = m_pwInterface->createWindow(m_pwInterface); + QVERIFY(windowCreatedSpy.wait()); + PlasmaWindow *window = windowCreatedSpy.first().first().value(); + QCOMPARE(model->rowCount(), 1); + delete model; + QFETCH(ClientWindowSignal, changedSignal); + QSignalSpy changedSpy(window, changedSignal); + QVERIFY(changedSpy.isValid()); + QVERIFY(!window->isActive()); + QFETCH(QVariant, setter); + QFETCH(QVariant, value); + if (QMetaType::Type(value.type()) == QMetaType::Bool) { + (w->*(setter.value()))(value.toBool()); + } else if (QMetaType::Type(value.type()) == QMetaType::QString) { + (w->*(setter.value()))(value.toString()); + } else if (QMetaType::Type(value.type()) == QMetaType::UInt) { + (w->*(setter.value()))(value.toUInt()); + } else if (!value.isValid()) { + (w->*(setter.value()))(); + } + + QVERIFY(changedSpy.wait()); +} + +void PlasmaWindowModelTest::testCreateWindowAfterModelDestroy() +{ + // this test verifies that creating a window after the model got destroyed doesn't crash + auto model = m_pw->createWindowModel(); + QVERIFY(model); + delete model; + QSignalSpy windowCreatedSpy(m_pw, &PlasmaWindowManagement::windowCreated); + QVERIFY(windowCreatedSpy.isValid()); + m_pwInterface->createWindow(m_pwInterface); + QVERIFY(windowCreatedSpy.wait()); +} + QTEST_GUILESS_MAIN(PlasmaWindowModelTest) #include "test_plasma_window_model.moc"