18#include <QAbstractItemModelTester>
23static const QString s_socketName = QStringLiteral(
"wayland_test_kwin_transient_placement-0");
32 void testWindowInteraction();
33 void testAssignedTileDeletion();
34 void resizeTileFromWindow();
37 void createSampleLayout();
44void TilesTest::initTestCase()
46 qRegisterMetaType<KWin::Window *>();
48 QVERIFY(applicationStartedSpy.isValid());
51 QRect(0, 0, 1280, 1024),
52 QRect(1280, 0, 1280, 1024),
56 QVERIFY(applicationStartedSpy.wait());
58 QCOMPARE(outputs.count(), 2);
59 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
60 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
61 setenv(
"QT_QPA_PLATFORM",
"wayland",
true);
72 m_rootTile = m_tileManager->
rootTile();
73 QAbstractItemModelTester(m_tileManager->
model(), QAbstractItemModelTester::FailureReportingMode::QtTest);
75 static_cast<CustomTile *
>(m_rootTile->
childTile(0))->remove();
80void TilesTest::cleanup()
83 static_cast<CustomTile *
>(m_rootTile->
childTile(0))->remove();
88void TilesTest::createSampleLayout()
94 auto leftTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().first());
95 auto rightTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().last());
99 QCOMPARE(leftTile->relativeGeometry(), QRectF(0, 0, 0.5, 1));
100 QCOMPARE(rightTile->relativeGeometry(), QRectF(0.5, 0, 0.5, 1));
104 auto newRightTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().last());
108 QCOMPARE(leftTile->relativeGeometry(), QRectF(0, 0, 0.5, 1));
109 QCOMPARE(rightTile->relativeGeometry(), QRectF(0.5, 0, 0.25, 1));
110 QCOMPARE(newRightTile->relativeGeometry(), QRectF(0.75, 0, 0.25, 1));
113 QCOMPARE(leftTile->windowGeometry(), QRectF(4, 4, 634, 1016));
114 QCOMPARE(rightTile->windowGeometry(), QRectF(642, 4, 316, 1016));
115 QCOMPARE(newRightTile->windowGeometry(), QRectF(962, 4, 314, 1016));
118 QVERIFY(!rightTile->isLayout());
119 QCOMPARE(rightTile->childCount(), 0);
121 QVERIFY(rightTile->isLayout());
122 QCOMPARE(rightTile->childCount(), 2);
123 auto verticalTopTile = qobject_cast<CustomTile *>(rightTile->childTiles().first());
124 auto verticalBottomTile = qobject_cast<CustomTile *>(rightTile->childTiles().last());
128 QCOMPARE(rightTile->relativeGeometry(), QRectF(0.5, 0, 0.25, 1));
129 QCOMPARE(rightTile->windowGeometry(), QRectF(642, 4, 316, 1016));
131 QCOMPARE(verticalTopTile->relativeGeometry(), QRectF(0.5, 0, 0.25, 0.5));
132 QCOMPARE(verticalBottomTile->relativeGeometry(), QRectF(0.5, 0.5, 0.25, 0.5));
133 QCOMPARE(verticalTopTile->windowGeometry(), QRectF(642, 4, 316, 506));
134 QCOMPARE(verticalBottomTile->windowGeometry(), QRectF(642, 514, 316, 506));
137void TilesTest::testWindowInteraction()
150 QVERIFY(surfaceConfigureRequestedSpy.wait());
151 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
152 QCOMPARE(toplevelConfigureRequestedSpy.count(), 1);
154 auto leftTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().first());
158 QVERIFY(surfaceConfigureRequestedSpy.wait());
159 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
160 QCOMPARE(toplevelConfigureRequestedSpy.count(), 2);
162 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
163 Test::render(surface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
164 QVERIFY(frameGeometryChangedSpy.wait());
165 QCOMPARE(
rootWindow->frameGeometry(), leftTile->windowGeometry().toRect());
167 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), leftTile->windowGeometry().toRect().size());
170 leftTile->setRelativeGeometry({0, 0, 0.4, 1});
172 QVERIFY(surfaceConfigureRequestedSpy.wait());
173 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
174 QCOMPARE(toplevelConfigureRequestedSpy.count(), 3);
176 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), leftTile->windowGeometry().toRect().size());
178 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
180 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), leftTile->windowGeometry().toRect().size());
182 Test::render(surface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
183 QVERIFY(frameGeometryChangedSpy.wait());
184 QCOMPARE(
rootWindow->frameGeometry(), leftTile->windowGeometry().toRect());
186 auto middleTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[1]);
188 auto rightTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[2]);
190 auto verticalTopTile = qobject_cast<CustomTile *>(middleTile->childTiles().first());
191 QVERIFY(verticalTopTile);
192 auto verticalBottomTile = qobject_cast<CustomTile *>(middleTile->childTiles().last());
193 QVERIFY(verticalBottomTile);
195 QCOMPARE(leftTile->relativeGeometry(), QRectF(0, 0, 0.4, 1));
196 QCOMPARE(middleTile->relativeGeometry(), QRectF(0.4, 0, 0.35, 1));
197 QCOMPARE(rightTile->relativeGeometry(), QRectF(0.75, 0, 0.25, 1));
198 QCOMPARE(verticalTopTile->relativeGeometry(), QRectF(0.4, 0, 0.35, 0.5));
199 QCOMPARE(verticalBottomTile->relativeGeometry(), QRectF(0.4, 0.5, 0.35, 0.5));
202void TilesTest::testAssignedTileDeletion()
204 auto leftTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().first());
206 leftTile->setRelativeGeometry({0, 0, 0.4, 1});
218 QVERIFY(surfaceConfigureRequestedSpy.wait());
219 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
220 QCOMPARE(toplevelConfigureRequestedSpy.count(), 1);
221 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
223 auto middleTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[1]);
225 auto middleBottomTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[1]->childTiles()[1]);
226 QVERIFY(middleBottomTile);
229 QVERIFY(surfaceConfigureRequestedSpy.wait());
230 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
231 QCOMPARE(toplevelConfigureRequestedSpy.count(), 2);
233 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
235 Test::render(rootSurface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
236 QVERIFY(frameGeometryChangedSpy.wait());
237 QCOMPARE(
rootWindow->frameGeometry(), middleBottomTile->windowGeometry().toRect());
239 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), middleBottomTile->windowGeometry().toRect().size());
241 QCOMPARE(middleBottomTile->windowGeometry().toRect(), QRect(514, 514, 444, 506));
243 middleBottomTile->remove();
245 QVERIFY(surfaceConfigureRequestedSpy.wait());
246 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
247 QCOMPARE(toplevelConfigureRequestedSpy.count(), 3);
249 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
252 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), middleTile->windowGeometry().toRect().size());
254 Test::render(rootSurface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
255 QVERIFY(frameGeometryChangedSpy.wait());
256 QCOMPARE(
rootWindow->frameGeometry(), middleTile->windowGeometry().toRect());
259 QCOMPARE(middleTile->isLayout(),
false);
260 QCOMPARE(middleTile->childCount(), 0);
264void TilesTest::resizeTileFromWindow()
266 auto middleBottomTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[1]->childTiles()[1]);
267 QVERIFY(middleBottomTile);
268 middleBottomTile->remove();
277 Test::XdgToplevel::States states;
281 QVERIFY(frameGeometryChangedSpy.isValid());
282 QVERIFY(surfaceConfigureRequestedSpy.wait());
283 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
284 QCOMPARE(toplevelConfigureRequestedSpy.count(), 1);
285 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
287 auto leftTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles().first());
289 leftTile->setRelativeGeometry({0, 0, 0.4, 1});
290 QCOMPARE(leftTile->windowGeometry(), QRectF(4, 4, 506, 1016));
292 auto middleTile = qobject_cast<CustomTile *>(m_rootTile->
childTiles()[1]);
294 QCOMPARE(middleTile->windowGeometry(), QRectF(514, 4, 444, 1016));
297 auto topLeftTile = qobject_cast<CustomTile *>(leftTile->childTiles().first());
298 QVERIFY(topLeftTile);
299 QCOMPARE(topLeftTile->windowGeometry(), QRectF(4, 4, 506, 506));
301 auto bottomLeftTile = qobject_cast<CustomTile *>(leftTile->childTiles().last());
302 QVERIFY(bottomLeftTile);
303 QCOMPARE(bottomLeftTile->windowGeometry(), QRectF(4, 514, 506, 506));
305 window->setTile(topLeftTile);
306 QVERIFY(surfaceConfigureRequestedSpy.wait());
307 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
308 QCOMPARE(toplevelConfigureRequestedSpy.count(), 2);
310 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
312 QCOMPARE(toplevelConfigureRequestedSpy.last().first().value<QSize>(), topLeftTile->windowGeometry().toRect().size());
313 Test::render(rootSurface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
314 QVERIFY(frameGeometryChangedSpy.wait());
315 QCOMPARE(window->frameGeometry(), QRect(4, 4, 506, 506));
317 QCOMPARE(
workspace()->activeWindow(), window);
319 QVERIFY(interactiveMoveResizeStartedSpy.isValid());
321 QVERIFY(moveResizedChangedSpy.isValid());
323 QVERIFY(interactiveMoveResizeFinishedSpy.isValid());
326 QCOMPARE(
workspace()->moveResizeWindow(),
nullptr);
327 QCOMPARE(window->isInteractiveMove(),
false);
328 QCOMPARE(window->isInteractiveResize(),
false);
330 QCOMPARE(
workspace()->moveResizeWindow(), window);
331 QCOMPARE(interactiveMoveResizeStartedSpy.count(), 1);
332 QCOMPARE(moveResizedChangedSpy.count(), 1);
333 QCOMPARE(window->isInteractiveResize(),
true);
334 QCOMPARE(window->geometryRestore(), QRect());
335 QVERIFY(surfaceConfigureRequestedSpy.wait());
336 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
337 QCOMPARE(toplevelConfigureRequestedSpy.count(), 3);
338 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
342 QPoint cursorPos = window->frameGeometry().bottomRight().toPoint();
344 window->updateInteractiveMoveResize(
Cursors::self()->mouse()->pos());
345 QCOMPARE(
Cursors::self()->mouse()->pos(), cursorPos + QPoint(8, 0));
348 QVERIFY(surfaceConfigureRequestedSpy.wait());
349 QCOMPARE(surfaceConfigureRequestedSpy.count(), 4);
350 QCOMPARE(toplevelConfigureRequestedSpy.count(), 4);
351 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
354 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(516, 508));
357 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
358 Test::render(rootSurface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
359 QVERIFY(frameGeometryChangedSpy.wait());
360 QCOMPARE(window->frameGeometry(), QRect(4, 4, 516, 508));
362 QTRY_COMPARE(tileGeometryChangedSpy.count(), 2);
363 QCOMPARE(window->tile(), topLeftTile);
364 QCOMPARE(topLeftTile->windowGeometry(), QRect(4, 4, 516, 508));
365 QCOMPARE(bottomLeftTile->windowGeometry(), QRect(4, 516, 516, 504));
366 QCOMPARE(leftTile->windowGeometry(), QRect(4, 4, 516, 1016));
367 QCOMPARE(middleTile->windowGeometry(), QRect(524, 4, 434, 1016));
371 QCOMPARE(
workspace()->moveResizeWindow(), window);
372 QCOMPARE(interactiveMoveResizeStartedSpy.count(), 2);
373 QCOMPARE(moveResizedChangedSpy.count(), 3);
374 QCOMPARE(window->isInteractiveResize(),
true);
375 QCOMPARE(window->geometryRestore(), QRect());
376 QVERIFY(surfaceConfigureRequestedSpy.wait());
377 QCOMPARE(surfaceConfigureRequestedSpy.count(), 5);
378 QCOMPARE(toplevelConfigureRequestedSpy.count(), 5);
379 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
384 cursorPos = window->frameGeometry().bottomRight().toPoint();
386 window->updateInteractiveMoveResize(
Cursors::self()->mouse()->pos());
387 QCOMPARE(
Cursors::self()->mouse()->pos(), cursorPos + QPoint(0, 8));
390 QVERIFY(surfaceConfigureRequestedSpy.wait());
391 QCOMPARE(surfaceConfigureRequestedSpy.count(), 6);
392 QCOMPARE(toplevelConfigureRequestedSpy.count(), 6);
393 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
396 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(518, 518));
399 root->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
400 Test::render(rootSurface.get(), toplevelConfigureRequestedSpy.last().first().value<QSize>(), Qt::blue);
401 QVERIFY(frameGeometryChangedSpy.wait());
402 QCOMPARE(window->frameGeometry(), QRect(4, 4, 518, 518));
404 QTRY_COMPARE(tileGeometryChangedSpy.count(), 5);
405 QCOMPARE(window->tile(), topLeftTile);
406 QCOMPARE(topLeftTile->windowGeometry(), QRect(4, 4, 518, 518));
407 QCOMPARE(bottomLeftTile->windowGeometry(), QRect(4, 526, 518, 494));
408 QCOMPARE(leftTile->windowGeometry(), QRect(4, 4, 518, 1016));
409 QCOMPARE(middleTile->windowGeometry(), QRect(526, 4, 432, 1016));
414#include "tiles_test.moc"
Q_INVOKABLE void split(KWin::Tile::LayoutDirection newDirection)
void configureRequested(quint32 serial)
void configureRequested(const QSize &size, KWin::Test::XdgToplevel::States states)
Tile * childTile(int row)
QList< Tile * > childTiles() const
QRectF windowGeometry() const
void windowGeometryChanged()
void interactiveMoveResizeStarted()
void interactiveMoveResizeFinished()
void moveResizedChanged()
void frameGeometryChanged(const QRectF &oldGeometry)
TileManager * tileManager(Output *output)
Output * activeOutput() const
QList< Output * > outputs() const
void setActiveOutput(Output *output)
#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)
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
KWIN_EXPORT xcb_window_t rootWindow()
WaylandServer * waylandServer()
InputRedirection * input()