KWin
Loading...
Searching...
No Matches
maximize_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
12#include "compositor.h"
14#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
22using namespace KWin;
23
24static const QString s_socketName = QStringLiteral("wayland_test_effects_maximize_animation-0");
25
26class MaximizeAnimationTest : public QObject
27{
28 Q_OBJECT
29
30private Q_SLOTS:
31 void initTestCase();
32 void init();
33 void cleanup();
34
35 void testMaximizeRestore();
36};
37
38void MaximizeAnimationTest::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 MaximizeAnimationTest::init()
71{
73}
74
75void MaximizeAnimationTest::cleanup()
76{
77 QVERIFY(effects);
79 QVERIFY(effects->loadedEffects().isEmpty());
80
82}
83
84void MaximizeAnimationTest::testMaximizeRestore()
85{
86 // This test verifies that the maximize effect animates a window
87 // when it's maximized or restored.
88
89 // Create the test window.
90 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
91 QVERIFY(surface != nullptr);
92
93 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
94
95 // Wait for the initial configure event.
96 Test::XdgToplevel::States states;
97 QSignalSpy toplevelConfigureRequestedSpy(shellSurface.get(), &Test::XdgToplevel::configureRequested);
98 QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
99
100 surface->commit(KWayland::Client::Surface::CommitFlag::None);
101
102 QVERIFY(surfaceConfigureRequestedSpy.wait());
103 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
104 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).value<QSize>(), QSize(0, 0));
105 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
106 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Activated));
107 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
108
109 // Draw contents of the surface.
110 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
111 Window *window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
112 QVERIFY(window);
113 QVERIFY(window->isActive());
114 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
115
116 // We should receive a configure event when the window becomes active.
117 QVERIFY(surfaceConfigureRequestedSpy.wait());
118 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
119 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
120 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
121 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
122
123 // Load effect that will be tested.
124 const QString effectName = QStringLiteral("maximize");
125 QVERIFY(effects);
126 QVERIFY(effects->loadEffect(effectName));
127 QCOMPARE(effects->loadedEffects().count(), 1);
128 QCOMPARE(effects->loadedEffects().first(), effectName);
129 Effect *effect = effects->findEffect(effectName);
130 QVERIFY(effect);
131 QVERIFY(!effect->isActive());
132
133 // Maximize the window.
134 QSignalSpy frameGeometryChangedSpy(window, &Window::frameGeometryChanged);
135 QSignalSpy maximizeChangedSpy(window, &Window::maximizedChanged);
136
138 QVERIFY(surfaceConfigureRequestedSpy.wait());
139 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
140 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).value<QSize>(), QSize(1280, 1024));
141 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
142 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
143 QVERIFY(states.testFlag(Test::XdgToplevel::State::Maximized));
144
145 // Draw contents of the maximized window.
146 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
147 Test::render(surface.get(), QSize(1280, 1024), Qt::red);
148 QVERIFY(frameGeometryChangedSpy.wait());
149 QCOMPARE(frameGeometryChangedSpy.count(), 1);
150 QCOMPARE(maximizeChangedSpy.count(), 1);
151 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeFull);
152 QVERIFY(effect->isActive());
153
154 // Eventually, the animation will be complete.
155 QTRY_VERIFY(!effect->isActive());
156
157 // Restore the window.
159 QVERIFY(surfaceConfigureRequestedSpy.wait());
160 QCOMPARE(surfaceConfigureRequestedSpy.count(), 4);
161 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).value<QSize>(), QSize(100, 50));
162 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
163 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
164 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
165
166 // Draw contents of the restored window.
167 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
168 Test::render(surface.get(), QSize(100, 50), Qt::blue);
169 QVERIFY(frameGeometryChangedSpy.wait());
170 QCOMPARE(frameGeometryChangedSpy.count(), 2);
171 QCOMPARE(maximizeChangedSpy.count(), 2);
172 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
173 QVERIFY(effect->isActive());
174
175 // Eventually, the animation will be complete.
176 QTRY_VERIFY(!effect->isActive());
177
178 // Destroy the test window.
179 surface.reset();
180 QVERIFY(Test::waitForWindowClosed(window));
181}
182
184#include "maximize_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)
void configureRequested(const QSize &size, KWin::Test::XdgToplevel::States states)
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())
void render(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32_Premultiplied)
bool renderNodeAvailable()
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
bool waitForWindowClosed(Window *window)
WaylandServer * waylandServer()
Workspace * workspace()
Definition workspace.h:830
EffectsHandler * effects