From 12f2e1e23fc1de16a42d3024561c0f839f9e96cd Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 16 Nov 2016 09:37:51 +0100 Subject: Don't crash when surface is destroyed Change-Id: I082c3bb0003265c625d165e1463951842a730c11 Reviewed-by: Johan Helsing --- .../extensions/qwaylandquickshellsurfaceitem.cpp | 2 +- src/compositor/extensions/qwaylandwlshell.cpp | 6 +++--- src/compositor/extensions/qwaylandwlshell_p.h | 2 +- .../extensions/qwaylandwlshellintegration.cpp | 21 +++++++++++---------- .../extensions/qwaylandwlshellintegration_p.h | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index f6a88e434..91f9d7771 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -208,7 +208,7 @@ bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e) QMouseEvent *event = static_cast(e); QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast(item); bool finalRelease = (event->type() == QEvent::MouseButtonRelease) && (event->buttons() == Qt::NoButton); - bool popupClient = shellSurfaceItem && shellSurfaceItem->surface()->client() == client; + bool popupClient = shellSurfaceItem && shellSurfaceItem->surface() && shellSurfaceItem->surface()->client() == client; if (waitForRelease) { // We are eating events until all mouse buttons are released diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index 3145c6646..9b434679e 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -335,7 +335,7 @@ QList QWaylandWlShell::shellSurfacesForClient(QWayland Q_D(const QWaylandWlShell); QList surfsForClient; Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { - if (shellSurface->surface()->client() == client) + if (shellSurface->surface() && shellSurface->surface()->client() == client) surfsForClient.append(shellSurface); } return surfsForClient; @@ -347,7 +347,7 @@ QList QWaylandWlShell::mappedPopups() const QList popupSurfaces; Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { if (shellSurface->windowType() == Qt::WindowType::Popup - && shellSurface->surface()->hasContent()) { + && shellSurface->surface() && shellSurface->surface()->hasContent()) { popupSurfaces.append(shellSurface); } } @@ -359,7 +359,7 @@ QWaylandClient *QWaylandWlShell::popupClient() const Q_D(const QWaylandWlShell); Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { if (shellSurface->windowType() == Qt::WindowType::Popup - && shellSurface->surface()->hasContent()) { + && shellSurface->surface() && shellSurface->surface()->hasContent()) { return shellSurface->surface()->client(); } } diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h index 5e8903090..a087f6f75 100644 --- a/src/compositor/extensions/qwaylandwlshell_p.h +++ b/src/compositor/extensions/qwaylandwlshell_p.h @@ -98,7 +98,7 @@ public: private: QWaylandWlShell *m_shell; - QWaylandSurface *m_surface; + QPointer m_surface; QSet m_pings; diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index 30e4704af..761a9022e 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -55,17 +55,17 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item) , nextState(State::Windowed) { m_item->setSurface(m_shellSurface->surface()); - connect(m_shellSurface, &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove); - connect(m_shellSurface, &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize); connect(m_shellSurface->surface(), &QWaylandSurface::redraw, this, &WlShellIntegration::handleRedraw); connect(m_shellSurface->surface(), &QWaylandSurface::offsetForNextFrame, this, &WlShellIntegration::adjustOffsetForNextFrame); connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, this, &WlShellIntegration::handleSurfaceHasContentChanged); - connect(m_shellSurface, &QWaylandWlShellSurface::setDefaultToplevel, this, &WlShellIntegration::handleSetDefaultTopLevel); - connect(m_shellSurface, &QWaylandWlShellSurface::setTransient, this, &WlShellIntegration::handleSetTransient); - connect(m_shellSurface, &QWaylandWlShellSurface::setMaximized, this, &WlShellIntegration::handleSetMaximized); - connect(m_shellSurface, &QWaylandWlShellSurface::setFullScreen, this, &WlShellIntegration::handleSetFullScreen); - connect(m_shellSurface, &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup); - connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::setDefaultToplevel, this, &WlShellIntegration::handleSetDefaultTopLevel); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::setTransient, this, &WlShellIntegration::handleSetTransient); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::setMaximized, this, &WlShellIntegration::handleSetMaximized); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::setFullScreen, this, &WlShellIntegration::handleSetFullScreen); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup); + connect(m_shellSurface.data(), &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); } void WlShellIntegration::handleStartMove(QWaylandSeat *seat) @@ -182,8 +182,9 @@ void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *par } isPopup = true; - QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [&]() { - m_shellSurface->shell()->closeAllPopups(); + auto shell = m_shellSurface->shell(); + QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [shell]() { + shell->closeAllPopups(); }); QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h index bbdfbd733..c0bbcfd10 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration_p.h +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -88,7 +88,7 @@ private: void handlePopupRemoved(); QWaylandQuickShellSurfaceItem *m_item; - QWaylandWlShellSurface *m_shellSurface; + QPointer m_shellSurface; GrabberState grabberState; struct { QWaylandSeat *seat; -- cgit v1.2.3