summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm62
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];
}