summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-04-28 15:07:50 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-05-10 00:20:18 +0000
commitdcff882f30603dfeb91fbbb678bc053bfa453ed4 (patch)
treea5f92605a82a8825fde04967cc87da0245ce61b0 /src/plugins/platforms/cocoa/qcocoamessagedialog.mm
parente51ff5c4935330b00d8039e435ec6cac60cfb875 (diff)
macOS: Clear event dispatcher interrupt before running NSAlert modal session
If the event dispatcher is interrupted we propagate the interrupt to lower event loop levels, in case they too need to be interrupted. And we defer the actual interrupt of the NSApplication to the next time we process Qt events, to avoid AppKit dropping queued events on the floor. This logic relies on QCocoaEventDispatcher::processEvents() setting the interrupt flag to false, which signals that we should not continue to tear down any further event loops. Unfortunately, native run loops such as running application modal sessions, are not driven by QCocoaEventDispatcher::processEvents(), so we never reset the interrupt, and end up ending the session immediately. To work around this we need to explicitly clear the interrupt flag before starting native modal sessions. This also fixes the issue seen in QTBUG-111524 with showing native alerts from nested event loops. Fixes: QTBUG-112697 Task-number: QTBUG-111524 Pick-to: 6.5 6.5.1 Change-Id: I6aaec97011fd18c4a513c1dde3173b1cc4d50112 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoamessagedialog.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoamessagedialog.mm7
1 files changed, 3 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamessagedialog.mm b/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
index f19146c60c..e058450ebd 100644
--- a/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
+++ b/src/plugins/platforms/cocoa/qcocoamessagedialog.mm
@@ -5,6 +5,7 @@
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
+#include "qcocoaeventdispatcher.h"
#include <QtCore/qmetaobject.h>
#include <QtCore/qscopedvaluerollback.h>
@@ -90,10 +91,6 @@ bool QCocoaMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality w
if (!options())
return false;
- if (windowModality == Qt::ApplicationModal && QThread::currentThread()->loopLevel() > 1) {
- qCWarning(lcQpaDialogs, "Cannot use native application modal dialog from nested event loop");
- return false;
- }
Q_ASSERT(!m_alert);
m_alert = [NSAlert new];
@@ -224,6 +221,7 @@ bool QCocoaMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality w
QTimer::singleShot(0, this, [this]{
if (m_alert && NSApp.modalWindow != m_alert.window) {
qCDebug(lcQpaDialogs) << "Running deferred modal" << m_alert;
+ QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
processResponse([m_alert runModal]);
}
});
@@ -243,6 +241,7 @@ void QCocoaMessageDialog::exec()
m_eventLoop->exec(QEventLoop::DialogExec);
} else {
qCDebug(lcQpaDialogs) << "Running modal" << m_alert;
+ QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
processResponse([m_alert runModal]);
}
}