QCocoaEventDispatcherPrivate members should not be static
Keep the Cocoa event dispatcher's private data as normal members of QCocoaEventDispatcherPrivate. This removes the global initializers for the macTimerHash and cocoaModalSessionStask as well. To keep timers working, we pass a pointer to the timer's MacTimerInfo struct to the callback, instead of just the timer id. The MacTimerInfo needs to keep a pointer back to the QCocoaEventDispatcherPrivate to get access to the private's members. Change-Id: Ic3a61e5e1d1d82030735de73cf0b0c70a13c21a4 Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@nokia.com>
This commit is contained in:
parent
a8495549d0
commit
da47d70c32
@ -130,13 +130,10 @@ public:
|
||||
void wakeUp();
|
||||
void interrupt();
|
||||
void flush();
|
||||
|
||||
private:
|
||||
//friend void qt_mac_select_timer_callbk(__EventLoopTimer*, void*);
|
||||
friend class QApplicationPrivate;
|
||||
};
|
||||
|
||||
struct MacTimerInfo {
|
||||
QCocoaEventDispatcherPrivate *d_ptr;
|
||||
int id;
|
||||
int interval;
|
||||
Qt::TimerType timerType;
|
||||
@ -166,26 +163,27 @@ class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate
|
||||
public:
|
||||
QCocoaEventDispatcherPrivate();
|
||||
|
||||
static MacTimerHash macTimerHash;
|
||||
MacTimerHash macTimerHash;
|
||||
|
||||
// Set 'blockSendPostedEvents' to true if you _really_ need
|
||||
// to make sure that qt events are not posted while calling
|
||||
// low-level cocoa functions (like beginModalForWindow). And
|
||||
// use a QBoolBlocker to be safe:
|
||||
static bool blockSendPostedEvents;
|
||||
bool blockSendPostedEvents;
|
||||
// The following variables help organizing modal sessions:
|
||||
static QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
|
||||
static bool currentExecIsNSAppRun;
|
||||
static bool nsAppRunCalledByQt;
|
||||
static bool cleanupModalSessionsNeeded;
|
||||
static NSModalSession currentModalSessionCached;
|
||||
static NSModalSession currentModalSession();
|
||||
static void updateChildrenWorksWhenModal();
|
||||
static void temporarilyStopAllModalSessions();
|
||||
static void beginModalSession(QWindow *widget);
|
||||
static void endModalSession(QWindow *widget);
|
||||
static void cancelWaitForMoreEvents();
|
||||
static void cleanupModalSessions();
|
||||
static void ensureNSAppInitialized();
|
||||
QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
|
||||
bool currentExecIsNSAppRun;
|
||||
bool nsAppRunCalledByQt;
|
||||
bool cleanupModalSessionsNeeded;
|
||||
NSModalSession currentModalSessionCached;
|
||||
NSModalSession currentModalSession();
|
||||
void updateChildrenWorksWhenModal();
|
||||
void temporarilyStopAllModalSessions();
|
||||
void beginModalSession(QWindow *widget);
|
||||
void endModalSession(QWindow *widget);
|
||||
void cancelWaitForMoreEvents();
|
||||
void cleanupModalSessions();
|
||||
void ensureNSAppInitialized();
|
||||
|
||||
MacSocketHash macSockets;
|
||||
QList<void *> queuedUserInputEvents; // NSEvent *
|
||||
@ -194,15 +192,15 @@ public:
|
||||
CFRunLoopObserverRef firstTimeObserver;
|
||||
QAtomicInt serialNumber;
|
||||
int lastSerial;
|
||||
static bool interrupt;
|
||||
private:
|
||||
bool interrupt;
|
||||
|
||||
static Boolean postedEventSourceEqualCallback(const void *info1, const void *info2);
|
||||
static void postedEventsSourcePerformCallback(void *info);
|
||||
static void activateTimer(CFRunLoopTimerRef, void *info);
|
||||
static void waitingObserverCallback(CFRunLoopObserverRef observer,
|
||||
CFRunLoopActivity activity, void *info);
|
||||
static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
|
||||
friend void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents);
|
||||
void processPostedEvents();
|
||||
};
|
||||
|
||||
class QtCocoaInterruptDispatcher : public QObject
|
||||
|
@ -111,20 +111,13 @@ static inline CFRunLoopRef mainRunLoop()
|
||||
/* timer call back */
|
||||
void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info)
|
||||
{
|
||||
int timerID =
|
||||
#ifdef Q_OS_MAC64
|
||||
qint64(info);
|
||||
#else
|
||||
int(info);
|
||||
#endif
|
||||
|
||||
MacTimerInfo *tmr;
|
||||
tmr = macTimerHash.value(timerID);
|
||||
MacTimerInfo *tmr = static_cast<MacTimerInfo *>(info);
|
||||
QCocoaEventDispatcherPrivate *d = tmr->d_ptr;
|
||||
int timerID = tmr->id;
|
||||
if (tmr == 0 || tmr->pending == true)
|
||||
return; // Can't send another timer event if it's pending.
|
||||
|
||||
|
||||
if (blockSendPostedEvents) {
|
||||
if (d->blockSendPostedEvents) {
|
||||
QCoreApplication::postEvent(tmr->obj, new QTimerEvent(tmr->id));
|
||||
} else {
|
||||
tmr->pending = true;
|
||||
@ -132,7 +125,7 @@ void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info)
|
||||
|
||||
QCoreApplication::sendSpontaneousEvent(tmr->obj, &e);
|
||||
// Get the value again in case the timer gets unregistered during the sendEvent.
|
||||
tmr = macTimerHash.value(timerID);
|
||||
tmr = d->macTimerHash.value(timerID);
|
||||
if (tmr != 0)
|
||||
tmr->pending = false;
|
||||
}
|
||||
@ -152,6 +145,7 @@ void QCocoaEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerTy
|
||||
#endif
|
||||
|
||||
MacTimerInfo *t = new MacTimerInfo();
|
||||
t->d_ptr = d_func();
|
||||
t->id = timerId;
|
||||
t->interval = interval;
|
||||
t->timerType = timerType;
|
||||
@ -162,8 +156,8 @@ void QCocoaEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerTy
|
||||
CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent();
|
||||
CFTimeInterval cfinterval = qMax(CFTimeInterval(interval) / 1000, 0.0000001);
|
||||
fireDate += cfinterval;
|
||||
QCocoaEventDispatcherPrivate::macTimerHash.insert(timerId, t);
|
||||
CFRunLoopTimerContext info = { 0, (void *)timerId, 0, 0, 0 };
|
||||
t->d_ptr->macTimerHash.insert(timerId, t);
|
||||
CFRunLoopTimerContext info = { 0, (void *)t, 0, 0, 0 };
|
||||
t->runLoopTimer = CFRunLoopTimerCreate(0, fireDate, cfinterval, 0, 0,
|
||||
QCocoaEventDispatcherPrivate::activateTimer, &info);
|
||||
if (t->runLoopTimer == 0) {
|
||||
@ -186,7 +180,7 @@ bool QCocoaEventDispatcher::unregisterTimer(int identifier)
|
||||
if (identifier <= 0)
|
||||
return false; // not init'd or invalid timer
|
||||
|
||||
MacTimerInfo *timerInfo = QCocoaEventDispatcherPrivate::macTimerHash.take(identifier);
|
||||
MacTimerInfo *timerInfo = d_func()->macTimerHash.take(identifier);
|
||||
if (timerInfo == 0)
|
||||
return false;
|
||||
|
||||
@ -209,8 +203,9 @@ bool QCocoaEventDispatcher::unregisterTimers(QObject *obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
|
||||
while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
|
||||
Q_D(QCocoaEventDispatcher);
|
||||
MacTimerHash::iterator it = d->macTimerHash.begin();
|
||||
while (it != d->macTimerHash.end()) {
|
||||
MacTimerInfo *timerInfo = it.value();
|
||||
if (timerInfo->obj != obj) {
|
||||
++it;
|
||||
@ -218,7 +213,7 @@ bool QCocoaEventDispatcher::unregisterTimers(QObject *obj)
|
||||
CFRunLoopTimerInvalidate(timerInfo->runLoopTimer);
|
||||
CFRelease(timerInfo->runLoopTimer);
|
||||
delete timerInfo;
|
||||
it = QCocoaEventDispatcherPrivate::macTimerHash.erase(it);
|
||||
it = d->macTimerHash.erase(it);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -234,8 +229,9 @@ QCocoaEventDispatcher::registeredTimers(QObject *object) const
|
||||
|
||||
QList<TimerInfo> list;
|
||||
|
||||
MacTimerHash::const_iterator it = QCocoaEventDispatcherPrivate::macTimerHash.constBegin();
|
||||
while (it != QCocoaEventDispatcherPrivate::macTimerHash.constEnd()) {
|
||||
Q_D(const QCocoaEventDispatcher);
|
||||
MacTimerHash::const_iterator it = d->macTimerHash.constBegin();
|
||||
while (it != d->macTimerHash.constEnd()) {
|
||||
MacTimerInfo *t = it.value();
|
||||
if (t->obj == object)
|
||||
list << TimerInfo(t->id, t->interval, t->timerType);
|
||||
@ -689,16 +685,6 @@ void QCocoaEventDispatcher::wakeUp()
|
||||
/*****************************************************************************
|
||||
QEventDispatcherMac Implementation
|
||||
*****************************************************************************/
|
||||
MacTimerHash QCocoaEventDispatcherPrivate::macTimerHash;
|
||||
bool QCocoaEventDispatcherPrivate::blockSendPostedEvents = false;
|
||||
bool QCocoaEventDispatcherPrivate::interrupt = false;
|
||||
|
||||
|
||||
QStack<QCocoaModalSessionInfo> QCocoaEventDispatcherPrivate::cocoaModalSessionStack;
|
||||
bool QCocoaEventDispatcherPrivate::currentExecIsNSAppRun = false;
|
||||
bool QCocoaEventDispatcherPrivate::nsAppRunCalledByQt = false;
|
||||
bool QCocoaEventDispatcherPrivate::cleanupModalSessionsNeeded = false;
|
||||
NSModalSession QCocoaEventDispatcherPrivate::currentModalSessionCached = 0;
|
||||
|
||||
void QCocoaEventDispatcherPrivate::ensureNSAppInitialized()
|
||||
{
|
||||
@ -896,6 +882,12 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
|
||||
}
|
||||
|
||||
QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
|
||||
: blockSendPostedEvents(false),
|
||||
currentExecIsNSAppRun(false),
|
||||
nsAppRunCalledByQt(false),
|
||||
cleanupModalSessionsNeeded(false),
|
||||
currentModalSessionCached(0),
|
||||
interrupt(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -952,38 +944,38 @@ Boolean QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback(const void
|
||||
return info1 == info2;
|
||||
}
|
||||
|
||||
void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents)
|
||||
void QCocoaEventDispatcherPrivate::processPostedEvents()
|
||||
{
|
||||
if (blockSendPostedEvents) {
|
||||
// We're told to not send posted events (because the event dispatcher
|
||||
// is currently working on setting up the correct session to run). But
|
||||
// we still need to make sure that we don't fall asleep until pending events
|
||||
// are sendt, so we just signal this need, and return:
|
||||
CFRunLoopSourceSignal(d->postedEventsSource);
|
||||
CFRunLoopSourceSignal(postedEventsSource);
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->cleanupModalSessionsNeeded)
|
||||
d->cleanupModalSessions();
|
||||
if (cleanupModalSessionsNeeded)
|
||||
cleanupModalSessions();
|
||||
|
||||
if (d->interrupt) {
|
||||
if (d->currentExecIsNSAppRun) {
|
||||
if (interrupt) {
|
||||
if (currentExecIsNSAppRun) {
|
||||
// The event dispatcher has been interrupted. But since
|
||||
// [NSApplication run] is running the event loop, we
|
||||
// delayed stopping it until now (to let cocoa process
|
||||
// pending cocoa events first).
|
||||
if (d->currentModalSessionCached)
|
||||
d->temporarilyStopAllModalSessions();
|
||||
if (currentModalSessionCached)
|
||||
temporarilyStopAllModalSessions();
|
||||
[NSApp stop:NSApp];
|
||||
d->cancelWaitForMoreEvents();
|
||||
cancelWaitForMoreEvents();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int serial = d->serialNumber.load();
|
||||
if (!d->threadData->canWait || (serial != d->lastSerial)) {
|
||||
d->lastSerial = serial;
|
||||
QWindowSystemInterface::sendWindowSystemEvents(d->q_func(), QEventLoop::AllEvents);
|
||||
int serial = serialNumber.load();
|
||||
if (!threadData->canWait || (serial != lastSerial)) {
|
||||
lastSerial = serial;
|
||||
QWindowSystemInterface::sendWindowSystemEvents(q_func(), QEventLoop::AllEvents);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1013,12 +1005,12 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
|
||||
forEventClass:kInternetEventClass andEventID:kAEGetURL];
|
||||
*/
|
||||
|
||||
processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
|
||||
static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents();
|
||||
}
|
||||
|
||||
void QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback(void *info)
|
||||
{
|
||||
processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
|
||||
static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents();
|
||||
}
|
||||
|
||||
void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
|
||||
@ -1054,8 +1046,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher()
|
||||
{
|
||||
Q_D(QCocoaEventDispatcher);
|
||||
//timer cleanup
|
||||
MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
|
||||
while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
|
||||
MacTimerHash::iterator it = d->macTimerHash.begin();
|
||||
while (it != d->macTimerHash.end()) {
|
||||
MacTimerInfo *t = it.value();
|
||||
if (t->runLoopTimer) {
|
||||
CFRunLoopTimerInvalidate(t->runLoopTimer);
|
||||
@ -1064,7 +1056,7 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher()
|
||||
delete t;
|
||||
++it;
|
||||
}
|
||||
QCocoaEventDispatcherPrivate::macTimerHash.clear();
|
||||
d->macTimerHash.clear();
|
||||
|
||||
// Remove CFSockets from the runloop.
|
||||
for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) {
|
||||
|
Loading…
Reference in New Issue
Block a user