Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/effects/maximize_animation_test.cpp
- This file was added.
1 | /******************************************************************** | ||||
---|---|---|---|---|---|
2 | KWin - the KDE window manager | ||||
3 | This file is part of the KDE project. | ||||
4 | | ||||
5 | Copyright (C) 2019 Vlad Zagorodniy <vladzzag@gmail.com> | ||||
6 | | ||||
7 | This program is free software; you can redistribute it and/or modify | ||||
8 | it under the terms of the GNU General Public License as published by | ||||
9 | the Free Software Foundation; either version 2 of the License, or | ||||
10 | (at your option) any later version. | ||||
11 | | ||||
12 | This program is distributed in the hope that it will be useful, | ||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
15 | GNU General Public License for more details. | ||||
16 | | ||||
17 | You should have received a copy of the GNU General Public License | ||||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | *********************************************************************/ | ||||
20 | | ||||
21 | #include "kwin_wayland_test.h" | ||||
22 | | ||||
23 | #include "abstract_client.h" | ||||
24 | #include "composite.h" | ||||
25 | #include "effectloader.h" | ||||
26 | #include "effects.h" | ||||
27 | #include "platform.h" | ||||
28 | #include "scene.h" | ||||
29 | #include "shell_client.h" | ||||
30 | #include "wayland_server.h" | ||||
31 | #include "workspace.h" | ||||
32 | | ||||
33 | #include "effect_builtins.h" | ||||
34 | | ||||
35 | #include <KWayland/Client/surface.h> | ||||
36 | #include <KWayland/Client/xdgshell.h> | ||||
37 | | ||||
38 | using namespace KWin; | ||||
39 | | ||||
40 | static const QString s_socketName = QStringLiteral("wayland_test_effects_maximize_animation-0"); | ||||
41 | | ||||
42 | class MaximizeAnimationTest : public QObject | ||||
43 | { | ||||
44 | Q_OBJECT | ||||
45 | | ||||
46 | private Q_SLOTS: | ||||
47 | void initTestCase(); | ||||
48 | void init(); | ||||
49 | void cleanup(); | ||||
50 | | ||||
51 | void testMaximizeRestore_data(); | ||||
52 | void testMaximizeRestore(); | ||||
53 | }; | ||||
54 | | ||||
55 | void MaximizeAnimationTest::initTestCase() | ||||
56 | { | ||||
57 | qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8()); | ||||
58 | | ||||
59 | qRegisterMetaType<KWin::AbstractClient *>(); | ||||
60 | qRegisterMetaType<KWin::ShellClient *>(); | ||||
61 | QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); | ||||
62 | QVERIFY(workspaceCreatedSpy.isValid()); | ||||
63 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | ||||
64 | QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); | ||||
65 | | ||||
66 | auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); | ||||
67 | KConfigGroup plugins(config, QStringLiteral("Plugins")); | ||||
68 | ScriptedEffectLoader loader; | ||||
69 | const auto builtinNames = BuiltInEffects::availableEffectNames() << loader.listOfKnownEffects(); | ||||
70 | for (const QString &name : builtinNames) { | ||||
71 | plugins.writeEntry(name + QStringLiteral("Enabled"), false); | ||||
72 | } | ||||
73 | config->sync(); | ||||
74 | kwinApp()->setConfig(config); | ||||
75 | | ||||
76 | qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1")); | ||||
77 | | ||||
78 | kwinApp()->start(); | ||||
79 | QVERIFY(workspaceCreatedSpy.wait()); | ||||
80 | waylandServer()->initWorkspace(); | ||||
81 | } | ||||
82 | | ||||
83 | void MaximizeAnimationTest::init() | ||||
84 | { | ||||
85 | QVERIFY(Test::setupWaylandConnection()); | ||||
86 | } | ||||
87 | | ||||
88 | void MaximizeAnimationTest::cleanup() | ||||
89 | { | ||||
90 | auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects); | ||||
91 | QVERIFY(effectsImpl); | ||||
92 | effectsImpl->unloadAllEffects(); | ||||
93 | QVERIFY(effectsImpl->loadedEffects().isEmpty()); | ||||
94 | | ||||
95 | Test::destroyWaylandConnection(); | ||||
96 | } | ||||
97 | | ||||
98 | void MaximizeAnimationTest::testMaximizeRestore_data() | ||||
99 | { | ||||
100 | QTest::addColumn<Test::ShellSurfaceType>("type"); | ||||
101 | | ||||
102 | QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5; | ||||
103 | QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6; | ||||
104 | QTest::newRow("xdgWmBase") << Test::ShellSurfaceType::XdgShellStable; | ||||
105 | } | ||||
106 | | ||||
107 | void MaximizeAnimationTest::testMaximizeRestore() | ||||
108 | { | ||||
109 | // This test verifies that the maximize effect animates a client | ||||
110 | // when it's maximized or restored. | ||||
111 | | ||||
112 | using namespace KWayland::Client; | ||||
113 | | ||||
114 | // Create the test client. | ||||
115 | QScopedPointer<Surface> surface(Test::createSurface()); | ||||
116 | QVERIFY(!surface.isNull()); | ||||
117 | | ||||
118 | QFETCH(Test::ShellSurfaceType, type); | ||||
119 | QScopedPointer<XdgShellSurface> shellSurface(qobject_cast<XdgShellSurface *>( | ||||
120 | Test::createShellSurface(type, surface.data()))); | ||||
121 | | ||||
122 | // Wait for the initial configure event. | ||||
123 | XdgShellSurface::States states; | ||||
124 | QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested); | ||||
125 | QVERIFY(configureRequestedSpy.isValid()); | ||||
126 | QVERIFY(configureRequestedSpy.wait()); | ||||
127 | QCOMPARE(configureRequestedSpy.count(), 1); | ||||
128 | QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), QSize(0, 0)); | ||||
129 | states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>(); | ||||
130 | QVERIFY(!states.testFlag(XdgShellSurface::State::Activated)); | ||||
131 | QVERIFY(!states.testFlag(XdgShellSurface::State::Maximized)); | ||||
132 | | ||||
133 | // Draw contents of the surface. | ||||
134 | shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>()); | ||||
135 | ShellClient *client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); | ||||
136 | QVERIFY(client); | ||||
137 | QVERIFY(client->isActive()); | ||||
138 | QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeRestore); | ||||
139 | | ||||
140 | // We should receive a configure event when the client becomes active. | ||||
141 | QVERIFY(configureRequestedSpy.wait()); | ||||
142 | QCOMPARE(configureRequestedSpy.count(), 2); | ||||
143 | states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>(); | ||||
144 | QVERIFY(states.testFlag(XdgShellSurface::State::Activated)); | ||||
145 | QVERIFY(!states.testFlag(XdgShellSurface::State::Maximized)); | ||||
146 | | ||||
147 | // Load effect that will be tested. | ||||
148 | const QString effectName = QStringLiteral("kwin4_effect_maximize"); | ||||
149 | auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects); | ||||
150 | QVERIFY(effectsImpl); | ||||
151 | QVERIFY(effectsImpl->loadEffect(effectName)); | ||||
152 | QCOMPARE(effectsImpl->loadedEffects().count(), 1); | ||||
153 | QCOMPARE(effectsImpl->loadedEffects().first(), effectName); | ||||
154 | Effect *effect = effectsImpl->findEffect(effectName); | ||||
155 | QVERIFY(effect); | ||||
156 | QVERIFY(!effect->isActive()); | ||||
157 | | ||||
158 | // Maximize the client. | ||||
159 | QSignalSpy geometryChangedSpy(client, &ShellClient::geometryChanged); | ||||
160 | QVERIFY(geometryChangedSpy.isValid()); | ||||
161 | QSignalSpy maximizeChangedSpy(client, qOverload<AbstractClient *, bool, bool>(&ShellClient::clientMaximizedStateChanged)); | ||||
162 | QVERIFY(maximizeChangedSpy.isValid()); | ||||
163 | | ||||
164 | workspace()->slotWindowMaximize(); | ||||
165 | QVERIFY(configureRequestedSpy.wait()); | ||||
166 | QCOMPARE(configureRequestedSpy.count(), 3); | ||||
167 | QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), QSize(1280, 1024)); | ||||
168 | states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>(); | ||||
169 | QVERIFY(states.testFlag(XdgShellSurface::State::Activated)); | ||||
170 | QVERIFY(states.testFlag(XdgShellSurface::State::Maximized)); | ||||
171 | | ||||
172 | // Draw contents of the maximized client. | ||||
173 | shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>()); | ||||
174 | Test::render(surface.data(), QSize(1280, 1024), Qt::red); | ||||
175 | QVERIFY(geometryChangedSpy.wait()); | ||||
176 | QCOMPARE(geometryChangedSpy.count(), 2); | ||||
177 | QCOMPARE(maximizeChangedSpy.count(), 1); | ||||
178 | QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeFull); | ||||
179 | QVERIFY(effect->isActive()); | ||||
180 | | ||||
181 | // Eventually, the animation will be complete. | ||||
182 | QTRY_VERIFY(!effect->isActive()); | ||||
183 | | ||||
184 | // Restore the client. | ||||
185 | workspace()->slotWindowMaximize(); | ||||
186 | QVERIFY(configureRequestedSpy.wait()); | ||||
187 | QCOMPARE(configureRequestedSpy.count(), 4); | ||||
188 | QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), QSize(100, 50)); | ||||
189 | states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>(); | ||||
190 | QVERIFY(states.testFlag(XdgShellSurface::State::Activated)); | ||||
191 | QVERIFY(!states.testFlag(XdgShellSurface::State::Maximized)); | ||||
192 | | ||||
193 | // Draw contents of the restored client. | ||||
194 | shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>()); | ||||
195 | Test::render(surface.data(), QSize(100, 50), Qt::blue); | ||||
196 | QVERIFY(geometryChangedSpy.wait()); | ||||
197 | QCOMPARE(geometryChangedSpy.count(), 4); | ||||
198 | QCOMPARE(maximizeChangedSpy.count(), 2); | ||||
199 | QCOMPARE(client->maximizeMode(), MaximizeMode::MaximizeRestore); | ||||
200 | QVERIFY(effect->isActive()); | ||||
201 | | ||||
202 | // Eventually, the animation will be complete. | ||||
203 | QTRY_VERIFY(!effect->isActive()); | ||||
204 | | ||||
205 | // Destroy the test client. | ||||
206 | surface.reset(); | ||||
207 | QVERIFY(Test::waitForWindowDestroyed(client)); | ||||
208 | } | ||||
209 | | ||||
210 | WAYLANDTEST_MAIN(MaximizeAnimationTest) | ||||
211 | #include "maximize_animation_test.moc" |