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>
This commit is contained in:
parent
e51ff5c493
commit
dcff882f30
@ -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]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user