KWin
Loading...
Searching...
No Matches
minimize_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: 2019 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/plasmawindowmanagement.h>
19#include <KWayland/Client/surface.h>
20
21using namespace KWin;
22
23static const QString s_socketName = QStringLiteral("wayland_test_effects_minimize_animation-0");
24
25class MinimizeAnimationTest : public QObject
26{
27 Q_OBJECT
28
29private Q_SLOTS:
30 void initTestCase();
31 void init();
32 void cleanup();
33
34 void testMinimizeUnminimize_data();
35 void testMinimizeUnminimize();
36};
37
38void MinimizeAnimationTest::initTestCase()
39{
41 QSKIP("no render node available");
42 return;
43 }
44 qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8());
45
46 qRegisterMetaType<KWin::Window *>();
47 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
48 QVERIFY(waylandServer()->init(s_socketName));
50 QRect(0, 0, 1280, 1024),
51 QRect(1280, 0, 1280, 1024),
52 });
53
54 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
55 KConfigGroup plugins(config, QStringLiteral("Plugins"));
56 const auto builtinNames = EffectLoader().listOfKnownEffects();
57 for (const QString &name : builtinNames) {
58 plugins.writeEntry(name + QStringLiteral("Enabled"), false);
59 }
60 config->sync();
61 kwinApp()->setConfig(config);
62
63 qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
64 qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1"));
65
66 kwinApp()->start();
67 QVERIFY(applicationStartedSpy.wait());
68}
69
70void MinimizeAnimationTest::init()
71{
72 QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1 | Test::AdditionalWaylandInterface::WindowManagement));
73}
74
75void MinimizeAnimationTest::cleanup()
76{
77 QVERIFY(effects);
79 QVERIFY(effects->loadedEffects().isEmpty());
80
82}
83
84void MinimizeAnimationTest::testMinimizeUnminimize_data()
85{
86 QTest::addColumn<QString>("effectName");
87
88 QTest::newRow("Magic Lamp") << QStringLiteral("magiclamp");
89 QTest::newRow("Squash") << QStringLiteral("squash");
90}
91
92void MinimizeAnimationTest::testMinimizeUnminimize()
93{
94 // This test verifies that a minimize effect tries to animate a window
95 // when it's minimized or unminimized.
96
97
98 // Create a panel at the top of the screen.
99 const QRect panelRect = QRect(0, 0, 1280, 36);
100 std::unique_ptr<KWayland::Client::Surface> panelSurface{Test::createSurface()};
101 std::unique_ptr<Test::LayerSurfaceV1> panelShellSurface{Test::createLayerSurfaceV1(panelSurface.get(), QStringLiteral("dock"))};
102 panelShellSurface->set_size(panelRect.width(), panelRect.height());
103 panelShellSurface->set_exclusive_zone(panelRect.height());
104 panelShellSurface->set_anchor(Test::LayerSurfaceV1::anchor_top);
105 panelSurface->commit(KWayland::Client::Surface::CommitFlag::None);
106
107 QSignalSpy panelConfigureRequestedSpy(panelShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
108 QVERIFY(panelConfigureRequestedSpy.wait());
109 Window *panel = Test::renderAndWaitForShown(panelSurface.get(), panelConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
110 QVERIFY(panel);
111 QVERIFY(panel->isDock());
112 QCOMPARE(panel->frameGeometry(), panelRect);
113
114 // Create the test window.
115 QSignalSpy plasmaWindowCreatedSpy(Test::waylandWindowManagement(), &KWayland::Client::PlasmaWindowManagement::windowCreated);
116 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
117 QVERIFY(surface != nullptr);
118 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
119 QVERIFY(shellSurface != nullptr);
120 Window *window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::red);
121 QVERIFY(window);
122 QVERIFY(plasmaWindowCreatedSpy.wait());
123 QCOMPARE(plasmaWindowCreatedSpy.count(), 1);
124
125 // We have to set the minimized geometry because the squash effect needs it,
126 // otherwise it won't start animation.
127 auto plasmaWindow = plasmaWindowCreatedSpy.last().first().value<KWayland::Client::PlasmaWindow *>();
128 QVERIFY(plasmaWindow);
129 const QRect iconRect = QRect(0, 0, 42, 36);
130 plasmaWindow->setMinimizedGeometry(panelSurface.get(), iconRect);
132 QTRY_COMPARE(window->iconGeometry(), iconRect.translated(panel->frameGeometry().topLeft().toPoint()));
133
134 // Load effect that will be tested.
135 QFETCH(QString, effectName);
136 QVERIFY(effects);
137 QVERIFY(effects->loadEffect(effectName));
138 QCOMPARE(effects->loadedEffects().count(), 1);
139 QCOMPARE(effects->loadedEffects().first(), effectName);
140 Effect *effect = effects->findEffect(effectName);
141 QVERIFY(effect);
142 QVERIFY(!effect->isActive());
143
144 // Start the minimize animation.
145 window->setMinimized(true);
146 QVERIFY(effect->isActive());
147
148 // Eventually, the animation will be complete.
149 QTRY_VERIFY(!effect->isActive());
150
151 // Start the unminimize animation.
152 window->setMinimized(false);
153 QVERIFY(effect->isActive());
154
155 // Eventually, the animation will be complete.
156 QTRY_VERIFY(!effect->isActive());
157
158 // Destroy the panel.
159 panelSurface.reset();
160 QVERIFY(Test::waitForWindowClosed(panel));
161
162 // Destroy the test window.
163 surface.reset();
164 QVERIFY(Test::waitForWindowClosed(window));
165}
166
168#include "minimize_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
void configureRequested(quint32 serial, const QSize &size)
virtual bool isActive() const
Definition effect.cpp:447
#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())
KWayland::Client::PlasmaWindowManagement * waylandWindowManagement()
LayerSurfaceV1 * createLayerSurfaceV1(KWayland::Client::Surface *surface, const QString &scope, KWayland::Client::Output *output=nullptr, LayerShellV1::layer layer=LayerShellV1::layer_top)
bool renderNodeAvailable()
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
void flushWaylandConnection()
bool waitForWindowClosed(Window *window)
WaylandServer * waylandServer()
EffectsHandler * effects