diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-04-28 13:39:52 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-04-29 13:25:24 +0200 |
commit | 41608170502a08b054a7a244034334d9f4c9ba11 (patch) | |
tree | c6e4fcca791b64c65d9707378a3000e28babf176 /src/plugins/platforms | |
parent | d01aa396171e101ba03638799c2c6fae6d116240 (diff) | |
download | qtbase-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.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoadrag.mm | 9 |
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(); } |