diff options
author | Liang Qi <liang.qi@qt.io> | 2019-11-05 07:48:33 +0100 |
---|---|---|
committer | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2019-11-05 11:35:46 +0100 |
commit | b990f98b44ced37a319d7f476fad7bfb3e070be0 (patch) | |
tree | 171a797b6e82a9433e047de7a2ffe475e544a1e8 | |
parent | d4ac2c9915fed87193cd2cf7ac438a9fa8edc126 (diff) | |
parent | 09474cdf5244ce6fba51a6b01bfe50caf7635c66 (diff) |
Merge remote-tracking branch 'origin/5.13' into 5.14
Conflicts:
src/client/qwaylanddisplay.cpp
src/client/qwaylandwindow.cpp
Change-Id: I30ddf5305b3087b93cf4d6e562fd0146dea61cc0
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 4 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 7 | ||||
-rw-r--r-- | tests/auto/client/shared/coreprotocol.h | 25 | ||||
-rw-r--r-- | tests/auto/client/shared/mockcompositor.h | 1 | ||||
-rw-r--r-- | tests/auto/client/shared_old/mockcompositor.cpp | 2 | ||||
-rw-r--r-- | tests/auto/client/surface/tst_surface.cpp | 41 |
6 files changed, 75 insertions, 5 deletions
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index a17e8917a..0464d3a42 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -114,6 +114,10 @@ struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion) return nullptr; } + // Make sure we don't pass NULL surfaces to libwayland (crashes) + Q_ASSERT(parent->wlSurface()); + Q_ASSERT(window->wlSurface()); + return mSubCompositor->get_subsurface(window->wlSurface(), parent->wlSurface()); } diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index bffb57015..950486c0c 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -125,9 +125,10 @@ void QWaylandWindow::initWindow() if (shouldCreateSubSurface()) { Q_ASSERT(!mSubSurfaceWindow); - QWaylandWindow *p = static_cast<QWaylandWindow *>(QPlatformWindow::parent()); - if (::wl_subsurface *ss = mDisplay->createSubSurface(this, p)) { - mSubSurfaceWindow = new QWaylandSubSurface(this, p, ss); + auto *parent = static_cast<QWaylandWindow *>(QPlatformWindow::parent()); + if (parent->wlSurface()) { + if (::wl_subsurface *subsurface = mDisplay->createSubSurface(this, parent)) + mSubSurfaceWindow = new QWaylandSubSurface(this, parent, subsurface); } } else if (shouldCreateShellSurface()) { Q_ASSERT(!mShellSurface); diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h index fe8202ad1..a12d22d36 100644 --- a/tests/auto/client/shared/coreprotocol.h +++ b/tests/auto/client/shared/coreprotocol.h @@ -164,6 +164,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 @@ -171,7 +181,20 @@ public: explicit SubCompositor(CoreCompositor *compositor, int version = 1) : QtWaylandServer::wl_subcompositor(compositor->m_display, version) {} - // TODO + QVector<Subsurface *> 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 c7d85b958..deef1f909 100644 --- a/tests/auto/client/shared/mockcompositor.h +++ b/tests/auto/client/shared/mockcompositor.h @@ -56,6 +56,7 @@ public: // Convenience functions Output *output(int i = 0) { return getAll<Output>().value(i, nullptr); } Surface *surface(int i = 0) { return get<WlCompositor>()->m_surfaces.value(i, nullptr); } + Subsurface *subSurface(int i = 0) { return get<SubCompositor>()->m_subsurfaces.value(i, nullptr); } XdgSurface *xdgSurface(int i = 0) { return get<XdgWmBase>()->m_xdgSurfaces.value(i, nullptr); } XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); } XdgPopup *xdgPopup(int i = 0) { return get<XdgWmBase>()->popup(i); } diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp index f71a78102..9553076dd 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); } diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp index 9659235a0..b8a65f159 100644 --- a/tests/auto/client/surface/tst_surface.cpp +++ b/tests/auto/client/surface/tst_surface.cpp @@ -45,6 +45,10 @@ private slots: void waitForFrameCallbackGl(); #endif void negotiateShmFormat(); + + // Subsurfaces + void createSubsurface(); + void createSubsurfaceForHiddenParent(); }; void tst_surface::createDestroySurface() @@ -160,5 +164,42 @@ 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()); +} + +// 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" |