summaryrefslogtreecommitdiff
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-04-28 13:39:52 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-04-29 13:25:24 +0200
commit41608170502a08b054a7a244034334d9f4c9ba11 (patch)
treec6e4fcca791b64c65d9707378a3000e28babf176 /src/plugins/platforms
parentd01aa396171e101ba03638799c2c6fae6d116240 (diff)
downloadqtbase-41608170502a08b054a7a244034334d9f4c9ba11.tar.gz
macOS: Don't leak QEventDispatcherUNIX during event dispatcher creation
During QCoreApplication initialization, we create the main thread's event dispatcher, which for a GUI app happens via QGuiApplicationPrivate's createEventDispatcher() override. This in turn relies on the platform integration to create the event dispatcher, but to do that it needs to create the platform integration first. And this might result in calling APIs that themselves initialize the main thread event dispatcher, such as QEventLoop, which non-lazily creates an event dispatcher for the thread. We already had a check to catch the platform integration setting the QCoreApplictionPrivate::eventDispatcher member, but not anything for checking the current thread data. On macOS this resulted in a leak of QEventDispatcherUNIX because QCocoaDrag contained a QEventLoop member. We now track the event loop temproarily via a pointer instead, like we do in other places. An alternative fix would be to defer the initialization of QCocoaDrag until QCocoaIntegration::drag() is called, but that would run the risk of something calling the function during platform initialization and we'd be back to the same problem. It's unclear why QEventLoop is not lazily ensuring the event dispatcher, and this might be a wider fix for similar issues. Pick-to: 6.5 Change-Id: I643010ddb09945936ce9b0b94de0df96f6fe218f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm9
2 files changed, 7 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h
index 24485ac6ac..dedf8a7fd9 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.h
+++ b/src/plugins/platforms/cocoa/qcocoadrag.h
@@ -44,7 +44,7 @@ private:
NSEvent *m_lastEvent;
NSView *m_lastView;
Qt::DropAction m_executed_drop_action;
- QEventLoop internalDragLoop;
+ QEventLoop *m_internalDragLoop = nullptr;
bool maybeDragMultipleItems();
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 101a13e3c2..de45e8a979 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -213,7 +213,9 @@ bool QCocoaDrag::maybeDragMultipleItems()
}
[sourceView beginDraggingSessionWithItems:dragItems event:m_lastEvent source:sourceView];
- internalDragLoop.exec();
+ QEventLoop eventLoop;
+ QScopedValueRollback updateGuard(m_internalDragLoop, &eventLoop);
+ eventLoop.exec();
return true;
}
@@ -224,8 +226,9 @@ void QCocoaDrag::setAcceptedAction(Qt::DropAction act)
void QCocoaDrag::exitDragLoop()
{
- if (internalDragLoop.isRunning())
- internalDragLoop.exit();
+ Q_ASSERT(m_internalDragLoop);
+ if (m_internalDragLoop->isRunning())
+ m_internalDragLoop->exit();
}