diff options
5 files changed, 55 insertions, 40 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 623765c8de..9942bed750 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -411,7 +411,7 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t) } else if (t->fastTimerId != 0) { timeKillEvent(t->fastTimerId); QCoreApplicationPrivate::removePostedTimerEvent(t->dispatcher, t->timerId); - } else if (internalHwnd) { + } else { KillTimer(internalHwnd, t->timerId); } t->timerId = -1; @@ -463,12 +463,16 @@ void QEventDispatcherWin32Private::postActivateEventNotifiers() QCoreApplication::postEvent(q, new QEvent(QEvent::WinEventAct)); } -void QEventDispatcherWin32::createInternalHwnd() +QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) + : QEventDispatcherWin32(*new QEventDispatcherWin32Private, parent) +{ +} + +QEventDispatcherWin32::QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent) + : QAbstractEventDispatcher(dd, parent) { Q_D(QEventDispatcherWin32); - if (d->internalHwnd) - return; d->internalHwnd = qt_create_internal_window(this); // setup GetMessage hook needed to drive our posted events @@ -478,21 +482,8 @@ void QEventDispatcherWin32::createInternalHwnd() qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %ls", errorCode, qUtf16Printable(qt_error_string(errorCode))); } - - // start all normal timers - for (int i = 0; i < d->timerVec.count(); ++i) - d->registerTimer(d->timerVec.at(i)); } -QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) - : QAbstractEventDispatcher(*new QEventDispatcherWin32Private, parent) -{ -} - -QEventDispatcherWin32::QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent) - : QAbstractEventDispatcher(dd, parent) -{ } - QEventDispatcherWin32::~QEventDispatcherWin32() { } @@ -517,11 +508,6 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherWin32); - if (!d->internalHwnd) { - createInternalHwnd(); - wakeUp(); // trigger a call to sendPostedEvents() - } - d->interrupt.storeRelaxed(false); emit awake(); @@ -642,8 +628,6 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) "same socket %d and type %s", sockfd, t[type]); } - createInternalHwnd(); - QSockNot *sn = new QSockNot; sn->obj = notifier; sn->fd = sockfd; @@ -752,8 +736,7 @@ void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerTy t->inTimerEvent = false; t->fastTimerId = 0; - if (d->internalHwnd) - d->registerTimer(t); + d->registerTimer(t); d->timerVec.append(t); // store in timer vector d->timerDict.insert(t->timerId, t); // store timers in dict @@ -849,8 +832,6 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier) if (d->winEventNotifierList.contains(notifier)) return true; - createInternalHwnd(); - d->winEventNotifierList.append(notifier); d->winEventNotifierListModified = true; @@ -933,10 +914,7 @@ int QEventDispatcherWin32::remainingTime(int timerId) if (t && t->timerId == timerId) { // timer found, return time to wait - if (d->internalHwnd) - return t->timeout > currentTime ? t->timeout - currentTime : 0; - else - return t->interval; + return t->timeout > currentTime ? t->timeout - currentTime : 0; } } @@ -950,7 +928,7 @@ int QEventDispatcherWin32::remainingTime(int timerId) void QEventDispatcherWin32::wakeUp() { Q_D(QEventDispatcherWin32); - if (d->internalHwnd && d->wakeUps.testAndSetRelaxed(0, 1)) { + if (d->wakeUps.testAndSetRelaxed(0, 1)) { // post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0)) qErrnoWarning("QEventDispatcherWin32::wakeUp: Failed to post a message"); @@ -1056,9 +1034,7 @@ void QEventDispatcherWin32::sendPostedEvents() HWND QEventDispatcherWin32::internalHwnd() { - Q_D(QEventDispatcherWin32); - createInternalHwnd(); - return d->internalHwnd; + return d_func()->internalHwnd; } QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index acad28530e..29cd960d40 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -72,9 +72,6 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher Q_OBJECT Q_DECLARE_PRIVATE(QEventDispatcherWin32) -protected: - void createInternalHwnd(); - public: explicit QEventDispatcherWin32(QObject *parent = 0); ~QEventDispatcherWin32(); diff --git a/src/gui/platform/windows/qwindowsguieventdispatcher.cpp b/src/gui/platform/windows/qwindowsguieventdispatcher.cpp index ca4bc4091b..999e119681 100644 --- a/src/gui/platform/windows/qwindowsguieventdispatcher.cpp +++ b/src/gui/platform/windows/qwindowsguieventdispatcher.cpp @@ -63,7 +63,6 @@ QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) : QEventDispatcherWin32(parent) { setObjectName(QStringLiteral("QWindowsGuiEventDispatcher")); - createInternalHwnd(); // QTBUG-40881: Do not delay registering timers, etc. for QtMfc. } bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 8567d8c3b9..b9772f6922 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -36,6 +36,10 @@ #include <private/qeventloop_p.h> #include <private/qthread_p.h> +#ifdef Q_OS_WIN +#include <QtCore/qt_windows.h> +#endif + typedef QCoreApplication TestApplication; class EventSpy : public QObject @@ -617,6 +621,42 @@ void tst_QCoreApplication::processEventsAlwaysSendsPostedEvents() } while (t.elapsed() < 1000); } +#ifdef Q_OS_WIN +void tst_QCoreApplication::sendPostedEventsInNativeLoop() +{ + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + TestApplication app(argc, argv); + + bool signalReceived = false; + + // Post a message to the queue + QMetaObject::invokeMethod(this, [&signalReceived]() { + signalReceived = true; + }, Qt::QueuedConnection); + + QElapsedTimer elapsedTimer; + elapsedTimer.start(); + + // Exec own message loop + MSG msg; + forever { + if (elapsedTimer.hasExpired(3000) || signalReceived) + break; + + if (!::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + QThread::msleep(100); + continue; + } + + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + QVERIFY(signalReceived); +} +#endif // Q_OS_WIN + class QuitBlocker : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index b8475fd8c2..655a879afa 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -49,6 +49,9 @@ private slots: void applicationPid(); void globalPostedEventsCount(); void processEventsAlwaysSendsPostedEvents(); +#ifdef Q_OS_WIN + void sendPostedEventsInNativeLoop(); +#endif void quit(); void reexec(); void execAfterExit(); |