diff --git a/src/wayland/test_wayland_surface.cpp b/src/wayland/test_wayland_surface.cpp
index 0c59895641..1b480895f4 100644
--- a/src/wayland/test_wayland_surface.cpp
+++ b/src/wayland/test_wayland_surface.cpp
@@ -24,6 +24,9 @@ along with this program. If not, see .
#include "../../wayland_client/connection_thread.h"
#include "../../wayland_client/surface.h"
#include "../../wayland_client/registry.h"
+#include "../../wayland_server/compositor_interface.h"
+#include "../../wayland_server/display.h"
+#include "../../wayland_server/surface_interface.h"
// Wayland
#include
@@ -37,86 +40,109 @@ private Q_SLOTS:
void cleanup();
void testStaticAccessor();
+ void testDamage();
+ void testFrameCallback();
private:
- QProcess *m_westonProcess;
+ KWin::WaylandServer::Display *m_display;
+ KWin::WaylandServer::CompositorInterface *m_compositorInterface;
+ KWin::Wayland::ConnectionThread *m_connection;
+ KWin::Wayland::Compositor *m_compositor;
+ QThread *m_thread;
};
static const QString s_socketName = QStringLiteral("kwin-test-wayland-surface-0");
TestWaylandSurface::TestWaylandSurface(QObject *parent)
: QObject(parent)
- , m_westonProcess(nullptr)
+ , m_display(nullptr)
+ , m_compositorInterface(nullptr)
+ , m_connection(nullptr)
+ , m_compositor(nullptr)
+ , m_thread(nullptr)
{
}
void TestWaylandSurface::init()
{
- QVERIFY(!m_westonProcess);
- // starts weston
- m_westonProcess = new QProcess(this);
- m_westonProcess->setProgram(QStringLiteral("weston"));
+ using namespace KWin::WaylandServer;
+ delete m_display;
+ m_display = new Display(this);
+ m_display->setSocketName(s_socketName);
+ m_display->start();
+ QVERIFY(m_display->isRunning());
- m_westonProcess->setArguments(QStringList({QStringLiteral("--socket=%1").arg(s_socketName),
- QStringLiteral("--use-pixman")}));
- m_westonProcess->start();
- QVERIFY(m_westonProcess->waitForStarted());
+ m_compositorInterface = m_display->createCompositor(m_display);
+ QVERIFY(m_compositorInterface);
+ m_compositorInterface->create();
+ QVERIFY(m_compositorInterface->isValid());
- // wait for the socket to appear
- QDir runtimeDir(qgetenv("XDG_RUNTIME_DIR"));
- if (runtimeDir.exists(s_socketName)) {
- return;
- }
- QFileSystemWatcher *socketWatcher = new QFileSystemWatcher(QStringList({runtimeDir.absolutePath()}), this);
- QSignalSpy socketSpy(socketWatcher, SIGNAL(directoryChanged(QString)));
+ // setup connection
+ m_connection = new KWin::Wayland::ConnectionThread;
+ QSignalSpy connectedSpy(m_connection, SIGNAL(connected()));
+ m_connection->setSocketName(s_socketName);
- // limit to maximum of 10 waits
- for (int i = 0; i < 10; ++i) {
- QVERIFY(socketSpy.wait());
- if (runtimeDir.exists(s_socketName)) {
- delete socketWatcher;
- return;
+ m_thread = new QThread(this);
+ m_connection->moveToThread(m_thread);
+ m_thread->start();
+
+ connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, m_connection,
+ [this]() {
+ if (m_connection->display()) {
+ wl_display_flush(m_connection->display());
+ }
}
- }
-}
+ );
-void TestWaylandSurface::cleanup()
-{
- // terminates weston
- m_westonProcess->terminate();
- QVERIFY(m_westonProcess->waitForFinished());
- delete m_westonProcess;
- m_westonProcess = nullptr;
-}
-
-void TestWaylandSurface::testStaticAccessor()
-{
- if (m_westonProcess->state() != QProcess::Running) {
- QSKIP("This test requires a running wayland server");
- }
- KWin::Wayland::ConnectionThread connection;
- QSignalSpy connectedSpy(&connection, SIGNAL(connected()));
- connection.setSocketName(s_socketName);
- connection.initConnection();
+ m_connection->initConnection();
QVERIFY(connectedSpy.wait());
KWin::Wayland::Registry registry;
QSignalSpy compositorSpy(®istry, SIGNAL(compositorAnnounced(quint32,quint32)));
- registry.create(connection.display());
+ registry.create(m_connection->display());
QVERIFY(registry.isValid());
registry.setup();
- wl_display_flush(connection.display());
QVERIFY(compositorSpy.wait());
- KWin::Wayland::Compositor compositor;
- compositor.setup(registry.bindCompositor(compositorSpy.first().first().value(), compositorSpy.first().last().value()));
- QVERIFY(compositor.isValid());
+ m_compositor = new KWin::Wayland::Compositor(this);
+ m_compositor->setup(registry.bindCompositor(compositorSpy.first().first().value(), compositorSpy.first().last().value()));
+ QVERIFY(m_compositor->isValid());
+}
+
+void TestWaylandSurface::cleanup()
+{
+ if (m_compositor) {
+ delete m_compositor;
+ m_compositor = nullptr;
+ }
+ if (m_thread) {
+ m_thread->quit();
+ m_thread->wait();
+ delete m_thread;
+ m_thread = nullptr;
+ }
+ delete m_connection;
+ m_connection = nullptr;
+
+ delete m_compositorInterface;
+ m_compositorInterface = nullptr;
+
+ delete m_display;
+ m_display = nullptr;
+}
+
+void TestWaylandSurface::testStaticAccessor()
+{
+ QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWin::WaylandServer::SurfaceInterface*)));
+ QVERIFY(serverSurfaceCreated.isValid());
QVERIFY(KWin::Wayland::Surface::all().isEmpty());
- KWin::Wayland::Surface *s1 = compositor.createSurface();
+ KWin::Wayland::Surface *s1 = m_compositor->createSurface();
+ QVERIFY(s1->isValid());
QCOMPARE(KWin::Wayland::Surface::all().count(), 1);
QCOMPARE(KWin::Wayland::Surface::all().first(), s1);
QCOMPARE(KWin::Wayland::Surface::get(*s1), s1);
+ QVERIFY(serverSurfaceCreated.wait());
QVERIFY(!s1->size().isValid());
QSignalSpy sizeChangedSpy(s1, SIGNAL(sizeChanged(QSize)));
@@ -128,12 +154,15 @@ void TestWaylandSurface::testStaticAccessor()
QCOMPARE(sizeChangedSpy.first().first().toSize(), testSize);
// add another surface
- KWin::Wayland::Surface *s2 = compositor.createSurface();
+ KWin::Wayland::Surface *s2 = m_compositor->createSurface();
+ QVERIFY(s2->isValid());
QCOMPARE(KWin::Wayland::Surface::all().count(), 2);
QCOMPARE(KWin::Wayland::Surface::all().first(), s1);
QCOMPARE(KWin::Wayland::Surface::all().last(), s2);
QCOMPARE(KWin::Wayland::Surface::get(*s1), s1);
QCOMPARE(KWin::Wayland::Surface::get(*s2), s2);
+ serverSurfaceCreated.clear();
+ QVERIFY(serverSurfaceCreated.wait());
// delete s2 again
delete s2;
@@ -147,5 +176,59 @@ void TestWaylandSurface::testStaticAccessor()
QVERIFY(!KWin::Wayland::Surface::get(nullptr));
}
+void TestWaylandSurface::testDamage()
+{
+ QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWin::WaylandServer::SurfaceInterface*)));
+ QVERIFY(serverSurfaceCreated.isValid());
+ KWin::Wayland::Surface *s = m_compositor->createSurface();
+ QVERIFY(serverSurfaceCreated.wait());
+ KWin::WaylandServer::SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value();
+ QVERIFY(serverSurface);
+ QCOMPARE(serverSurface->damage(), QRegion());
+
+ QSignalSpy damageSpy(serverSurface, SIGNAL(damaged(QRegion)));
+ QVERIFY(damageSpy.isValid());
+
+ // TODO: actually we would need to attach a buffer first
+ s->damage(QRect(0, 0, 10, 10));
+ s->commit(KWin::Wayland::Surface::CommitFlag::None);
+ QVERIFY(damageSpy.wait());
+ QCOMPARE(serverSurface->damage(), QRegion(0, 0, 10, 10));
+ QCOMPARE(damageSpy.first().first().value(), QRegion(0, 0, 10, 10));
+
+ // damage multiple times
+ QRegion testRegion(5, 8, 3, 6);
+ testRegion = testRegion.united(QRect(10, 20, 30, 15));
+ s->damage(testRegion);
+ damageSpy.clear();
+ s->commit(KWin::Wayland::Surface::CommitFlag::None);
+ QVERIFY(damageSpy.wait());
+ QCOMPARE(serverSurface->damage(), testRegion);
+ QCOMPARE(damageSpy.first().first().value(), testRegion);
+}
+
+void TestWaylandSurface::testFrameCallback()
+{
+ QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWin::WaylandServer::SurfaceInterface*)));
+ QVERIFY(serverSurfaceCreated.isValid());
+ KWin::Wayland::Surface *s = m_compositor->createSurface();
+ QVERIFY(serverSurfaceCreated.wait());
+ KWin::WaylandServer::SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value();
+ QVERIFY(serverSurface);
+
+ QSignalSpy damageSpy(serverSurface, SIGNAL(damaged(QRegion)));
+ QVERIFY(damageSpy.isValid());
+
+ QSignalSpy frameRenderedSpy(s, SIGNAL(frameRendered()));
+ QVERIFY(frameRenderedSpy.isValid());
+ s->damage(QRect(0, 0, 10, 10));
+ s->commit();
+ QVERIFY(damageSpy.wait());
+ serverSurface->frameRendered(10);
+ QVERIFY(frameRenderedSpy.isEmpty());
+ QVERIFY(frameRenderedSpy.wait());
+ QVERIFY(!frameRenderedSpy.isEmpty());
+}
+
QTEST_MAIN(TestWaylandSurface)
#include "test_wayland_surface.moc"