From 20d7d41a7486fd5cbc659c5d19b65d0f2d21f596 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 13 Sep 2022 09:01:13 +0200 Subject: QMacPasteboard: check QGuiApplication is alive for a promise containing QPixmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise, when platform integration is deleted, it triggers resolving promises after the global instance of QGuiApplication is dead and QPixmap in turn calls qFatal, crashing the exiting app. Fixes: QTBUG-106472 Change-Id: Ie706d030214c33abdbc8fff86cc2eddd0c632f1b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qmacclipboard.h | 6 ++++++ src/plugins/platforms/cocoa/qmacclipboard.mm | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h index 658497f743..925e816831 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.h +++ b/src/plugins/platforms/cocoa/qmacclipboard.h @@ -30,6 +30,12 @@ private: QPointer mimeData; QVariant variantData; DataRequestType dataRequestType; + // QMimeData can be set from QVariant, holding + // QPixmap. When converting, this triggers + // QPixmap's ctor which in turn requires QGuiApplication + // to exist and thus will abort the application + // abnormally if not. + bool isPixmap = false; }; QList promises; diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 5b77413def..b298a47bef 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -57,9 +58,12 @@ QMacPasteboard::Promise::Promise(int itemId, QMacInternalPasteboardMime *c, QStr // Request the data from the application immediately for eager requests. if (dataRequestType == QMacPasteboard::EagerRequest) { variantData = md->variantData(m); + isPixmap = variantData.metaType().id() == QMetaType::QPixmap; mimeData = nullptr; } else { mimeData = md; + if (md->hasImage()) + isPixmap = md->imageData().metaType().id() == QMetaType::QPixmap; } } @@ -170,8 +174,14 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id, // to request the data from the application. QVariant promiseData; if (promise.dataRequestType == LazyRequest) { - if (!qpaste->resolvingBeforeDestruction && !promise.mimeData.isNull()) + if (!qpaste->resolvingBeforeDestruction && !promise.mimeData.isNull()) { + if (promise.isPixmap && !QGuiApplication::instance()) { + qCWarning(lcQpaClipboard, + "Cannot keep promise, data contains QPixmap and requires livining QGuiApplication"); + return cantGetFlavorErr; + } promiseData = promise.mimeData->variantData(promise.mime); + } } else { promiseData = promise.variantData; } -- cgit v1.2.3