From 62e959eaa707a163daca69a42c733bbd272d41d6 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Wed, 30 Oct 2019 08:59:49 +0100 Subject: Client tests: Fix flaky deadlock Sometimes the test would wait indefinitely in the compositor constructor, while also waiting in the compositor thread for m_ready to become true. m_ready is set to true in applicationInitialized(), which is supposed to be called from the client thread after QGuiApplication has been created (and also after the MockCompositor constructor has returned). I.e. the problem is that the wake in MockCompositor::run may sometimes happen before the MockCompositor::MockCompositor starts waiting. Move the wake inside the pre-initialized compositor loop. Essentially waking every 20 ms until the application is initialized. Fixes: QTBUG-66570 Change-Id: Ia5eba5d08ce4d1d3eeca99eae6cfa7d9d4fd5a0b Reviewed-by: Paul Olav Tvete --- tests/auto/client/shared_old/mockcompositor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp index 0dfaef5ea..96dc059e7 100644 --- a/tests/auto/client/shared_old/mockcompositor.cpp +++ b/tests/auto/client/shared_old/mockcompositor.cpp @@ -312,9 +312,9 @@ void *MockCompositor::run(void *data) Impl::Compositor compositor(controller); controller->m_compositor = &compositor; - controller->m_waitCondition.wakeOne(); while (!controller->m_ready) { + controller->m_waitCondition.wakeOne(); controller->dispatchCommands(); compositor.dispatchEvents(20); } -- cgit v1.2.3 From e7c9adccf89ed13dd2a693bf0555062729a624e8 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Fri, 1 Nov 2019 10:14:20 +0100 Subject: Add basic client test for subsurfaces Change-Id: I1ef21287933a2afccad989f47e4fe59329b6f537 Reviewed-by: Paul Olav Tvete --- tests/auto/client/shared/coreprotocol.h | 25 ++++++++++++++++++++++++- tests/auto/client/shared/mockcompositor.h | 1 + tests/auto/client/surface/tst_surface.cpp | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h index 5cef476c8..f92842e02 100644 --- a/tests/auto/client/shared/coreprotocol.h +++ b/tests/auto/client/shared/coreprotocol.h @@ -163,6 +163,16 @@ protected: } }; +class Subsurface : public QObject, public QtWaylandServer::wl_subsurface +{ + Q_OBJECT +public: + explicit Subsurface(wl_client *client, int id, int version) + : QtWaylandServer::wl_subsurface(client, id, version) + { + } +}; + class SubCompositor : public Global, public QtWaylandServer::wl_subcompositor { Q_OBJECT @@ -170,7 +180,20 @@ public: explicit SubCompositor(CoreCompositor *compositor, int version = 1) : QtWaylandServer::wl_subcompositor(compositor->m_display, version) {} - // TODO + QVector m_subsurfaces; + +signals: + void subsurfaceCreated(Subsurface *subsurface); + +protected: + void subcompositor_get_subsurface(Resource *resource, uint32_t id, ::wl_resource *surface, ::wl_resource *parent) override + { + QTRY_VERIFY(parent); + QTRY_VERIFY(surface); + auto *subsurface = new Subsurface(resource->client(), id, resource->version()); + m_subsurfaces.append(subsurface); // TODO: clean up? + emit subsurfaceCreated(subsurface); + } }; struct OutputMode { diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h index f5264ccf6..f17c93426 100644 --- a/tests/auto/client/shared/mockcompositor.h +++ b/tests/auto/client/shared/mockcompositor.h @@ -50,6 +50,7 @@ public: // Convenience functions Output *output(int i = 0) { return getAll().value(i, nullptr); } Surface *surface(int i = 0) { return get()->m_surfaces.value(i, nullptr); } + Subsurface *subSurface(int i = 0) { return get()->m_subsurfaces.value(i, nullptr); } XdgSurface *xdgSurface(int i = 0) { return get()->m_xdgSurfaces.value(i, nullptr); } XdgToplevel *xdgToplevel(int i = 0) { return get()->toplevel(i); } XdgPopup *xdgPopup(int i = 0) { return get()->popup(i); } diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp index dddff0866..451fbac75 100644 --- a/tests/auto/client/surface/tst_surface.cpp +++ b/tests/auto/client/surface/tst_surface.cpp @@ -41,6 +41,8 @@ private slots: void waitForFrameCallbackRaster(); void waitForFrameCallbackGl(); void negotiateShmFormat(); + + void createSubsurface(); }; void tst_surface::createDestroySurface() @@ -154,5 +156,21 @@ void tst_surface::negotiateShmFormat() }); } +void tst_surface::createSubsurface() +{ + QRasterWindow window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + + QRasterWindow subWindow; + subWindow.setParent(&window); + subWindow.resize(64, 64); + subWindow.show(); + QCOMPOSITOR_TRY_VERIFY(subSurface()); +} + QCOMPOSITOR_TEST_MAIN(tst_surface) #include "tst_surface.moc" -- cgit v1.2.3 From 09474cdf5244ce6fba51a6b01bfe50caf7635c66 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Fri, 1 Nov 2019 10:16:43 +0100 Subject: Add client test for subsurface with hidden parent Task-number: QTBUG-79674 Change-Id: I451ee4423dee511f41070498a61167912920c086 Reviewed-by: Paul Olav Tvete --- tests/auto/client/surface/tst_surface.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp index 451fbac75..f9dcec581 100644 --- a/tests/auto/client/surface/tst_surface.cpp +++ b/tests/auto/client/surface/tst_surface.cpp @@ -42,7 +42,9 @@ private slots: void waitForFrameCallbackGl(); void negotiateShmFormat(); + // Subsurfaces void createSubsurface(); + void createSubsurfaceForHiddenParent(); }; void tst_surface::createDestroySurface() @@ -172,5 +174,26 @@ void tst_surface::createSubsurface() QCOMPOSITOR_TRY_VERIFY(subSurface()); } +// Used to cause a crash in libwayland (QTBUG-79674) +void tst_surface::createSubsurfaceForHiddenParent() +{ + QRasterWindow window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + + window.hide(); + + QRasterWindow subWindow; + subWindow.setParent(&window); + subWindow.resize(64, 64); + subWindow.show(); + + // Make sure the client doesn't quit before it has a chance to crash + xdgPingAndWaitForPong(); +} + QCOMPOSITOR_TEST_MAIN(tst_surface) #include "tst_surface.moc" -- cgit v1.2.3