Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/effects/minimize_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/plasmashell.h> | ||||
36 | #include <KWayland/Client/plasmawindowmanagement.h> | ||||
37 | #include <KWayland/Client/surface.h> | ||||
38 | #include <KWayland/Client/xdgshell.h> | ||||
39 | | ||||
40 | using namespace KWin; | ||||
41 | | ||||
42 | static const QString s_socketName = QStringLiteral("wayland_test_effects_minimize_animation-0"); | ||||
43 | | ||||
44 | class MinimizeAnimationTest : public QObject | ||||
45 | { | ||||
46 | Q_OBJECT | ||||
47 | | ||||
48 | private Q_SLOTS: | ||||
49 | void initTestCase(); | ||||
50 | void init(); | ||||
51 | void cleanup(); | ||||
52 | | ||||
53 | void testMinimizeUnminimize_data(); | ||||
54 | void testMinimizeUnminimize(); | ||||
55 | }; | ||||
56 | | ||||
57 | void MinimizeAnimationTest::initTestCase() | ||||
58 | { | ||||
59 | qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8()); | ||||
60 | | ||||
61 | qRegisterMetaType<KWin::AbstractClient *>(); | ||||
62 | qRegisterMetaType<KWin::ShellClient *>(); | ||||
63 | QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); | ||||
64 | QVERIFY(workspaceCreatedSpy.isValid()); | ||||
65 | kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); | ||||
66 | QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); | ||||
67 | | ||||
68 | auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); | ||||
69 | KConfigGroup plugins(config, QStringLiteral("Plugins")); | ||||
70 | ScriptedEffectLoader loader; | ||||
71 | const auto builtinNames = BuiltInEffects::availableEffectNames() << loader.listOfKnownEffects(); | ||||
72 | for (const QString &name : builtinNames) { | ||||
73 | plugins.writeEntry(name + QStringLiteral("Enabled"), false); | ||||
74 | } | ||||
75 | config->sync(); | ||||
76 | kwinApp()->setConfig(config); | ||||
77 | | ||||
78 | qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2")); | ||||
79 | qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1")); | ||||
80 | | ||||
81 | kwinApp()->start(); | ||||
82 | QVERIFY(workspaceCreatedSpy.wait()); | ||||
83 | waylandServer()->initWorkspace(); | ||||
84 | | ||||
85 | auto scene = Compositor::self()->scene(); | ||||
86 | QVERIFY(scene); | ||||
87 | QCOMPARE(scene->compositingType(), OpenGL2Compositing); | ||||
88 | } | ||||
89 | | ||||
90 | void MinimizeAnimationTest::init() | ||||
91 | { | ||||
92 | QVERIFY(Test::setupWaylandConnection( | ||||
93 | Test::AdditionalWaylandInterface::PlasmaShell | | ||||
94 | Test::AdditionalWaylandInterface::WindowManagement | ||||
95 | )); | ||||
96 | } | ||||
97 | | ||||
98 | void MinimizeAnimationTest::cleanup() | ||||
99 | { | ||||
100 | auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects); | ||||
101 | QVERIFY(effectsImpl); | ||||
102 | effectsImpl->unloadAllEffects(); | ||||
103 | QVERIFY(effectsImpl->loadedEffects().isEmpty()); | ||||
104 | | ||||
105 | Test::destroyWaylandConnection(); | ||||
106 | } | ||||
107 | | ||||
108 | void MinimizeAnimationTest::testMinimizeUnminimize_data() | ||||
109 | { | ||||
110 | QTest::addColumn<QString>("effectName"); | ||||
111 | | ||||
112 | QTest::newRow("Magic Lamp") << QStringLiteral("magiclamp"); | ||||
113 | QTest::newRow("Squash") << QStringLiteral("kwin4_effect_squash"); | ||||
114 | } | ||||
115 | | ||||
116 | void MinimizeAnimationTest::testMinimizeUnminimize() | ||||
117 | { | ||||
118 | // This test verifies that a minimize effect tries to animate a client | ||||
119 | // when it's minimized or unminimized. | ||||
120 | | ||||
121 | using namespace KWayland::Client; | ||||
122 | | ||||
123 | QSignalSpy plasmaWindowCreatedSpy(Test::waylandWindowManagement(), &PlasmaWindowManagement::windowCreated); | ||||
124 | QVERIFY(plasmaWindowCreatedSpy.isValid()); | ||||
125 | | ||||
126 | // Create a panel at the top of the screen. | ||||
127 | const QRect panelRect = QRect(0, 0, 1280, 36); | ||||
128 | QScopedPointer<Surface> panelSurface(Test::createSurface()); | ||||
129 | QVERIFY(!panelSurface.isNull()); | ||||
130 | QScopedPointer<XdgShellSurface> panelShellSurface(Test::createXdgShellStableSurface(panelSurface.data())); | ||||
131 | QVERIFY(!panelShellSurface.isNull()); | ||||
132 | QScopedPointer<PlasmaShellSurface> plasmaPanelShellSurface(Test::waylandPlasmaShell()->createSurface(panelSurface.data())); | ||||
133 | QVERIFY(!plasmaPanelShellSurface.isNull()); | ||||
134 | plasmaPanelShellSurface->setRole(PlasmaShellSurface::Role::Panel); | ||||
135 | plasmaPanelShellSurface->setPosition(panelRect.topLeft()); | ||||
136 | plasmaPanelShellSurface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::AlwaysVisible); | ||||
137 | ShellClient *panel = Test::renderAndWaitForShown(panelSurface.data(), panelRect.size(), Qt::blue); | ||||
138 | QVERIFY(panel); | ||||
139 | QVERIFY(panel->isDock()); | ||||
140 | QCOMPARE(panel->geometry(), panelRect); | ||||
141 | QVERIFY(plasmaWindowCreatedSpy.wait()); | ||||
142 | QCOMPARE(plasmaWindowCreatedSpy.count(), 1); | ||||
143 | | ||||
144 | // Create the test client. | ||||
145 | QScopedPointer<Surface> surface(Test::createSurface()); | ||||
146 | QVERIFY(!surface.isNull()); | ||||
147 | QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellStableSurface(surface.data())); | ||||
148 | QVERIFY(!shellSurface.isNull()); | ||||
149 | ShellClient *client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::red); | ||||
150 | QVERIFY(client); | ||||
151 | QVERIFY(plasmaWindowCreatedSpy.wait()); | ||||
152 | QCOMPARE(plasmaWindowCreatedSpy.count(), 2); | ||||
153 | | ||||
154 | // We have to set the minimized geometry because the squash effect needs it, | ||||
155 | // otherwise it won't start animation. | ||||
156 | auto window = plasmaWindowCreatedSpy.last().first().value<PlasmaWindow *>(); | ||||
157 | QVERIFY(window); | ||||
158 | const QRect iconRect = QRect(0, 0, 42, 36); | ||||
159 | window->setMinimizedGeometry(panelSurface.data(), iconRect); | ||||
160 | Test::flushWaylandConnection(); | ||||
161 | QTRY_COMPARE(client->iconGeometry(), iconRect.translated(panel->geometry().topLeft())); | ||||
162 | | ||||
163 | // Load effect that will be tested. | ||||
164 | QFETCH(QString, effectName); | ||||
165 | auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects); | ||||
166 | QVERIFY(effectsImpl); | ||||
167 | QVERIFY(effectsImpl->loadEffect(effectName)); | ||||
168 | QCOMPARE(effectsImpl->loadedEffects().count(), 1); | ||||
169 | QCOMPARE(effectsImpl->loadedEffects().first(), effectName); | ||||
170 | Effect *effect = effectsImpl->findEffect(effectName); | ||||
171 | QVERIFY(effect); | ||||
172 | QVERIFY(!effect->isActive()); | ||||
173 | | ||||
174 | // Start the minimize animation. | ||||
175 | client->minimize(); | ||||
176 | QVERIFY(effect->isActive()); | ||||
177 | | ||||
178 | // Eventually, the animation will be complete. | ||||
179 | QTRY_VERIFY(!effect->isActive()); | ||||
180 | | ||||
181 | // Start the unminimize animation. | ||||
182 | client->unminimize(); | ||||
183 | QVERIFY(effect->isActive()); | ||||
184 | | ||||
185 | // Eventually, the animation will be complete. | ||||
186 | QTRY_VERIFY(!effect->isActive()); | ||||
187 | | ||||
188 | // Destroy the panel. | ||||
189 | panelSurface.reset(); | ||||
190 | QVERIFY(Test::waitForWindowDestroyed(panel)); | ||||
191 | | ||||
192 | // Destroy the test client. | ||||
193 | surface.reset(); | ||||
194 | QVERIFY(Test::waitForWindowDestroyed(client)); | ||||
195 | } | ||||
196 | | ||||
197 | WAYLANDTEST_MAIN(MinimizeAnimationTest) | ||||
198 | #include "minimize_animation_test.moc" |