From e82679a683fb0bfec251cd619977b4f015a68b0a Mon Sep 17 00:00:00 2001 From: rewine Date: Fri, 21 Feb 2025 13:47:32 +0800 Subject: [PATCH 1/2] Fix get null handle in a valid qwobject Fix null pointer access issue encountered in EventItem::contains, When WXWaylandSurface calls safeDeleteLater to destroy, WSurface should invalidated in time --- src/server/kernel/wglobal.cpp | 3 +++ src/server/protocols/wxwaylandsurface.cpp | 9 +++++++-- src/server/qtquick/private/wsurfaceitem_p.h | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/server/kernel/wglobal.cpp b/src/server/kernel/wglobal.cpp index 22069b7b4..6d25ec275 100644 --- a/src/server/kernel/wglobal.cpp +++ b/src/server/kernel/wglobal.cpp @@ -202,6 +202,9 @@ QW_NAMESPACE::qw_object_basic *WWrapObject::handle() const bool WWrapObject::isInvalidated() const { W_DC(WWrapObject); + + Q_ASSERT_X(d->invalidated || handle() != nullptr, Q_FUNC_INFO, "WWrapObject not invalidate in time"); + return d->invalidated; } diff --git a/src/server/protocols/wxwaylandsurface.cpp b/src/server/protocols/wxwaylandsurface.cpp index 793555425..e79f91039 100644 --- a/src/server/protocols/wxwaylandsurface.cpp +++ b/src/server/protocols/wxwaylandsurface.cpp @@ -63,9 +63,14 @@ class Q_DECL_HIDDEN WXWaylandSurfacePrivate : public WToplevelSurfacePrivate void WXWaylandSurfacePrivate::instantRelease() { + W_Q(WXWaylandSurface); handle()->set_data(nullptr, nullptr); - if (surface) - surface->removeAttachedData(); + handle()->disconnect(q); + + if (!surface) + return; + surface->safeDeleteLater(); + surface = nullptr; } void WXWaylandSurfacePrivate::init() diff --git a/src/server/qtquick/private/wsurfaceitem_p.h b/src/server/qtquick/private/wsurfaceitem_p.h index f0cfa451c..f100db793 100644 --- a/src/server/qtquick/private/wsurfaceitem_p.h +++ b/src/server/qtquick/private/wsurfaceitem_p.h @@ -5,6 +5,7 @@ #include "wsurfaceitem.h" #include "wsurface.h" +#include "wwrappointer.h" #include #include @@ -63,8 +64,8 @@ class Q_DECL_HIDDEN WSurfaceItemPrivate : public QQuickItemPrivate } Q_DECLARE_PUBLIC(WSurfaceItem) - QPointer surface; - QPointer shellSurface; + WWrapPointer surface; + WWrapPointer shellSurface; std::unique_ptr surfaceState; QQuickItem *contentContainer = nullptr; QQmlComponent *delegate = nullptr; From 1daff852ccabe49049ccf363f39e03cb8dab5e10 Mon Sep 17 00:00:00 2001 From: rewine Date: Fri, 21 Feb 2025 17:34:18 +0800 Subject: [PATCH 2/2] Don't use WWrapPointer if has monitor aboutToBeInvalidated --- src/server/qtquick/private/wsurfaceitem_p.h | 2 +- src/server/qtquick/wsurfaceitem.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/server/qtquick/private/wsurfaceitem_p.h b/src/server/qtquick/private/wsurfaceitem_p.h index f100db793..4e21d436a 100644 --- a/src/server/qtquick/private/wsurfaceitem_p.h +++ b/src/server/qtquick/private/wsurfaceitem_p.h @@ -64,7 +64,7 @@ class Q_DECL_HIDDEN WSurfaceItemPrivate : public QQuickItemPrivate } Q_DECLARE_PUBLIC(WSurfaceItem) - WWrapPointer surface; + WSurface *surface = nullptr; WWrapPointer shellSurface; std::unique_ptr surfaceState; QQuickItem *contentContainer = nullptr; diff --git a/src/server/qtquick/wsurfaceitem.cpp b/src/server/qtquick/wsurfaceitem.cpp index 9f4b571db..fd0478d7f 100644 --- a/src/server/qtquick/wsurfaceitem.cpp +++ b/src/server/qtquick/wsurfaceitem.cpp @@ -271,7 +271,7 @@ class Q_DECL_HIDDEN WSurfaceItemContentPrivate: public QQuickItemPrivate } W_DECLARE_PUBLIC(WSurfaceItemContent) - WWrapPointer surface; + WSurface *surface = nullptr; QRectF bufferSourceBox; QPoint bufferOffset; qreal devicePixelRatio = 1.0; @@ -592,7 +592,7 @@ WSurfaceItem *WSurfaceItem::fromFocusObject(QObject *focusObject) WSurface *WSurfaceItem::surface() const { Q_D(const WSurfaceItem); - return d->surface.get(); + return d->surface; } void WSurfaceItem::setSurface(WSurface *surface) @@ -900,6 +900,7 @@ void WSurfaceItem::releaseResources() if (d->surface) { d->surface->safeDisconnect(this); + d->surface = nullptr; } if (!d->surfaceFlags.testFlag(DontCacheLastBuffer)) { @@ -936,7 +937,7 @@ bool WSurfaceItem::sendEvent(QInputEvent *event) if (!d->surface) return false; - return WSeat::sendEvent(d->surface.get(), this, d->eventItem, event); + return WSeat::sendEvent(d->surface, this, d->eventItem, event); } bool WSurfaceItem::doResizeSurface(const QSize &newSize) @@ -1220,7 +1221,7 @@ WSurfaceItem *WSurfaceItemPrivate::ensureSubsurfaceItem(WSurface *subsurfaceSurf { for (int i = 0; i < subsurfaces.count(); ++i) { auto surfaceItem = subsurfaces.at(i); - WSurface *surface = surfaceItem->d_func()->surface.get(); + WSurface *surface = surfaceItem->d_func()->surface; if (surface && surface == subsurfaceSurface) { if (surfaceItem->parent() == parent) {