summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm33
-rw-r--r--src/gui/kernel/qeventdispatcher_mac_p.h1
-rw-r--r--tests/auto/qcoreapplication/tst_qcoreapplication.cpp45
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);
}