From 18175b6eb8d8cfdc12003186ec1829579a35fef4 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 22 Feb 2018 15:33:40 +0100 Subject: Client test for xdg-shell v6 configure events Task-number: QTBUG-66689 Change-Id: Ifdf38a9ab73357fdbe61e77f0464b227ddd2e8ac Reviewed-by: Andy Nichols --- tests/auto/client/client/tst_client.cpp | 1 + tests/auto/client/shared/mockcompositor.cpp | 28 ++++++++++ tests/auto/client/shared/mockcompositor.h | 24 ++++++++ tests/auto/client/shared/mockxdgshellv6.cpp | 73 +++++++++++++------------ tests/auto/client/shared/mockxdgshellv6.h | 56 +++++++++++++++++++ tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp | 28 ++++++++++ 6 files changed, 176 insertions(+), 34 deletions(-) diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp index ab9e5754d..02c5bab3e 100644 --- a/tests/auto/client/client/tst_client.cpp +++ b/tests/auto/client/client/tst_client.cpp @@ -153,6 +153,7 @@ public slots: // make sure the surfaces from the last test are properly cleaned up // and don't show up as false positives in the next test QTRY_VERIFY(!compositor->surface()); + QTRY_VERIFY(!compositor->xdgToplevelV6()); } private slots: diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp index ef2636b0f..c11d952a7 100644 --- a/tests/auto/client/shared/mockcompositor.cpp +++ b/tests/auto/client/shared/mockcompositor.cpp @@ -219,6 +219,14 @@ void MockCompositor::sendSurfaceLeave(const QSharedPointer &surface processCommand(command); } +void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer toplevel, const QSize &size) +{ + Command command = makeCommand(Impl::Compositor::sendXdgToplevelV6Configure, m_compositor); + command.parameters << QVariant::fromValue(toplevel); + command.parameters << QVariant::fromValue(size); + processCommand(command); +} + void MockCompositor::waitForStartDrag() { Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor); @@ -251,6 +259,16 @@ QSharedPointer MockCompositor::output(int index) return result; } +QSharedPointer MockCompositor::xdgToplevelV6(int index) +{ + QSharedPointer result; + lock(); + if (Impl::XdgToplevelV6 *toplevel = m_compositor->xdgShellV6()->toplevels().value(index, nullptr)) + result = toplevel->mockToplevel(); + unlock(); + return result; +} + MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target) { Command command; @@ -400,6 +418,11 @@ QVector Compositor::outputs() const return m_outputs; } +XdgShellV6 *Compositor::xdgShellV6() const +{ + return m_xdgShellV6.data(); +} + uint32_t Compositor::nextSerial() { return wl_display_next_serial(m_display); @@ -429,5 +452,10 @@ Output *Compositor::resolveOutput(const QVariant &v) return mockOutput ? mockOutput->handle() : nullptr; } +XdgToplevelV6 *Compositor::resolveToplevel(const QVariant &v) +{ + QSharedPointer mockToplevel = v.value>(); + return mockToplevel ? mockToplevel->handle() : nullptr; } +} diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h index c0c3c884f..48461e253 100644 --- a/tests/auto/client/shared/mockcompositor.h +++ b/tests/auto/client/shared/mockcompositor.h @@ -29,6 +29,8 @@ #ifndef MOCKCOMPOSITOR_H #define MOCKCOMPOSITOR_H +#include "mockxdgshellv6.h" + #include #include #include @@ -70,6 +72,8 @@ public: QVector surfaces() const; QVector outputs() const; + XdgShellV6 *xdgShellV6() const; + void addSurface(Surface *surface); void removeSurface(Surface *surface); @@ -93,6 +97,7 @@ public: static void sendRemoveOutput(void *data, const QList ¶meters); static void sendOutputGeometry(void *data, const QList ¶meters); static void sendSurfaceEnter(void *data, const QList ¶meters); + static void sendXdgToplevelV6Configure(void *data, const QList ¶meters); static void sendSurfaceLeave(void *data, const QList ¶meters); public: @@ -102,6 +107,7 @@ private: static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id); static Surface *resolveSurface(const QVariant &v); static Output *resolveOutput(const QVariant &v); + static XdgToplevelV6 *resolveToplevel(const QVariant &v); void initShm(); @@ -146,6 +152,22 @@ private: Q_DECLARE_METATYPE(QSharedPointer) +class MockXdgToplevelV6 +{ +public: + Impl::XdgToplevelV6 *handle() const { return m_toplevel; } + + void sendConfigure(const QSharedPointer toplevel); +private: + MockXdgToplevelV6(Impl::XdgToplevelV6 *toplevel) : m_toplevel(toplevel) {} + friend class Impl::Compositor; + friend class Impl::XdgToplevelV6; + + Impl::XdgToplevelV6 *m_toplevel; +}; + +Q_DECLARE_METATYPE(QSharedPointer) + class MockOutput { public: Impl::Output *handle() const { return m_output; } @@ -187,10 +209,12 @@ public: void sendOutputGeometry(const QSharedPointer &output, const QRect &geometry); void sendSurfaceEnter(const QSharedPointer &surface, QSharedPointer &output); void sendSurfaceLeave(const QSharedPointer &surface, QSharedPointer &output); + void sendXdgToplevelV6Configure(const QSharedPointer toplevel, const QSize &size); void waitForStartDrag(); QSharedPointer surface(); QSharedPointer output(int index = 0); + QSharedPointer xdgToplevelV6(int index = 0); void lock(); void unlock(); diff --git a/tests/auto/client/shared/mockxdgshellv6.cpp b/tests/auto/client/shared/mockxdgshellv6.cpp index f909fa108..5c83f2db3 100644 --- a/tests/auto/client/shared/mockxdgshellv6.cpp +++ b/tests/auto/client/shared/mockxdgshellv6.cpp @@ -28,47 +28,26 @@ #include "mockxdgshellv6.h" #include "mocksurface.h" +#include "mockcompositor.h" namespace Impl { -class XdgSurfaceV6; - -class XdgToplevelV6 : public QtWaylandServer::zxdg_toplevel_v6 -{ -public: - XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version) - : QtWaylandServer::zxdg_toplevel_v6(client, id, version) - , m_xdgSurface(xdgSurface) - {} - void zxdg_toplevel_v6_destroy_resource(Resource *) override { delete this; } - void zxdg_toplevel_v6_destroy(Resource *resource) override; - XdgSurfaceV6 *m_xdgSurface = nullptr; -}; - -class XdgSurfaceV6 : public QtWaylandServer::zxdg_surface_v6 -{ -public: - XdgSurfaceV6(wl_client *client, uint32_t id, Surface *surface); - void zxdg_surface_v6_destroy_resource(Resource *) override { delete this; } - void zxdg_surface_v6_get_toplevel(Resource *resource, uint32_t id) override; - void zxdg_surface_v6_destroy(Resource *resource) override - { - Q_ASSERT(!m_toplevel); - wl_resource_destroy(resource->handle); - } - Surface *m_surface = nullptr; - XdgToplevelV6 *m_toplevel = nullptr; -}; - -void XdgToplevelV6::zxdg_toplevel_v6_destroy(QtWaylandServer::zxdg_toplevel_v6::Resource *resource) +void Compositor::sendXdgToplevelV6Configure(void *data, const QList ¶meters) { - m_xdgSurface->m_toplevel = nullptr; - wl_resource_destroy(resource->handle); + Compositor *compositor = static_cast(data); + XdgToplevelV6 *toplevel = resolveToplevel(parameters.at(0)); + Q_ASSERT(toplevel && toplevel->resource()); + QSize size = parameters.at(1).toSize(); + Q_ASSERT(size.isValid()); + QByteArray states; + toplevel->send_configure(size.width(), size.height(), states); + toplevel->xdgSurface()->send_configure(compositor->nextSerial()); } -XdgSurfaceV6::XdgSurfaceV6(wl_client *client, uint32_t id, Surface *surface) +XdgSurfaceV6::XdgSurfaceV6(XdgShellV6 *shell, Surface *surface, wl_client *client, uint32_t id) : QtWaylandServer::zxdg_surface_v6(client, id, 1) , m_surface(surface) + , m_shell(shell) { } @@ -79,9 +58,35 @@ void XdgSurfaceV6::zxdg_surface_v6_get_toplevel(QtWaylandServer::zxdg_surface_v6 m_surface->map(); } +void XdgSurfaceV6::zxdg_surface_v6_destroy(QtWaylandServer::zxdg_surface_v6::Resource *resource) +{ + Q_ASSERT(!m_toplevel); + wl_resource_destroy(resource->handle); +} + +XdgToplevelV6::XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version) + : QtWaylandServer::zxdg_toplevel_v6(client, id, version) + , m_xdgSurface(xdgSurface) + , m_mockToplevel(new MockXdgToplevelV6(this)) +{ + m_xdgSurface->shell()->addToplevel(this); +} + +XdgToplevelV6::~XdgToplevelV6() +{ + m_xdgSurface->shell()->removeToplevel(this); + m_mockToplevel->m_toplevel = nullptr; +} + +void XdgToplevelV6::zxdg_toplevel_v6_destroy(QtWaylandServer::zxdg_toplevel_v6::Resource *resource) +{ + m_xdgSurface->m_toplevel = nullptr; + wl_resource_destroy(resource->handle); +} + void Impl::XdgShellV6::zxdg_shell_v6_get_xdg_surface(QtWaylandServer::zxdg_shell_v6::Resource *resource, uint32_t id, wl_resource *surface) { - new XdgSurfaceV6(resource->client(), id, Surface::fromResource(surface)); + new XdgSurfaceV6(this, Surface::fromResource(surface), resource->client(), id); } } // namespace Impl diff --git a/tests/auto/client/shared/mockxdgshellv6.h b/tests/auto/client/shared/mockxdgshellv6.h index d72606d24..f836ebd07 100644 --- a/tests/auto/client/shared/mockxdgshellv6.h +++ b/tests/auto/client/shared/mockxdgshellv6.h @@ -28,16 +28,72 @@ #include +#include +#include + #ifndef MOCKXDGSHELLV6_H #define MOCKXDGSHELLV6_H +class MockXdgToplevelV6; + namespace Impl { +class XdgToplevelV6; +class XdgShellV6; +class Surface; + +class XdgSurfaceV6 : public QtWaylandServer::zxdg_surface_v6 +{ +public: + XdgSurfaceV6(XdgShellV6 *shell, Surface *surface, wl_client *client, uint32_t id); + XdgShellV6 *shell() const { return m_shell; } + +protected: + void zxdg_surface_v6_destroy_resource(Resource *) override { delete this; } + void zxdg_surface_v6_get_toplevel(Resource *resource, uint32_t id) override; + void zxdg_surface_v6_destroy(Resource *resource) override; + +private: + Surface *m_surface = nullptr; + XdgToplevelV6 *m_toplevel = nullptr; + XdgShellV6 *m_shell = nullptr; + + friend class XdgToplevelV6; +}; + +class XdgToplevelV6 : public QtWaylandServer::zxdg_toplevel_v6 +{ +public: + XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version); + ~XdgToplevelV6() override; + XdgSurfaceV6 *xdgSurface() const { return m_xdgSurface; } + + QSharedPointer mockToplevel() const { return m_mockToplevel; } + +protected: + void zxdg_toplevel_v6_destroy_resource(Resource *) override { delete this; } + void zxdg_toplevel_v6_destroy(Resource *resource) override; + +private: + XdgSurfaceV6 *m_xdgSurface = nullptr; + QSharedPointer m_mockToplevel; +}; + class XdgShellV6 : public QtWaylandServer::zxdg_shell_v6 { public: explicit XdgShellV6(::wl_display *display) : zxdg_shell_v6(display, 1) {} + QVector toplevels() const { return m_toplevels; } + +protected: void zxdg_shell_v6_get_xdg_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override; + +private: + void addToplevel(XdgToplevelV6 *toplevel) { m_toplevels.append(toplevel); } + void removeToplevel(XdgToplevelV6 *toplevel) { m_toplevels.removeOne(toplevel); } + QVector m_toplevels; + + friend class XdgToplevelV6; }; } // namespace Impl diff --git a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp index 9e4aa8c07..364cd1099 100644 --- a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp +++ b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp @@ -76,10 +76,12 @@ public slots: // make sure the surfaces from the last test are properly cleaned up // and don't show up as false positives in the next test QTRY_VERIFY(!m_compositor->surface()); + QTRY_VERIFY(!m_compositor->xdgToplevelV6()); } private slots: void createDestroyWindow(); + void configure(); private: MockCompositor *m_compositor = nullptr; @@ -96,6 +98,32 @@ void tst_WaylandClientXdgShellV6::createDestroyWindow() QTRY_VERIFY(!m_compositor->surface()); } +void tst_WaylandClientXdgShellV6::configure() +{ + QSharedPointer output; + QTRY_VERIFY(output = m_compositor->output()); + + TestWindow window; + window.show(); + + QSharedPointer surface; + QTRY_VERIFY(surface = m_compositor->surface()); + + m_compositor->processWaylandEvents(); + QTRY_VERIFY(window.isVisible()); + QTRY_VERIFY(!window.isExposed()); //Window should not be exposed before the first configure event + + //TODO: according to xdg-shell protocol, a buffer should not be attached to a the surface + //until it's configured. Ensure this in the test! + + QSharedPointer toplevel; + QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6()); + const QSize newSize(123, 456); + m_compositor->sendXdgToplevelV6Configure(toplevel, newSize); + QTRY_VERIFY(window.isExposed()); + QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), newSize)); +} + int main(int argc, char **argv) { setenv("XDG_RUNTIME_DIR", ".", 1); -- cgit v1.2.3