From 279406aa207584b22d27b4e8c5e5ecdef6c70ee9 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Tue, 16 Jul 2024 11:57:17 +0200 Subject: [PATCH] Client: Use std::unique_ptr to manage window decoration There was a potential crash in the QWaylandWindow destructor. First it deletes the window decoration (but does not unset the pointer!) and then deletes the surface via reset(). This eventually triggers QWaylandDisplay::handleKeyboardFocusChanged which will call decoration->update(). Using std::unique_ptr makes it easier to manage and prevents such errors. Change-Id: I52edcdab0d25c35dc656581fbb5c1c9b5ca481c4 Reviewed-by: Vlad Zahorodnii --- src/plugins/platforms/wayland/qwaylandwindow.cpp | 12 +++++------- src/plugins/platforms/wayland/qwaylandwindow_p.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index b9112d81ee1..581d353aaf0 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -72,7 +72,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display) QWaylandWindow::~QWaylandWindow() { - delete mWindowDecoration; + mWindowDecoration.reset(); if (mSurface) reset(); @@ -1064,8 +1064,7 @@ bool QWaylandWindow::createDecoration() if (decoration && !decorationPluginFailed) { if (!mWindowDecorationEnabled) { if (mWindowDecoration) { - delete mWindowDecoration; - mWindowDecoration = nullptr; + mWindowDecoration.reset(); } QStringList decorations = QWaylandDecorationFactory::keys(); @@ -1104,8 +1103,7 @@ bool QWaylandWindow::createDecoration() if (targetKey.isEmpty()) targetKey = decorations.first(); // first come, first served. - - mWindowDecoration = QWaylandDecorationFactory::create(targetKey, QStringList()); + mWindowDecoration.reset(QWaylandDecorationFactory::create(targetKey, QStringList())); if (!mWindowDecoration) { qWarning() << "Could not create decoration from factory! Running with no decorations."; decorationPluginFailed = true; @@ -1137,12 +1135,12 @@ bool QWaylandWindow::createDecoration() window()->requestUpdate(); } - return mWindowDecoration; + return mWindowDecoration.get(); } QWaylandAbstractDecoration *QWaylandWindow::decoration() const { - return mWindowDecorationEnabled ? mWindowDecoration : nullptr; + return mWindowDecorationEnabled ? mWindowDecoration.get() : nullptr; } static QWaylandWindow *closestShellSurfaceWindow(QWindow *window) diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 38423f79b1a..c165125501b 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -270,7 +270,7 @@ protected: QWaylandSubSurface *mSubSurfaceWindow = nullptr; QList mChildren; - QWaylandAbstractDecoration *mWindowDecoration = nullptr; + std::unique_ptr mWindowDecoration; bool mWindowDecorationEnabled = false; bool mMouseEventsInContentArea = false; Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;