[client] Add context pointer to connects in PlasmaWindowModel
Summary: When the model gets destroyed the lambda connections were still invoked and could cause crashers. Test Plan: Test case added and each one verified that it crashed Reviewers: #plasma, hein Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D1624
This commit is contained in:
parent
3fda8376b6
commit
32eae0863c
1 changed files with 87 additions and 0 deletions
|
@ -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<ClientWindowSignal>("changedSignal");
|
||||
QTest::addColumn<QVariant>("setter");
|
||||
QTest::addColumn<QVariant>("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<PlasmaWindow*>();
|
||||
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<ServerWindowBoolSetter>()))(value.toBool());
|
||||
} else if (QMetaType::Type(value.type()) == QMetaType::QString) {
|
||||
(w->*(setter.value<ServerWindowStringSetter>()))(value.toString());
|
||||
} else if (QMetaType::Type(value.type()) == QMetaType::UInt) {
|
||||
(w->*(setter.value<ServerWindowQuint32Setter>()))(value.toUInt());
|
||||
} else if (!value.isValid()) {
|
||||
(w->*(setter.value<ServerWindowVoidSetter>()))();
|
||||
}
|
||||
|
||||
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"
|
||||
|
|
Loading…
Reference in a new issue