KWin
Loading...
Searching...
No Matches
dont_crash_reinitialize_compositor.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#include "kwin_wayland_test.h"
11
12#include "compositor.h"
13#include "core/output.h"
15#include "effect/effectloader.h"
16#include "wayland_server.h"
17#include "window.h"
18#include "workspace.h"
19
20#include <KWayland/Client/surface.h>
21
22namespace KWin
23{
24
25static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_reinitialize_compositor-0");
26
28{
29 Q_OBJECT
30
31private Q_SLOTS:
32 void initTestCase();
33 void init();
34 void cleanup();
35
36 void testReinitializeCompositor_data();
37 void testReinitializeCompositor();
38};
39
40void DontCrashReinitializeCompositorTest::initTestCase()
41{
43 QSKIP("no render node available");
44 return;
45 }
46 qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8());
47
48 qRegisterMetaType<KWin::Window *>();
49 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
50 QVERIFY(waylandServer()->init(s_socketName));
52 QRect(0, 0, 1280, 1024),
53 QRect(1280, 0, 1280, 1024),
54 });
55
56 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
57 KConfigGroup plugins(config, QStringLiteral("Plugins"));
58 const auto builtinNames = EffectLoader().listOfKnownEffects();
59 for (const QString &name : builtinNames) {
60 plugins.writeEntry(name + QStringLiteral("Enabled"), false);
61 }
62 config->sync();
63 kwinApp()->setConfig(config);
64
65 qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
66 qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1"));
67
68 kwinApp()->start();
69 QVERIFY(applicationStartedSpy.wait());
70 const auto outputs = workspace()->outputs();
71 QCOMPARE(outputs.count(), 2);
72 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
73 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
74}
75
76void DontCrashReinitializeCompositorTest::init()
77{
79}
80
81void DontCrashReinitializeCompositorTest::cleanup()
82{
83 // Unload all effects.
85 QVERIFY(effects->loadedEffects().isEmpty());
86
88}
89
90void DontCrashReinitializeCompositorTest::testReinitializeCompositor_data()
91{
92 QTest::addColumn<QString>("effectName");
93
94 QTest::newRow("Fade") << QStringLiteral("fade");
95 QTest::newRow("Glide") << QStringLiteral("glide");
96 QTest::newRow("Scale") << QStringLiteral("scale");
97}
98
99void DontCrashReinitializeCompositorTest::testReinitializeCompositor()
100{
101 // This test verifies that KWin doesn't crash when the compositor settings
102 // have been changed while a scripted effect animates the disappearing of
103 // a window.
104
105 // Create the test window.
106 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
107 QVERIFY(surface != nullptr);
108 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
109 QVERIFY(shellSurface != nullptr);
110 Window *window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
111 QVERIFY(window);
112
113 // Make sure that only the test effect is loaded.
114 QFETCH(QString, effectName);
115 QVERIFY(effects->loadEffect(effectName));
116 QCOMPARE(effects->loadedEffects().count(), 1);
117 QCOMPARE(effects->loadedEffects().first(), effectName);
118 Effect *effect = effects->findEffect(effectName);
119 QVERIFY(effect);
120 QVERIFY(!effect->isActive());
121
122 // Close the test window.
123 QSignalSpy windowClosedSpy(window, &Window::closed);
124 shellSurface.reset();
125 surface.reset();
126 QVERIFY(windowClosedSpy.wait());
127
128 // The test effect should start animating the test window. Is there a better
129 // way to verify that the test effect actually animates the test window?
130 QVERIFY(effect->isActive());
131
132 // Re-initialize the compositor, effects will be destroyed and created again.
134
135 // By this time, KWin should still be alive.
136}
137
138} // namespace KWin
139
141#include "dont_crash_reinitialize_compositor.moc"
virtual void reinitialize()
static Compositor * self()
QStringList loadedEffects
Q_SCRIPTABLE bool loadEffect(const QString &name)
Effect * findEffect(const QString &name) const
QList< Output * > outputs() const
Definition workspace.h:762
#define WAYLANDTEST_MAIN(TestObject)
Window * renderAndWaitForShown(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32, int timeout=5000)
void destroyWaylandConnection()
void setOutputConfig(const QList< QRect > &geometries)
bool setupWaylandConnection(AdditionalWaylandInterfaces flags=AdditionalWaylandInterfaces())
QList< KWayland::Client::Output * > outputs
bool renderNodeAvailable()
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
WaylandServer * waylandServer()
Workspace * workspace()
Definition workspace.h:830
EffectsHandler * effects