diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index fd0a4b4717..739fbda4f5 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -115,6 +115,7 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() return; } + using DoubleSeconds = std::chrono::duration<double, std::ratio<1>>; if (!runLoopTimerRef) { // start the CFRunLoopTimer CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent(); @@ -122,10 +123,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); // Q: when should the CFRunLoopTimer fire for the first time? - struct timespec tv; - if (timerInfoList.timerWait(tv)) { + if (auto opt = timerInfoList.timerWait()) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + DoubleSeconds secs{*opt}; + interval = qMax(secs.count(), 0.0000001); } else { // this shouldn't really happen, but in case it does, set the timer to fire a some point in the distant future interval = oneyear; @@ -145,10 +146,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval interval; // Q: when should the timer first next? - struct timespec tv; - if (timerInfoList.timerWait(tv)) { + if (auto opt = timerInfoList.timerWait()) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + DoubleSeconds secs{*opt}; + interval = qMax(secs.count(), 0.0000001); } else { // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some // point in the distant future (the timer interval is one year) @@ -170,10 +171,11 @@ void QCocoaEventDispatcherPrivate::maybeStopCFRunLoopTimer() runLoopTimerRef = nullptr; } -void QCocoaEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *obj) +void QCocoaEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval, + Qt::TimerType timerType, QObject *obj) { #ifndef QT_NO_DEBUG - if (timerId < 1 || interval < 0 || !obj) { + if (qToUnderlying(timerId) < 1 || interval.count() < 0 || !obj) { qWarning("QCocoaEventDispatcher::registerTimer: invalid arguments"); return; } else if (obj->thread() != thread() || thread() != QThread::currentThread()) { @@ -187,10 +189,10 @@ void QCocoaEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::Time d->maybeStartCFRunLoopTimer(); } -bool QCocoaEventDispatcher::unregisterTimer(int timerId) +bool QCocoaEventDispatcher::unregisterTimer(Qt::TimerId timerId) { #ifndef QT_NO_DEBUG - if (timerId < 1) { + if (qToUnderlying(timerId) < 1) { qWarning("QCocoaEventDispatcher::unregisterTimer: invalid argument"); return false; } else if (thread() != QThread::currentThread()) { @@ -229,13 +231,13 @@ bool QCocoaEventDispatcher::unregisterTimers(QObject *obj) return returnValue; } -QList<QCocoaEventDispatcher::TimerInfo> -QCocoaEventDispatcher::registeredTimers(QObject *object) const +QList<QCocoaEventDispatcher::TimerInfoV2> +QCocoaEventDispatcher::timersForObject(QObject *object) const { #ifndef QT_NO_DEBUG if (!object) { qWarning("QCocoaEventDispatcher:registeredTimers: invalid argument"); - return QList<TimerInfo>(); + return {}; } #endif @@ -374,6 +376,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 +420,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 @@ -537,17 +541,17 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) return retVal; } -int QCocoaEventDispatcher::remainingTime(int timerId) +auto QCocoaEventDispatcher::remainingTime(Qt::TimerId timerId) const -> Duration { #ifndef QT_NO_DEBUG - if (timerId < 1) { + if (qToUnderlying(timerId) < 1) { qWarning("QCocoaEventDispatcher::remainingTime: invalid argument"); - return -1; + return Duration::min(); } #endif - Q_D(QCocoaEventDispatcher); - return d->timerInfoList.timerRemainingTime(timerId); + Q_D(const QCocoaEventDispatcher); + return d->timerInfoList.remainingDuration(timerId); } void QCocoaEventDispatcher::wakeUp() @@ -617,6 +621,8 @@ void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions() for (int i=0; i<stackSize; ++i) { QCocoaModalSessionInfo &info = cocoaModalSessionStack[i]; if (info.session) { + qCDebug(lcEventDispatcher) << "Temporarily ending modal session" << info.session + << "for" << info.nswindow; [NSApp endModalSession:info.session]; info.session = nullptr; [(NSWindow*) info.nswindow release]; @@ -656,6 +662,8 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() [(NSWindow*) info.nswindow retain]; QRect rect = cocoaWindow->geometry(); 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 +712,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 +726,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 +754,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 @@ -782,7 +802,7 @@ void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *even } QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) - : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent) + : QAbstractEventDispatcherV2(*new QCocoaEventDispatcherPrivate, parent) { Q_D(QCocoaEventDispatcher); @@ -957,7 +977,7 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() { Q_D(QCocoaEventDispatcher); - qDeleteAll(d->timerInfoList); + d->timerInfoList.clearTimers(); d->maybeStopCFRunLoopTimer(); CFRunLoopRemoveSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes); CFRelease(d->activateTimersSourceRef); @@ -966,6 +986,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]; } |