From 063299d8520ca5c944a596723e63e7654e712955 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 28 Aug 2017 12:58:55 +0200 Subject: qtwaylandscanner: Remove globals when destroying wrappers When globals are destroyed on the compositor side, send the "global_remove" event and set the resource implementation to nullptr so all further requests are ignored. This also adds a compositor test to see if outputs are removed when they are deleted. Change-Id: Ib77a4c3d4c2c93283a14ac20f5964e2ce08a1d38 Reviewed-by: David Edmundson Reviewed-by: Paul Olav Tvete --- tests/auto/compositor/compositor/mockclient.cpp | 24 +++++++++++++++++----- tests/auto/compositor/compositor/mockclient.h | 4 +++- .../auto/compositor/compositor/tst_compositor.cpp | 17 +++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) (limited to 'tests/auto/compositor/compositor') diff --git a/tests/auto/compositor/compositor/mockclient.cpp b/tests/auto/compositor/compositor/mockclient.cpp index 970890a65..85a89f04c 100644 --- a/tests/auto/compositor/compositor/mockclient.cpp +++ b/tests/auto/compositor/compositor/mockclient.cpp @@ -42,13 +42,12 @@ const struct wl_registry_listener MockClient::registryListener = { MockClient::handleGlobal, - nullptr + MockClient::handleGlobalRemove }; MockClient::MockClient() : display(wl_display_connect("wayland-qt-test-0")) , compositor(0) - , output(0) , registry(0) , wlshell(0) , xdgShell(nullptr) @@ -75,9 +74,9 @@ MockClient::MockClient() timeout.start(); do { QCoreApplication::processEvents(); - } while (!(compositor && output) && timeout.elapsed() < 1000); + } while (!(compositor && !m_outputs.isEmpty()) && timeout.elapsed() < 1000); - if (!compositor || !output) + if (!compositor || m_outputs.empty()) qFatal("MockClient(): failed to receive globals from display"); } @@ -166,12 +165,18 @@ void MockClient::handleGlobal(void *data, wl_registry *registry, uint32_t id, co resolve(data)->handleGlobal(id, QByteArray(interface)); } +void MockClient::handleGlobalRemove(void *data, wl_registry *wl_registry, uint32_t id) +{ + resolve(data)->handleGlobalRemove(id); +} + void MockClient::handleGlobal(uint32_t id, const QByteArray &interface) { if (interface == "wl_compositor") { compositor = static_cast(wl_registry_bind(registry, id, &wl_compositor_interface, 1)); } else if (interface == "wl_output") { - output = static_cast(wl_registry_bind(registry, id, &wl_output_interface, 2)); + auto output = static_cast(wl_registry_bind(registry, id, &wl_output_interface, 2)); + m_outputs.append(output); wl_output_add_listener(output, &outputListener, this); } else if (interface == "wl_shm") { shm = static_cast(wl_registry_bind(registry, id, &wl_shm_interface, 1)); @@ -187,6 +192,15 @@ void MockClient::handleGlobal(uint32_t id, const QByteArray &interface) } } +void MockClient::handleGlobalRemove(uint32_t id) +{ + for (auto output : m_outputs) { + auto outputId = wl_proxy_get_id(reinterpret_cast(output)); + if (outputId == id) + m_outputs.removeAll(output); + } +} + wl_surface *MockClient::createSurface() { flushDisplay(); diff --git a/tests/auto/compositor/compositor/mockclient.h b/tests/auto/compositor/compositor/mockclient.h index 1881393a6..7aa6a3b7b 100644 --- a/tests/auto/compositor/compositor/mockclient.h +++ b/tests/auto/compositor/compositor/mockclient.h @@ -64,7 +64,7 @@ public: wl_display *display; wl_compositor *compositor; - wl_output *output; + QVector m_outputs; wl_shm *shm; wl_registry *registry; wl_shell *wlshell; @@ -96,6 +96,7 @@ private: static MockClient *resolve(void *data) { return static_cast(data); } static const struct wl_registry_listener registryListener; static void handleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); + static void handleGlobalRemove(void *data, struct wl_registry *wl_registry, uint32_t id); static int sourceUpdate(uint32_t mask, void *data); static void outputGeometryEvent(void *data, @@ -117,6 +118,7 @@ private: static void outputScale(void *data, wl_output *output, int factor); void handleGlobal(uint32_t id, const QByteArray &interface); + void handleGlobalRemove(uint32_t id); static const wl_output_listener outputListener; }; diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index c54903dc0..39ae1d48c 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -64,6 +64,7 @@ private slots: void sizeFollowsWindow(); void mapSurface(); void frameCallback(); + void removeOutput(); void advertisesXdgShellSupport(); void createsXdgSurfaces(); @@ -375,6 +376,22 @@ void tst_WaylandCompositor::frameCallback() wl_surface_destroy(surface); } +void tst_WaylandCompositor::removeOutput() +{ + TestCompositor compositor; + QWindow window; + window.resize(800, 600); + auto output = new QWaylandOutput(&compositor, &window); + + compositor.create(); + MockClient client; + QTRY_COMPARE(client.m_outputs.size(), 2); + + delete output; + compositor.flushClients(); + QTRY_COMPARE(client.m_outputs.size(), 1); +} + void tst_WaylandCompositor::seatCapabilities() { TestCompositor compositor; -- cgit v1.2.3