diff options
Diffstat (limited to 'tests/auto/compositor/compositor')
-rw-r--r-- | tests/auto/compositor/compositor/compositor.pro | 10 | ||||
-rw-r--r-- | tests/auto/compositor/compositor/mockclient.cpp | 25 | ||||
-rw-r--r-- | tests/auto/compositor/compositor/mockclient.h | 8 | ||||
-rw-r--r-- | tests/auto/compositor/compositor/mockxdgoutputv1.cpp | 68 | ||||
-rw-r--r-- | tests/auto/compositor/compositor/mockxdgoutputv1.h | 64 | ||||
-rw-r--r-- | tests/auto/compositor/compositor/tst_compositor.cpp | 204 |
6 files changed, 357 insertions, 22 deletions
diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro index 500a92c61..270016597 100644 --- a/tests/auto/compositor/compositor/compositor.pro +++ b/tests/auto/compositor/compositor/compositor.pro @@ -14,7 +14,9 @@ WAYLANDCLIENTSOURCES += \ ../../../../src/3rdparty/protocol/ivi-application.xml \ ../../../../src/3rdparty/protocol/wayland.xml \ ../../../../src/3rdparty/protocol/xdg-shell.xml \ - ../../../../src/3rdparty/protocol/viewporter.xml + ../../../../src/3rdparty/protocol/viewporter.xml \ + ../../../../src/3rdparty/protocol/idle-inhibit-unstable-v1.xml \ + ../../../../src/3rdparty/protocol/xdg-output-unstable-v1.xml SOURCES += \ tst_compositor.cpp \ @@ -24,7 +26,8 @@ SOURCES += \ mockseat.cpp \ testseat.cpp \ mockkeyboard.cpp \ - mockpointer.cpp + mockpointer.cpp \ + mockxdgoutputv1.cpp HEADERS += \ testcompositor.h \ @@ -33,4 +36,5 @@ HEADERS += \ mockseat.h \ testseat.h \ mockkeyboard.h \ - mockpointer.h + mockpointer.h \ + mockxdgoutputv1.h diff --git a/tests/auto/compositor/compositor/mockclient.cpp b/tests/auto/compositor/compositor/mockclient.cpp index fa4d4c6b3..27d1eed89 100644 --- a/tests/auto/compositor/compositor/mockclient.cpp +++ b/tests/auto/compositor/compositor/mockclient.cpp @@ -184,11 +184,19 @@ void MockClient::handleGlobal(uint32_t id, const QByteArray &interface) } else if (interface == "wl_seat") { wl_seat *s = static_cast<wl_seat *>(wl_registry_bind(registry, id, &wl_seat_interface, 1)); m_seats << new MockSeat(s); + } else if (interface == "zwp_idle_inhibit_manager_v1") { + idleInhibitManager = static_cast<zwp_idle_inhibit_manager_v1 *>(wl_registry_bind(registry, id, &zwp_idle_inhibit_manager_v1_interface, 1)); + } else if (interface == "zxdg_output_manager_v1") { + xdgOutputManager = new QtWayland::zxdg_output_manager_v1(registry, id, 2); } } void MockClient::handleGlobalRemove(uint32_t id) { + auto *output = m_outputs[id]; + if (m_xdgOutputs.contains(output)) + delete m_xdgOutputs.take(output); + m_outputs.remove(id); } @@ -222,6 +230,23 @@ ivi_surface *MockClient::createIviSurface(wl_surface *surface, uint iviId) return ivi_application_surface_create(iviApplication, iviId, surface); } +zwp_idle_inhibitor_v1 *MockClient::createIdleInhibitor(wl_surface *surface) +{ + flushDisplay(); + + auto *idleInhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor( + idleInhibitManager, surface); + zwp_idle_inhibitor_v1_set_user_data(idleInhibitor, this); + return idleInhibitor; +} + +MockXdgOutputV1 *MockClient::createXdgOutput(wl_output *output) +{ + auto *xdgOutput = new MockXdgOutputV1(xdgOutputManager->get_xdg_output(output)); + m_xdgOutputs[output] = xdgOutput; + return xdgOutput; +} + ShmBuffer::ShmBuffer(const QSize &size, wl_shm *shm) { int stride = size.width() * 4; diff --git a/tests/auto/compositor/compositor/mockclient.h b/tests/auto/compositor/compositor/mockclient.h index 31424cf79..89d0a0b3f 100644 --- a/tests/auto/compositor/compositor/mockclient.h +++ b/tests/auto/compositor/compositor/mockclient.h @@ -30,6 +30,7 @@ #include <qwayland-xdg-shell.h> #include <wayland-ivi-application-client-protocol.h> #include "wayland-viewporter-client-protocol.h" +#include "wayland-idle-inhibit-unstable-v1-client-protocol.h" #include <QObject> #include <QImage> @@ -38,6 +39,8 @@ #include <QtCore/QMap> #include <QWaylandOutputMode> +#include "mockxdgoutputv1.h" + class MockSeat; class ShmBuffer @@ -64,16 +67,21 @@ public: xdg_surface *createXdgSurface(wl_surface *surface); xdg_toplevel *createXdgToplevel(xdg_surface *xdgSurface); ivi_surface *createIviSurface(wl_surface *surface, uint iviId); + zwp_idle_inhibitor_v1 *createIdleInhibitor(wl_surface *surface); + MockXdgOutputV1 *createXdgOutput(wl_output *output); wl_display *display = nullptr; wl_compositor *compositor = nullptr; QMap<uint, wl_output *> m_outputs; + QMap<wl_output *, MockXdgOutputV1 *> m_xdgOutputs; wl_shm *shm = nullptr; wl_registry *registry = nullptr; wl_shell *wlshell = nullptr; xdg_wm_base *xdgWmBase = nullptr; wp_viewporter *viewporter = nullptr; ivi_application *iviApplication = nullptr; + zwp_idle_inhibit_manager_v1 *idleInhibitManager = nullptr; + QtWayland::zxdg_output_manager_v1 *xdgOutputManager = nullptr; QList<MockSeat *> m_seats; diff --git a/tests/auto/compositor/compositor/mockxdgoutputv1.cpp b/tests/auto/compositor/compositor/mockxdgoutputv1.cpp new file mode 100644 index 000000000..eebc55bbb --- /dev/null +++ b/tests/auto/compositor/compositor/mockxdgoutputv1.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockxdgoutputv1.h" + +MockXdgOutputV1::MockXdgOutputV1(struct ::zxdg_output_v1 *object) + : QtWayland::zxdg_output_v1(object) +{ +} + +MockXdgOutputV1::~MockXdgOutputV1() +{ + destroy(); +} + +void MockXdgOutputV1::zxdg_output_v1_logical_position(int32_t x, int32_t y) +{ + pending.logicalPosition = QPoint(x, y); +} + +void MockXdgOutputV1::zxdg_output_v1_logical_size(int32_t width, int32_t height) +{ + pending.logicalSize = QSize(width, height); +} + +void MockXdgOutputV1::zxdg_output_v1_done() +{ + // In version 3 we'll have to do this for wl_output.done as well + name = pending.name; + description = pending.description; + logicalPosition = pending.logicalPosition; + logicalSize = pending.logicalSize; +} + +void MockXdgOutputV1::zxdg_output_v1_name(const QString &name) +{ + pending.name = name; +} + +void MockXdgOutputV1::zxdg_output_v1_description(const QString &description) +{ + pending.description = description; +} diff --git a/tests/auto/compositor/compositor/mockxdgoutputv1.h b/tests/auto/compositor/compositor/mockxdgoutputv1.h new file mode 100644 index 000000000..db5820698 --- /dev/null +++ b/tests/auto/compositor/compositor/mockxdgoutputv1.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKXDGOUTPUTV1_H +#define MOCKXDGOUTPUTV1_H + +#include <QPoint> +#include <QSize> +#include <QString> + +#include "qwayland-xdg-output-unstable-v1.h" + +class MockXdgOutputV1 : public QtWayland::zxdg_output_v1 +{ +public: + explicit MockXdgOutputV1(struct ::zxdg_output_v1 *object); + ~MockXdgOutputV1(); + + QString name; + QString description; + QPoint logicalPosition; + QSize logicalSize; + + struct { + QString name; + QString description; + QPoint logicalPosition; + QSize logicalSize; + } pending; + +protected: + void zxdg_output_v1_logical_position(int32_t x, int32_t y) override; + void zxdg_output_v1_logical_size(int32_t width, int32_t height) override; + void zxdg_output_v1_done() override; + void zxdg_output_v1_name(const QString &name) override; + void zxdg_output_v1_description(const QString &description) override; +}; + +#endif // MOCKXDGOUTPUTV1_H diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index c286aae70..e87fab2a8 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -29,6 +29,7 @@ #include "mockclient.h" #include "mockseat.h" #include "mockpointer.h" +#include "mockxdgoutputv1.h" #include "testcompositor.h" #include "testkeyboardgrabber.h" #include "testseat.h" @@ -47,8 +48,12 @@ #include <QtWaylandCompositor/QWaylandResource> #include <QtWaylandCompositor/QWaylandKeymap> #include <QtWaylandCompositor/QWaylandViewporter> +#include <QtWaylandCompositor/QWaylandIdleInhibitManagerV1> +#include <QtWaylandCompositor/QWaylandXdgOutputManagerV1> #include <qwayland-xdg-shell.h> #include <qwayland-ivi-application.h> +#include <QtWaylandCompositor/private/qwaylandoutput_p.h> +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> #include <QtTest/QtTest> @@ -73,12 +78,14 @@ private slots: void singleClient(); void multipleClients(); void geometry(); + void availableGeometry(); void modes(); void comparingModes(); void sizeFollowsWindow(); void mapSurface(); void mapSurfaceHiDpi(); void frameCallback(); + void pixelFormats(); void outputs(); void customSurface(); @@ -111,6 +118,10 @@ private slots: void viewportSourceNoSurfaceError(); void viewportHiDpi(); + void idleInhibit(); + + void xdgOutput(); + private: QTemporaryDir m_tmpRuntimeDir; }; @@ -372,6 +383,22 @@ void tst_WaylandCompositor::geometry() QTRY_COMPARE(client.refreshRate, 60000); } +void tst_WaylandCompositor::availableGeometry() +{ + TestCompositor compositor; + compositor.create(); + + QWaylandOutputMode mode(QSize(1024, 768), 60000); + compositor.defaultOutput()->addMode(mode, true); + compositor.defaultOutput()->setCurrentMode(mode); + + MockClient client; + + QRect availableGeometry(50, 100, 850, 600); + compositor.defaultOutput()->setAvailableGeometry(availableGeometry); + QCOMPARE(compositor.defaultOutput()->availableGeometry(), availableGeometry); +} + void tst_WaylandCompositor::modes() { TestCompositor compositor; @@ -518,8 +545,13 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() QObject::connect(waylandSurface, &QWaylandSurface::hasContentChanged, verifyComittedState); QSignalSpy hasContentSpy(waylandSurface, SIGNAL(hasContentChanged())); +#if QT_DEPRECATED_SINCE(5, 13) QObject::connect(waylandSurface, &QWaylandSurface::sizeChanged, verifyComittedState); QSignalSpy sizeSpy(waylandSurface, SIGNAL(sizeChanged())); +#endif + + QObject::connect(waylandSurface, &QWaylandSurface::bufferSizeChanged, verifyComittedState); + QSignalSpy bufferSizeSpy(waylandSurface, SIGNAL(bufferSizeChanged())); QObject::connect(waylandSurface, &QWaylandSurface::destinationSizeChanged, verifyComittedState); QSignalSpy destinationSizeSpy(waylandSurface, SIGNAL(destinationSizeChanged())); @@ -543,7 +575,10 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() wl_surface_commit(surface); QTRY_COMPARE(hasContentSpy.count(), 1); +#if QT_DEPRECATED_SINCE(5, 13) QTRY_COMPARE(sizeSpy.count(), 1); +#endif + QTRY_COMPARE(bufferSizeSpy.count(), 1); QTRY_COMPARE(destinationSizeSpy.count(), 1); QTRY_COMPARE(bufferScaleSpy.count(), 1); QTRY_COMPARE(offsetSpy.count(), 1); @@ -566,27 +601,27 @@ static void registerFrameCallback(wl_surface *surface, int *counter) wl_callback_add_listener(wl_surface_frame(surface), &frameCallbackListener, counter); } -void tst_WaylandCompositor::frameCallback() +class BufferView : public QWaylandView { - class BufferView : public QWaylandView +public: + void bufferCommitted(const QWaylandBufferRef &ref, const QRegion &damage) override { - public: - void bufferCommitted(const QWaylandBufferRef &ref, const QRegion &damage) override - { - Q_UNUSED(damage); - bufferRef = ref; - } + Q_UNUSED(damage); + bufferRef = ref; + } - QImage image() const - { - if (bufferRef.isNull() || !bufferRef.isSharedMemory()) - return QImage(); - return bufferRef.image(); - } + QImage image() const + { + if (bufferRef.isNull() || !bufferRef.isSharedMemory()) + return QImage(); + return bufferRef.image(); + } - QWaylandBufferRef bufferRef; - }; + QWaylandBufferRef bufferRef; +}; +void tst_WaylandCompositor::frameCallback() +{ TestCompositor compositor; compositor.create(); @@ -627,6 +662,35 @@ void tst_WaylandCompositor::frameCallback() wl_surface_destroy(surface); } +void tst_WaylandCompositor::pixelFormats() +{ + TestCompositor compositor; + compositor.create(); + + MockClient client; + + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + BufferView* view = new BufferView; + view->setSurface(waylandSurface); + view->setOutput(compositor.defaultOutput()); + + QSize size(32, 32); + ShmBuffer buffer(size, client.shm); // Will be WL_SHM_FORMAT_ARGB8888; + wl_surface_attach(surface, buffer.handle, 0, 0); + wl_surface_damage(surface, 0, 0, size.width(), size.height()); + wl_surface_commit(surface); + + QTRY_COMPARE(waylandSurface->hasContent(), true); + + // According to https://lists.freedesktop.org/archives/wayland-devel/2017-August/034791.html + // all RGB formats with alpha are premultiplied. Verify it here: + QCOMPARE(view->image().format(), QImage::Format_ARGB32_Premultiplied); + + wl_surface_destroy(surface); +} + void tst_WaylandCompositor::outputs() { TestCompositor compositor; @@ -720,9 +784,8 @@ void tst_WaylandCompositor::seatCreation() // The compositor will create the default input device QTRY_VERIFY(seat->isInitialized()); - QList<QMouseEvent *> allEvents; - allEvents += seat->createMouseEvents(5); - foreach (QMouseEvent *me, allEvents) { + const QList<QMouseEvent *> allEvents = seat->createMouseEvents(5); + for (QMouseEvent *me : allEvents) { compositor.seatFor(me); } @@ -851,6 +914,11 @@ void tst_WaylandCompositor::inputRegion() QVERIFY(!waylandSurface->inputRegionContains(QPoint(1, 6))); QVERIFY(!waylandSurface->inputRegionContains(QPoint(4, 2))); + QVERIFY(!waylandSurface->inputRegionContains(QPointF(0.99, 1.99))); + QVERIFY(waylandSurface->inputRegionContains(QPointF(1, 2))); + QVERIFY(waylandSurface->inputRegionContains(QPointF(3.99, 4.99))); + QVERIFY(!waylandSurface->inputRegionContains(QPointF(4, 5))); + // Setting a nullptr input region means we want all events wl_surface_set_input_region(surface, nullptr); wl_surface_commit(surface); @@ -1705,5 +1773,103 @@ void tst_WaylandCompositor::viewportHiDpi() wl_surface_destroy(surface); } +class IdleInhibitCompositor : public TestCompositor +{ + Q_OBJECT +public: + IdleInhibitCompositor() : idleInhibitManager(this) {} + QWaylandIdleInhibitManagerV1 idleInhibitManager; +}; + +void tst_WaylandCompositor::idleInhibit() +{ + IdleInhibitCompositor compositor; + compositor.create(); + MockClient client; + QTRY_VERIFY(client.idleInhibitManager); + + auto *surface = client.createSurface(); + QVERIFY(surface); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + auto *waylandSurfacePrivate = + QWaylandSurfacePrivate::get(waylandSurface); + QVERIFY(waylandSurfacePrivate); + + QSignalSpy changedSpy(waylandSurface, SIGNAL(inhibitsIdleChanged())); + + QCOMPARE(waylandSurface->inhibitsIdle(), false); + + auto *idleInhibitor = client.createIdleInhibitor(surface); + QVERIFY(idleInhibitor); + QTRY_COMPARE(waylandSurfacePrivate->idleInhibitors.size(), 1); + QCOMPARE(waylandSurface->inhibitsIdle(), true); + QTRY_COMPARE(changedSpy.count(), 1); +} + +class XdgOutputCompositor : public TestCompositor +{ + Q_OBJECT +public: + XdgOutputCompositor() : xdgOutputManager(this) {} + QWaylandXdgOutputManagerV1 xdgOutputManager; +}; + +void tst_WaylandCompositor::xdgOutput() +{ + XdgOutputCompositor compositor; + compositor.create(); + + QWaylandOutputMode mode(QSize(1024, 768), 60000); + compositor.defaultOutput()->addMode(mode, true); + compositor.defaultOutput()->setCurrentMode(mode); + + MockClient client; + QTRY_VERIFY(client.xdgOutputManager); + QTRY_COMPARE(client.m_outputs.size(), 1); + + auto *wlOutput = client.m_outputs.first(); + QVERIFY(wlOutput); + + // Output is not associated yet + QCOMPARE(QWaylandOutputPrivate::get(compositor.defaultOutput())->xdgOutput.isNull(), true); + + // Create xdg-output on the server + auto *xdgOutputServer = new QWaylandXdgOutputV1(compositor.defaultOutput(), &compositor.xdgOutputManager); + QVERIFY(xdgOutputServer); + xdgOutputServer->setName(QStringLiteral("OUTPUT1")); + xdgOutputServer->setDescription(QStringLiteral("This is a test output")); + + // Create it on the client + auto *xdgOutput = client.createXdgOutput(wlOutput); + QVERIFY(xdgOutput); + QVERIFY(client.m_xdgOutputs.contains(wlOutput)); + + // Now it should be associated + QCOMPARE(QWaylandOutputPrivate::get(compositor.defaultOutput())->xdgOutput.isNull(), false); + + // Verify initial values + QTRY_COMPARE(xdgOutput->name, "OUTPUT1"); + QTRY_COMPARE(xdgOutput->logicalPosition, QPoint()); + QTRY_COMPARE(xdgOutput->logicalSize, QSize()); + + // Change properties + xdgOutputServer->setName(QStringLiteral("OUTPUT2")); + xdgOutputServer->setDescription(QStringLiteral("New description")); + xdgOutputServer->setLogicalPosition(QPoint(100, 100)); + xdgOutputServer->setLogicalSize(QSize(1000, 1000)); + compositor.flushClients(); + + // Name and description can't be changed after initialization, + // so we expect them to be the same + // TODO: With protocol version 3 the description will be allowed to change, + // but we implement version 2 now + QTRY_COMPARE(xdgOutput->name, "OUTPUT1"); + QTRY_COMPARE(xdgOutput->description, "This is a test output"); + QTRY_COMPARE(xdgOutput->logicalPosition, QPoint(100, 100)); + QTRY_COMPARE(xdgOutput->logicalSize, QSize(1000, 1000)); +} + #include <tst_compositor.moc> QTEST_MAIN(tst_WaylandCompositor); |