KWin
Loading...
Searching...
No Matches
toplevel_open_close_animation_test.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
13#include "effect/effectloader.h"
14#include "wayland_server.h"
15#include "window.h"
16#include "workspace.h"
17
18#include <KWayland/Client/surface.h>
19
20using namespace KWin;
21
22static const QString s_socketName = QStringLiteral("wayland_test_effects_toplevel_open_close_animation-0");
23
24class ToplevelOpenCloseAnimationTest : public QObject
25{
26 Q_OBJECT
27
28private Q_SLOTS:
29 void initTestCase();
30 void init();
31 void cleanup();
32
33 void testAnimateToplevels_data();
34 void testAnimateToplevels();
35 void testDontAnimatePopups_data();
36 void testDontAnimatePopups();
37};
38
39void ToplevelOpenCloseAnimationTest::initTestCase()
40{
42 QSKIP("no render node available");
43 return;
44 }
45 qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8());
46
47 qRegisterMetaType<KWin::Window *>();
48 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
49 QVERIFY(waylandServer()->init(s_socketName));
51 QRect(0, 0, 1280, 1024),
52 QRect(1280, 0, 1280, 1024),
53 });
54
55 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
56 KConfigGroup plugins(config, QStringLiteral("Plugins"));
57 const auto builtinNames = EffectLoader().listOfKnownEffects();
58 for (const QString &name : builtinNames) {
59 plugins.writeEntry(name + QStringLiteral("Enabled"), false);
60 }
61 config->sync();
62 kwinApp()->setConfig(config);
63
64 qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
65 qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1"));
66
67 kwinApp()->start();
68 QVERIFY(applicationStartedSpy.wait());
69}
70
71void ToplevelOpenCloseAnimationTest::init()
72{
74}
75
76void ToplevelOpenCloseAnimationTest::cleanup()
77{
79 QVERIFY(effects->loadedEffects().isEmpty());
80
82}
83
84void ToplevelOpenCloseAnimationTest::testAnimateToplevels_data()
85{
86 QTest::addColumn<QString>("effectName");
87
88 QTest::newRow("Fade") << QStringLiteral("fade");
89 QTest::newRow("Glide") << QStringLiteral("glide");
90 QTest::newRow("Scale") << QStringLiteral("scale");
91}
92
93void ToplevelOpenCloseAnimationTest::testAnimateToplevels()
94{
95 // This test verifies that window open/close animation effects try to
96 // animate the appearing and the disappearing of toplevel windows.
97
98 // Load effect that will be tested.
99 QFETCH(QString, effectName);
100 QVERIFY(effects->loadEffect(effectName));
101 QCOMPARE(effects->loadedEffects().count(), 1);
102 QCOMPARE(effects->loadedEffects().first(), effectName);
103 Effect *effect = effects->findEffect(effectName);
104 QVERIFY(effect);
105 QVERIFY(!effect->isActive());
106
107 // Create the test window.
108 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
109 QVERIFY(surface != nullptr);
110 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
111 QVERIFY(shellSurface != nullptr);
112 Window *window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
113 QVERIFY(window);
114 QVERIFY(effect->isActive());
115
116 // Eventually, the animation will be complete.
117 QTRY_VERIFY(!effect->isActive());
118
119 // Close the test window, the effect should start animating the disappearing
120 // of the window.
121 QSignalSpy windowClosedSpy(window, &Window::closed);
122 shellSurface.reset();
123 surface.reset();
124 QVERIFY(windowClosedSpy.wait());
125 QVERIFY(effect->isActive());
126
127 // Eventually, the animation will be complete.
128 QTRY_VERIFY(!effect->isActive());
129}
130
131void ToplevelOpenCloseAnimationTest::testDontAnimatePopups_data()
132{
133 QTest::addColumn<QString>("effectName");
134
135 QTest::newRow("Fade") << QStringLiteral("fade");
136 QTest::newRow("Glide") << QStringLiteral("glide");
137 QTest::newRow("Scale") << QStringLiteral("scale");
138}
139
140void ToplevelOpenCloseAnimationTest::testDontAnimatePopups()
141{
142 // This test verifies that window open/close animation effects don't try
143 // to animate popups(e.g. popup menus, tooltips, etc).
144
145 // Create the main window.
146 std::unique_ptr<KWayland::Client::Surface> mainWindowSurface(Test::createSurface());
147 QVERIFY(mainWindowSurface != nullptr);
148 std::unique_ptr<Test::XdgToplevel> mainWindowShellSurface(Test::createXdgToplevelSurface(mainWindowSurface.get()));
149 QVERIFY(mainWindowShellSurface != nullptr);
150 Window *mainWindow = Test::renderAndWaitForShown(mainWindowSurface.get(), QSize(100, 50), Qt::blue);
151 QVERIFY(mainWindow);
152
153 // Load effect that will be tested.
154 QFETCH(QString, effectName);
155 QVERIFY(effects->loadEffect(effectName));
156 QCOMPARE(effects->loadedEffects().count(), 1);
157 QCOMPARE(effects->loadedEffects().first(), effectName);
158 Effect *effect = effects->findEffect(effectName);
159 QVERIFY(effect);
160 QVERIFY(!effect->isActive());
161
162 // Create a popup, it should not be animated.
163 std::unique_ptr<KWayland::Client::Surface> popupSurface(Test::createSurface());
164 QVERIFY(popupSurface != nullptr);
165 std::unique_ptr<Test::XdgPositioner> positioner(Test::createXdgPositioner());
166 QVERIFY(positioner);
167 positioner->set_size(20, 20);
168 positioner->set_anchor_rect(0, 0, 10, 10);
169 positioner->set_gravity(Test::XdgPositioner::gravity_bottom_right);
170 positioner->set_anchor(Test::XdgPositioner::anchor_bottom_left);
171 std::unique_ptr<Test::XdgPopup> popupShellSurface(Test::createXdgPopupSurface(popupSurface.get(), mainWindowShellSurface->xdgSurface(), positioner.get()));
172 QVERIFY(popupShellSurface != nullptr);
173 Window *popup = Test::renderAndWaitForShown(popupSurface.get(), QSize(20, 20), Qt::red);
174 QVERIFY(popup);
175 QVERIFY(popup->isPopupWindow());
176 QCOMPARE(popup->transientFor(), mainWindow);
177 QVERIFY(!effect->isActive());
178
179 // Destroy the popup, it should not be animated.
180 QSignalSpy popupClosedSpy(popup, &Window::closed);
181 popupShellSurface.reset();
182 popupSurface.reset();
183 QVERIFY(popupClosedSpy.wait());
184 QVERIFY(!effect->isActive());
185
186 // Destroy the main window.
187 mainWindowSurface.reset();
188 QVERIFY(Test::waitForWindowClosed(mainWindow));
189}
190
192#include "toplevel_open_close_animation_test.moc"
Base class for all KWin effects.
Definition effect.h:535
QStringList listOfKnownEffects() const override
All the Effects this loader knows of.
QStringList loadedEffects
Q_SCRIPTABLE bool loadEffect(const QString &name)
Effect * findEffect(const QString &name) const
virtual bool isActive() const
Definition effect.cpp:447
#define WAYLANDTEST_MAIN(TestObject)
XdgPositioner * createXdgPositioner()
Window * renderAndWaitForShown(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32, int timeout=5000)
XdgPopup * createXdgPopupSurface(KWayland::Client::Surface *surface, XdgSurface *parentSurface, XdgPositioner *positioner, CreationSetup configureMode=CreationSetup::CreateAndConfigure, QObject *parent=nullptr)
void destroyWaylandConnection()
void setOutputConfig(const QList< QRect > &geometries)
bool setupWaylandConnection(AdditionalWaylandInterfaces flags=AdditionalWaylandInterfaces())
bool renderNodeAvailable()
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
bool waitForWindowClosed(Window *window)
WaylandServer * waylandServer()
EffectsHandler * effects