diff options
-rw-r--r-- | src/gui/kernel/qeventdispatcher_mac.mm | 33 | ||||
-rw-r--r-- | src/gui/kernel/qeventdispatcher_mac_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qcoreapplication/tst_qcoreapplication.cpp | 45 |
3 files changed, 64 insertions, 15 deletions
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index f05d56f..7a3af86 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -909,6 +909,22 @@ QEventDispatcherMac::QEventDispatcherMac(QObject *parent) QEventDispatcherMacPrivate::waitingObserverCallback, &observerContext); CFRunLoopAddObserver(mainRunLoop(), d->waitingObserver, kCFRunLoopCommonModes); + + /* The first cycle in the loop adds the source and the events of the source + are not processed. + We use an observer to process the posted events for the first + execution of the loop. */ + CFRunLoopObserverContext firstTimeObserverContext; + bzero(&firstTimeObserverContext, sizeof(CFRunLoopObserverContext)); + firstTimeObserverContext.info = d; + CFRunLoopObserverRef firstTimeObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, + kCFRunLoopEntry, + /* repeats = */ false, + 0, + QEventDispatcherMacPrivate::firstLoopEntry, + &firstTimeObserverContext); + CFRunLoopAddObserver(mainRunLoop(), firstTimeObserver, kCFRunLoopCommonModes); + CFRelease(firstTimeObserver); } void QEventDispatcherMacPrivate::waitingObserverCallback(CFRunLoopObserverRef, @@ -925,9 +941,8 @@ Boolean QEventDispatcherMacPrivate::postedEventSourceEqualCallback(const void *i return info1 == info2; } -void QEventDispatcherMacPrivate::postedEventsSourcePerformCallback(void *info) +inline static void processPostedEvents(QEventDispatcherMacPrivate *const d, const bool blockSendPostedEvents) { - QEventDispatcherMacPrivate *d = static_cast<QEventDispatcherMacPrivate *>(info); if (blockSendPostedEvents) { CFRunLoopSourceSignal(d->postedEventsSource); } else { @@ -938,6 +953,20 @@ void QEventDispatcherMacPrivate::postedEventsSourcePerformCallback(void *info) } } +void QEventDispatcherMacPrivate::firstLoopEntry(CFRunLoopObserverRef ref, + CFRunLoopActivity activity, + void *info) +{ + Q_UNUSED(ref); + Q_UNUSED(activity); + processPostedEvents(static_cast<QEventDispatcherMacPrivate *>(info), blockSendPostedEvents); +} + +void QEventDispatcherMacPrivate::postedEventsSourcePerformCallback(void *info) +{ + processPostedEvents(static_cast<QEventDispatcherMacPrivate *>(info), blockSendPostedEvents); +} + void QEventDispatcherMac::interrupt() { Q_D(QEventDispatcherMac); diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/gui/kernel/qeventdispatcher_mac_p.h index e94d98a..15bc6f8 100644 --- a/src/gui/kernel/qeventdispatcher_mac_p.h +++ b/src/gui/kernel/qeventdispatcher_mac_p.h @@ -196,6 +196,7 @@ private: static void activateTimer(CFRunLoopTimerRef, void *info); static void waitingObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info); + static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info); }; #ifdef QT_MAC_USE_COCOA diff --git a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp index 9ddd54a..4b38044 100644 --- a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp @@ -47,6 +47,7 @@ class tst_QCoreApplication: public QObject { Q_OBJECT private slots: + void sendEventsOnProcessEvents(); // this must be the first test void getSetCheck(); void qAppName(); void argc(); @@ -59,6 +60,35 @@ private slots: void globalPostedEventsCount(); }; +class EventSpy : public QObject +{ + Q_OBJECT + +public: + QList<int> recordedEvents; + bool eventFilter(QObject *, QEvent *event) + { + recordedEvents.append(event->type()); + return false; + } +}; + +void tst_QCoreApplication::sendEventsOnProcessEvents() +{ + int argc = 1; + char *argv[] = { "tst_qcoreapplication" }; + QCoreApplication app(argc, argv); + + EventSpy spy; + app.installEventFilter(&spy); + + QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + QList<int> expected; + expected << QEvent::User + 1; + QCOMPARE(expected, spy.recordedEvents); +} + void tst_QCoreApplication::getSetCheck() { // do not crash @@ -114,19 +144,6 @@ void tst_QCoreApplication::argc() } } -class EventSpy : public QObject -{ - Q_OBJECT - -public: - QList<int> recordedEvents; - bool eventFilter(QObject *, QEvent *event) - { - recordedEvents.append(event->type()); - return false; - } -}; - class EventGenerator : public QObject { Q_OBJECT @@ -394,6 +411,8 @@ public: } case QEvent::User + 1: break; + default: + break; } return QObject::event(event); } |