Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/dont_crash_cancel_animation.cpp
Show All 27 Lines | |||||
28 | #include "screens.h" | 28 | #include "screens.h" | ||
29 | #include "shell_client.h" | 29 | #include "shell_client.h" | ||
30 | #include "wayland_server.h" | 30 | #include "wayland_server.h" | ||
31 | #include "workspace.h" | 31 | #include "workspace.h" | ||
32 | #include "scripting/scriptedeffect.h" | 32 | #include "scripting/scriptedeffect.h" | ||
33 | 33 | | |||
34 | #include <KDecoration2/Decoration> | 34 | #include <KDecoration2/Decoration> | ||
35 | 35 | | |||
36 | #include <KWayland/Client/registry.h> | | |||
37 | #include <KWayland/Client/connection_thread.h> | 36 | #include <KWayland/Client/connection_thread.h> | ||
38 | #include <KWayland/Client/compositor.h> | 37 | #include <KWayland/Client/compositor.h> | ||
39 | #include <KWayland/Client/shm_pool.h> | 38 | #include <KWayland/Client/shm_pool.h> | ||
40 | #include <KWayland/Client/shell.h> | 39 | #include <KWayland/Client/shell.h> | ||
41 | #include <KWayland/Client/surface.h> | 40 | #include <KWayland/Client/surface.h> | ||
42 | #include <KWayland/Client/event_queue.h> | | |||
43 | 41 | | |||
44 | namespace KWin | 42 | namespace KWin | ||
45 | { | 43 | { | ||
46 | 44 | | |||
47 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_cancel_animation-0"); | 45 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_cancel_animation-0"); | ||
48 | 46 | | |||
49 | class DontCrashCancelAnimationFromAnimationEndedTest : public QObject | 47 | class DontCrashCancelAnimationFromAnimationEndedTest : public QObject | ||
50 | { | 48 | { | ||
51 | Q_OBJECT | 49 | Q_OBJECT | ||
52 | private Q_SLOTS: | 50 | private Q_SLOTS: | ||
53 | void initTestCase(); | 51 | void initTestCase(); | ||
54 | void init(); | 52 | void init(); | ||
55 | void cleanup(); | 53 | void cleanup(); | ||
56 | void testScript(); | 54 | void testScript(); | ||
57 | 55 | | |||
58 | private: | 56 | private: | ||
59 | void unlock(); | 57 | void unlock(); | ||
60 | AbstractClient *showWindow(); | 58 | AbstractClient *showWindow(); | ||
61 | KWayland::Client::ConnectionThread *m_connection = nullptr; | | |||
62 | KWayland::Client::Compositor *m_compositor = nullptr; | | |||
63 | KWayland::Client::ShmPool *m_shm = nullptr; | | |||
64 | KWayland::Client::Shell *m_shell = nullptr; | | |||
65 | KWayland::Client::EventQueue *m_queue = nullptr; | | |||
66 | QThread *m_thread = nullptr; | | |||
67 | }; | 59 | }; | ||
68 | 60 | | |||
69 | void DontCrashCancelAnimationFromAnimationEndedTest::initTestCase() | 61 | void DontCrashCancelAnimationFromAnimationEndedTest::initTestCase() | ||
70 | { | 62 | { | ||
71 | qRegisterMetaType<KWin::Deleted*>(); | 63 | qRegisterMetaType<KWin::Deleted*>(); | ||
72 | qRegisterMetaType<KWin::ShellClient*>(); | 64 | qRegisterMetaType<KWin::ShellClient*>(); | ||
73 | qRegisterMetaType<KWin::AbstractClient*>(); | 65 | qRegisterMetaType<KWin::AbstractClient*>(); | ||
74 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | 66 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | ||
75 | waylandServer()->init(s_socketName.toLocal8Bit()); | 67 | waylandServer()->init(s_socketName.toLocal8Bit()); | ||
76 | kwinApp()->start(); | 68 | kwinApp()->start(); | ||
77 | QVERIFY(Compositor::self()); | 69 | QVERIFY(Compositor::self()); | ||
78 | QSignalSpy compositorToggledSpy(Compositor::self(), &Compositor::compositingToggled); | 70 | QSignalSpy compositorToggledSpy(Compositor::self(), &Compositor::compositingToggled); | ||
79 | QVERIFY(compositorToggledSpy.isValid()); | 71 | QVERIFY(compositorToggledSpy.isValid()); | ||
80 | QVERIFY(compositorToggledSpy.wait()); | 72 | QVERIFY(compositorToggledSpy.wait()); | ||
81 | QVERIFY(effects); | 73 | QVERIFY(effects); | ||
82 | } | 74 | } | ||
83 | 75 | | |||
84 | void DontCrashCancelAnimationFromAnimationEndedTest::init() | 76 | void DontCrashCancelAnimationFromAnimationEndedTest::init() | ||
85 | { | 77 | { | ||
86 | using namespace KWayland::Client; | 78 | QVERIFY(Test::setupWaylandConnection(s_socketName)); | ||
87 | // setup connection | | |||
88 | m_connection = new ConnectionThread; | | |||
89 | QSignalSpy connectedSpy(m_connection, &ConnectionThread::connected); | | |||
90 | QVERIFY(connectedSpy.isValid()); | | |||
91 | m_connection->setSocketName(s_socketName); | | |||
92 | | ||||
93 | m_thread = new QThread(this); | | |||
94 | m_connection->moveToThread(m_thread); | | |||
95 | m_thread->start(); | | |||
96 | | ||||
97 | m_connection->initConnection(); | | |||
98 | QVERIFY(connectedSpy.wait()); | | |||
99 | | ||||
100 | m_queue = new EventQueue(this); | | |||
101 | QVERIFY(!m_queue->isValid()); | | |||
102 | m_queue->setup(m_connection); | | |||
103 | QVERIFY(m_queue->isValid()); | | |||
104 | | ||||
105 | Registry registry; | | |||
106 | registry.setEventQueue(m_queue); | | |||
107 | QSignalSpy compositorSpy(®istry, &Registry::compositorAnnounced); | | |||
108 | QSignalSpy shmSpy(®istry, &Registry::shmAnnounced); | | |||
109 | QSignalSpy shellSpy(®istry, &Registry::shellAnnounced); | | |||
110 | QSignalSpy allAnnounced(®istry, &Registry::interfacesAnnounced); | | |||
111 | QVERIFY(allAnnounced.isValid()); | | |||
112 | QVERIFY(shmSpy.isValid()); | | |||
113 | QVERIFY(shellSpy.isValid()); | | |||
114 | QVERIFY(compositorSpy.isValid()); | | |||
115 | registry.create(m_connection->display()); | | |||
116 | QVERIFY(registry.isValid()); | | |||
117 | registry.setup(); | | |||
118 | QVERIFY(allAnnounced.wait()); | | |||
119 | QVERIFY(!compositorSpy.isEmpty()); | | |||
120 | QVERIFY(!shmSpy.isEmpty()); | | |||
121 | QVERIFY(!shellSpy.isEmpty()); | | |||
122 | | ||||
123 | m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this); | | |||
124 | QVERIFY(m_compositor->isValid()); | | |||
125 | m_shm = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this); | | |||
126 | QVERIFY(m_shm->isValid()); | | |||
127 | m_shell = registry.createShell(shellSpy.first().first().value<quint32>(), shellSpy.first().last().value<quint32>(), this); | | |||
128 | QVERIFY(m_shell->isValid()); | | |||
129 | } | 79 | } | ||
130 | 80 | | |||
131 | void DontCrashCancelAnimationFromAnimationEndedTest::cleanup() | 81 | void DontCrashCancelAnimationFromAnimationEndedTest::cleanup() | ||
132 | { | 82 | { | ||
133 | delete m_compositor; | 83 | Test::destroyWaylandConnection(); | ||
134 | m_compositor = nullptr; | | |||
135 | delete m_shm; | | |||
136 | m_shm = nullptr; | | |||
137 | delete m_shell; | | |||
138 | m_shell = nullptr; | | |||
139 | delete m_queue; | | |||
140 | m_queue = nullptr; | | |||
141 | if (m_thread) { | | |||
142 | m_connection->deleteLater(); | | |||
143 | m_thread->quit(); | | |||
144 | m_thread->wait(); | | |||
145 | delete m_thread; | | |||
146 | m_thread = nullptr; | | |||
147 | m_connection = nullptr; | | |||
148 | } | | |||
149 | } | 84 | } | ||
150 | 85 | | |||
151 | void DontCrashCancelAnimationFromAnimationEndedTest::testScript() | 86 | void DontCrashCancelAnimationFromAnimationEndedTest::testScript() | ||
152 | { | 87 | { | ||
153 | // load a scripted effect which deletes animation data | 88 | // load a scripted effect which deletes animation data | ||
154 | ScriptedEffect *effect = ScriptedEffect::create(QStringLiteral("crashy"), QFINDTESTDATA("data/anim-data-delete-effect/effect.js"), 10); | 89 | ScriptedEffect *effect = ScriptedEffect::create(QStringLiteral("crashy"), QFINDTESTDATA("data/anim-data-delete-effect/effect.js"), 10); | ||
155 | QVERIFY(effect); | 90 | QVERIFY(effect); | ||
156 | 91 | | |||
157 | const auto children = effects->children(); | 92 | const auto children = effects->children(); | ||
158 | for (auto it = children.begin(); it != children.end(); ++it) { | 93 | for (auto it = children.begin(); it != children.end(); ++it) { | ||
159 | if (qstrcmp((*it)->metaObject()->className(), "KWin::EffectLoader") != 0) { | 94 | if (qstrcmp((*it)->metaObject()->className(), "KWin::EffectLoader") != 0) { | ||
160 | continue; | 95 | continue; | ||
161 | } | 96 | } | ||
162 | QVERIFY(QMetaObject::invokeMethod(*it, "effectLoaded", Q_ARG(KWin::Effect*, effect), Q_ARG(QString, QStringLiteral("crashy")))); | 97 | QVERIFY(QMetaObject::invokeMethod(*it, "effectLoaded", Q_ARG(KWin::Effect*, effect), Q_ARG(QString, QStringLiteral("crashy")))); | ||
163 | break; | 98 | break; | ||
164 | } | 99 | } | ||
165 | QVERIFY(static_cast<EffectsHandlerImpl*>(effects)->isEffectLoaded(QStringLiteral("crashy"))); | 100 | QVERIFY(static_cast<EffectsHandlerImpl*>(effects)->isEffectLoaded(QStringLiteral("crashy"))); | ||
166 | 101 | | |||
167 | using namespace KWayland::Client; | 102 | using namespace KWayland::Client; | ||
168 | // create a window | 103 | // create a window | ||
169 | QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); | 104 | QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); | ||
170 | QVERIFY(clientAddedSpy.isValid()); | 105 | QVERIFY(clientAddedSpy.isValid()); | ||
171 | 106 | | |||
172 | Surface *surface = m_compositor->createSurface(m_compositor); | 107 | Surface *surface = Test::createSurface(Test::waylandCompositor()); | ||
173 | QVERIFY(surface); | 108 | QVERIFY(surface); | ||
174 | ShellSurface *shellSurface = m_shell->createSurface(surface, surface); | 109 | ShellSurface *shellSurface = Test::createShellSurface(surface, surface); | ||
175 | QVERIFY(shellSurface); | 110 | QVERIFY(shellSurface); | ||
176 | // let's render | 111 | // let's render | ||
177 | QImage img(QSize(100, 50), QImage::Format_ARGB32); | 112 | Test::render(surface, QSize(100, 50), Qt::blue); | ||
178 | img.fill(Qt::blue); | | |||
179 | surface->attachBuffer(m_shm->createBuffer(img)); | | |||
180 | surface->damage(QRect(0, 0, 100, 50)); | | |||
181 | surface->commit(Surface::CommitFlag::None); | | |||
182 | 113 | | |||
183 | m_connection->flush(); | 114 | Test::flushWaylandConnection(); | ||
184 | QVERIFY(clientAddedSpy.wait()); | 115 | QVERIFY(clientAddedSpy.wait()); | ||
185 | AbstractClient *c = workspace()->activeClient(); | 116 | AbstractClient *c = workspace()->activeClient(); | ||
186 | QVERIFY(c); | 117 | QVERIFY(c); | ||
187 | QCOMPARE(clientAddedSpy.first().first().value<ShellClient*>(), c); | 118 | QCOMPARE(clientAddedSpy.first().first().value<ShellClient*>(), c); | ||
188 | 119 | | |||
189 | // make sure we animate | 120 | // make sure we animate | ||
190 | QTest::qWait(200); | 121 | QTest::qWait(200); | ||
191 | 122 | | |||
Show All 15 Lines |