diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 787b23ec4db..d501cb9400a 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -59,6 +59,8 @@ #include +Q_FORWARD_DECLARE_OBJC_CLASS(NSWindow); + QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher); @@ -67,7 +69,7 @@ typedef struct _NSModalSession *NSModalSession; typedef struct _QCocoaModalSessionInfo { QPointer window; NSModalSession session; - void *nswindow; + NSWindow *nswindow; } QCocoaModalSessionInfo; class QCocoaEventDispatcherPrivate; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index fd0a4b47172..66f2a7a21d0 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -374,6 +374,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // [NSApp run], which is the normal code path for cocoa applications. if (NSModalSession session = d->currentModalSession()) { QBoolBlocker execGuard(d->currentExecIsNSAppRun, false); + qCDebug(lcEventDispatcher) << "Running modal session" << session; while ([NSApp runModalSession:session] == NSModalResponseContinue && !d->interrupt) { qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode); if (session != d->currentModalSessionCached) { @@ -417,6 +418,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // to use cocoa's native way of running modal sessions: if (flags & QEventLoop::WaitForMoreEvents) qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode); + qCDebug(lcEventDispatcher) << "Running modal session" << session; NSInteger status = [NSApp runModalSession:session]; if (status != NSModalResponseContinue && session == d->currentModalSessionCached) { // INVARIANT: Someone called [NSApp stopModal:] from outside the event @@ -617,6 +619,8 @@ void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions() for (int i=0; igeometry(); info.session = [NSApp beginModalSessionForWindow:nswindow]; + qCDebug(lcEventDispatcher) << "Begun modal session" << info.session + << "for" << nswindow; // The call to beginModalSessionForWindow above processes events and may // have deleted or destroyed the window. Check if it's still valid. @@ -704,6 +710,8 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() currentModalSessionCached = nullptr; if (info.session) { Q_ASSERT(info.nswindow); + qCDebug(lcEventDispatcher) << "Ending modal session" << info.session + << "for" << info.nswindow; [NSApp endModalSession:info.session]; [(NSWindow *)info.nswindow release]; } @@ -716,6 +724,14 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) { + qCDebug(lcEventDispatcher) << "Adding modal session for" << window; + + if (std::any_of(cocoaModalSessionStack.constBegin(), cocoaModalSessionStack.constEnd(), + [&](const auto &sessionInfo) { return sessionInfo.window == window; })) { + qCWarning(lcEventDispatcher) << "Modal session for" << window << "already exists!"; + return; + } + // We need to start spinning the modal session. Usually this is done with // QDialog::exec() for Qt Widgets based applications, but for others that // just call show(), we need to interrupt(). @@ -736,6 +752,8 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) { + qCDebug(lcEventDispatcher) << "Removing modal session for" << window; + Q_Q(QCocoaEventDispatcher); // Mark all sessions attached to window as pending to be stopped. We do this @@ -966,6 +984,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() for (int i = 0; i < d->cocoaModalSessionStack.count(); ++i) { QCocoaModalSessionInfo &info = d->cocoaModalSessionStack[i]; if (info.session) { + qCDebug(lcEventDispatcher) << "Ending modal session" << info.session + << "for" << info.nswindow << "during shutdown"; [NSApp endModalSession:info.session]; [(NSWindow *)info.nswindow release]; }