summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2020-09-15 18:06:40 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2020-09-16 19:26:02 +0300
commit2180b4c84aacfcfcc2bc5a255a4a51be65e38551 (patch)
treeace021b3f6dd6496b062c5bc4f32fc57fdddaf52
parentada01394dd02f7373bb2104fd16e6662a1873126 (diff)
QEventDispatcherWin32: create internal window on construction
When QCoreApplication object is instantiated, creation of the internal message window is delayed until QEventDispatcherWin32::processEvents() is called or socket/event notifier is registered. But, if the user uses a native event loop, posted events are not delivered and timers do not work. This problem was fixed in a4ac4b326318ed9034466305222280ed8d1651b5 for QWindowsGuiEventDispatcher in the same way. So, the risk of regression is minimal. Change-Id: I7bbb721d96046f64d21a7b0e553e46798b37189c Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp48
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h3
-rw-r--r--src/gui/platform/windows/qwindowsguieventdispatcher.cpp1
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp40
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h3
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();