summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-04-28 15:07:50 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-05-10 04:31:13 +0000
commit162ce53fcf72fe794d438326d0125495b950de9b (patch)
treedf3a5867cd0f2696f16f633f72b417d7669595f1
parentdbf4dbe386c1aaaa0a46a2ecb5b53362bedcd136 (diff)
downloadqtbase-162ce53fcf72fe794d438326d0125495b950de9b.tar.gz
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 Change-Id: I6aaec97011fd18c4a513c1dde3173b1cc4d50112 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit dcff882f30603dfeb91fbbb678bc053bfa453ed4) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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 e4e2260299..0aeb7bcbd0 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]);
}
}