16#include <KConfigGroup>
18#include <KWayland/Client/connection_thread.h>
19#include <KWayland/Client/registry.h>
20#include <KWayland/Client/slide.h>
21#include <KWayland/Client/surface.h>
24#include <xcb/xcb_icccm.h>
27static const QString s_socketName = QStringLiteral(
"wayland_test_effects_slidingpopups-0");
37 void testWithOtherEffect_data();
38 void testWithOtherEffect();
39 void testWithOtherEffectWayland_data();
40 void testWithOtherEffectWayland();
43void SlidingPopupsTest::initTestCase()
46 QSKIP(
"no render node available");
49 qputenv(
"XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8());
50 qRegisterMetaType<KWin::Window *>();
51 qRegisterMetaType<KWin::Effect *>();
55 QRect(0, 0, 1280, 1024),
56 QRect(1280, 0, 1280, 1024),
60 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
61 KConfigGroup plugins(config, QStringLiteral(
"Plugins"));
63 for (QString name : builtinNames) {
64 plugins.writeEntry(name + QStringLiteral(
"Enabled"),
false);
66 KConfigGroup wobblyGroup = config->group(QStringLiteral(
"Effect-Wobbly"));
67 wobblyGroup.writeEntry(QStringLiteral(
"Settings"), QStringLiteral(
"Custom"));
68 wobblyGroup.writeEntry(QStringLiteral(
"OpenEffect"),
true);
69 wobblyGroup.writeEntry(QStringLiteral(
"CloseEffect"),
true);
72 kwinApp()->setConfig(config);
74 qputenv(
"KWIN_COMPOSE", QByteArrayLiteral(
"O2"));
75 qputenv(
"KWIN_EFFECTS_FORCE_ANIMATIONS",
"1");
77 QVERIFY(applicationStartedSpy.wait());
80void SlidingPopupsTest::init()
85void SlidingPopupsTest::cleanup()
95void SlidingPopupsTest::testWithOtherEffect_data()
97 QTest::addColumn<QStringList>(
"effectsToLoad");
99 QTest::newRow(
"fade, slide") << QStringList{QStringLiteral(
"fade"), QStringLiteral(
"slidingpopups")};
100 QTest::newRow(
"slide, fade") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"fade")};
101 QTest::newRow(
"scale, slide") << QStringList{QStringLiteral(
"scale"), QStringLiteral(
"slidingpopups")};
102 QTest::newRow(
"slide, scale") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"scale")};
105 QTest::newRow(
"glide, slide") << QStringList{QStringLiteral(
"glide"), QStringLiteral(
"slidingpopups")};
106 QTest::newRow(
"slide, glide") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"glide")};
107 QTest::newRow(
"wobblywindows, slide") << QStringList{QStringLiteral(
"wobblywindows"), QStringLiteral(
"slidingpopups")};
108 QTest::newRow(
"slide, wobblywindows") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"wobblywindows")};
109 QTest::newRow(
"fallapart, slide") << QStringList{QStringLiteral(
"fallapart"), QStringLiteral(
"slidingpopups")};
110 QTest::newRow(
"slide, fallapart") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"fallapart")};
114void SlidingPopupsTest::testWithOtherEffect()
121 QVERIFY(effectloader);
124 Effect *slidingPoupus =
nullptr;
125 Effect *otherEffect =
nullptr;
126 QFETCH(QStringList, effectsToLoad);
127 for (
const QString &effectName : effectsToLoad) {
132 QCOMPARE(effectLoadedSpy.count(), 1);
133 Effect *effect = effectLoadedSpy.first().first().value<
Effect *>();
134 if (effectName == QStringLiteral(
"slidingpopups")) {
135 slidingPoupus = effect;
137 otherEffect = effect;
139 effectLoadedSpy.clear();
141 QVERIFY(slidingPoupus);
142 QVERIFY(otherEffect);
144 QVERIFY(!slidingPoupus->
isActive());
151 QVERIFY(!xcb_connection_has_error(c.get()));
152 const QRect windowGeometry(0, 0, 100, 200);
153 xcb_window_t windowId = xcb_generate_id(c.get());
154 xcb_create_window(c.get(), XCB_COPY_FROM_PARENT, windowId,
rootWindow(),
157 windowGeometry.width(),
158 windowGeometry.height(),
159 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0,
nullptr);
160 xcb_size_hints_t hints;
161 memset(&hints, 0,
sizeof(hints));
162 xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y());
163 xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height());
164 xcb_icccm_set_wm_normal_hints(c.get(), windowId, &hints);
165 NETWinInfo winInfo(c.get(), windowId,
rootWindow(), NET::Properties(), NET::Properties2());
166 winInfo.setWindowType(NET::Normal);
169 const QByteArray effectAtomName = QByteArrayLiteral(
"_KDE_SLIDE");
170 xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c.get(),
false, effectAtomName.length(), effectAtomName.constData());
176 QVERIFY(atom !=
nullptr);
177 xcb_change_property(c.get(), XCB_PROP_MODE_REPLACE, windowId, atom->atom, atom->atom, 32, size, data);
179 xcb_map_window(c.get(), windowId);
184 QVERIFY(windowCreatedSpy.wait());
187 QCOMPARE(window->
window(), windowId);
191 QCOMPARE(windowAddedSpy.count(), 1);
192 QTRY_VERIFY(slidingPoupus->
isActive());
196 QTRY_VERIFY(!slidingPoupus->
isActive());
197 QTRY_VERIFY(!otherEffect->
isActive());
200 xcb_unmap_window(c.get(), windowId);
203 QSignalSpy closedSpy(window, &X11Window::closed);
206 QVERIFY(closedSpy.wait());
212 QVERIFY(windowDeletedSpy.wait());
214 QCOMPARE(windowDeletedSpy.count(), 1);
215 QVERIFY(!slidingPoupus->
isActive());
217 xcb_destroy_window(c.get(), windowId);
221void SlidingPopupsTest::testWithOtherEffectWayland_data()
223 QTest::addColumn<QStringList>(
"effectsToLoad");
225 QTest::newRow(
"fade, slide") << QStringList{QStringLiteral(
"fade"), QStringLiteral(
"slidingpopups")};
226 QTest::newRow(
"slide, fade") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"fade")};
227 QTest::newRow(
"scale, slide") << QStringList{QStringLiteral(
"scale"), QStringLiteral(
"slidingpopups")};
228 QTest::newRow(
"slide, scale") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"scale")};
231 QTest::newRow(
"glide, slide") << QStringList{QStringLiteral(
"glide"), QStringLiteral(
"slidingpopups")};
232 QTest::newRow(
"slide, glide") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"glide")};
233 QTest::newRow(
"wobblywindows, slide") << QStringList{QStringLiteral(
"wobblywindows"), QStringLiteral(
"slidingpopups")};
234 QTest::newRow(
"slide, wobblywindows") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"wobblywindows")};
235 QTest::newRow(
"fallapart, slide") << QStringList{QStringLiteral(
"fallapart"), QStringLiteral(
"slidingpopups")};
236 QTest::newRow(
"slide, fallapart") << QStringList{QStringLiteral(
"slidingpopups"), QStringLiteral(
"fallapart")};
240void SlidingPopupsTest::testWithOtherEffectWayland()
248 QVERIFY(effectloader);
251 Effect *slidingPoupus =
nullptr;
252 Effect *otherEffect =
nullptr;
253 QFETCH(QStringList, effectsToLoad);
254 for (
const QString &effectName : effectsToLoad) {
259 QCOMPARE(effectLoadedSpy.count(), 1);
260 Effect *effect = effectLoadedSpy.first().first().value<
Effect *>();
261 if (effectName == QStringLiteral(
"slidingpopups")) {
262 slidingPoupus = effect;
264 otherEffect = effect;
266 effectLoadedSpy.clear();
268 QVERIFY(slidingPoupus);
269 QVERIFY(otherEffect);
271 QVERIFY(!slidingPoupus->
isActive());
276 std::unique_ptr<KWayland::Client::Registry>
registry(
new KWayland::Client::Registry);
279 QSignalSpy interfacesAnnouncedSpy(
registry.get(), &KWayland::Client::Registry::interfacesAnnounced);
281 QVERIFY(interfacesAnnouncedSpy.wait());
282 auto slideInterface =
registry->interface(KWayland::Client::Registry::Interface::Slide);
283 QVERIFY(slideInterface.name != 0);
284 std::unique_ptr<KWayland::Client::SlideManager> slideManager(
registry->createSlideManager(slideInterface.name, slideInterface.version));
285 QVERIFY(slideManager);
290 std::unique_ptr<KWayland::Client::Slide> slide(slideManager->createSlide(surface.get()));
291 slide->setLocation(KWayland::Client::Slide::Location::Left);
294 QVERIFY(shellSurface);
295 QCOMPARE(windowAddedSpy.count(), 0);
301 QCOMPARE(windowAddedSpy.count(), 1);
302 QTRY_VERIFY(slidingPoupus->
isActive());
306 QTRY_VERIFY(!slidingPoupus->
isActive());
307 QTRY_VERIFY(!otherEffect->
isActive());
310 shellSurface.reset();
313 QSignalSpy windowClosedSpy(window, &X11Window::closed);
316 QVERIFY(windowClosedSpy.wait());
322 QVERIFY(windowDeletedSpy.wait());
324 QCOMPARE(windowDeletedSpy.count(), 1);
325 QVERIFY(!slidingPoupus->
isActive());
330#include "slidingpopups_test.moc"
Interface to describe how an effect loader has to function.
void effectLoaded(KWin::Effect *effect, const QString &name)
The loader emits this signal when it successfully loaded an effect.
Base class for all KWin effects.
QStringList listOfKnownEffects() const override
All the Effects this loader knows of.
Q_SCRIPTABLE void unloadEffect(const QString &name)
void windowDeleted(KWin::EffectWindow *w)
QStringList loadedEffects
Q_SCRIPTABLE bool loadEffect(const QString &name)
CompositingType compositingType
Q_SCRIPTABLE bool isEffectLoaded(const QString &name) const
void windowAdded(KWin::EffectWindow *w)
bool isNormalWindow() const
void windowAdded(KWin::Window *)
xcb_window_t window() const
virtual bool isActive() const
#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::Registry * registry
XcbConnectionPtr createX11Connection()
bool renderNodeAvailable()
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
KWayland::Client::ConnectionThread * waylandConnection()
std::unique_ptr< xcb_connection_t, XcbConnectionDeleter > XcbConnectionPtr
KWIN_EXPORT xcb_window_t rootWindow()
WaylandServer * waylandServer()
std::unique_ptr< T, CDeleter > UniqueCPtr