diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-06 01:00:35 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-04-06 15:45:11 +0200 |
commit | 864048a8f5625b252bb2ac63812fd3edb7361343 (patch) | |
tree | 5c9339c80f7a1a6d0725031626fa5fcf1e2fbd19 /src/corelib/kernel | |
parent | 1c23d34ad4bdd67dec6d501d91087823dc9ea358 (diff) | |
parent | 4ee7adf59d13ada5bfaa4f0382e0bb70b66b8814 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Conflicts:
src/corelib/kernel/qeventdispatcher_win.cpp
Change-Id: I32db3f755577aefc15f757041367d6144f5e5c66
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 82 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win_p.h | 1 |
2 files changed, 50 insertions, 33 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index f2216d4113..e841919600 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -84,10 +84,8 @@ enum { WM_QT_ACTIVATENOTIFIERS = WM_USER + 2 }; -// WM_QT_SENDPOSTEDEVENTS message parameter enum { - WMWP_QT_TOFOREIGNLOOP = 0, - WMWP_QT_FROMWAKEUP + SendPostedEventsTimerId = ~1u }; class QEventDispatcherWin32Private; @@ -100,8 +98,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA QEventDispatcherWin32Private::QEventDispatcherWin32Private() : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), - getMessageHook(0), wakeUps(0), activateNotifiersPosted(false), - winEventNotifierActivatedEvent(NULL) + getMessageHook(0), sendPostedEventsTimerId(0), wakeUps(0), + activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL) { } @@ -129,6 +127,18 @@ void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId)); } +static inline UINT inputQueueMask() +{ + UINT result = QS_ALLEVENTS; + // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of + // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. +#if WINVER > 0x0601 + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) + result &= ~(QS_TOUCH | QS_POINTER); +#endif // WINVER > 0x0601 + return result; +} + LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) { if (message == WM_NCCREATE) @@ -240,47 +250,39 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA case WM_TIMER: Q_ASSERT(d != 0); - d->sendTimerEvent(wp); + if (wp == d->sendPostedEventsTimerId) + q->sendPostedEvents(); + else + d->sendTimerEvent(wp); return 0; case WM_QT_SENDPOSTEDEVENTS: Q_ASSERT(d != 0); // We send posted events manually, if the window procedure was invoked // by the foreign event loop (e.g. from the native modal dialog). - q->sendPostedEvents(); + // Skip sending, if the message queue is not empty. + // sendPostedEventsTimer will deliver posted events later. + static const UINT mask = inputQueueMask(); + if (HIWORD(GetQueueStatus(mask)) == 0) + q->sendPostedEvents(); return 0; } // switch (message) return DefWindowProc(hwnd, message, wp, lp); } -static inline UINT inputQueueMask() -{ - UINT result = QS_ALLEVENTS; - // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of - // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. -#if WINVER > 0x0601 - if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) - result &= ~(QS_TOUCH | QS_POINTER); -#endif // WINVER > 0x0601 - return result; -} - LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); Q_ASSERT(q != 0); QEventDispatcherWin32Private *d = q->d_func(); MSG *msg = reinterpret_cast<MSG *>(lp); - static const UINT mask = inputQueueMask(); - - if (HIWORD(GetQueueStatus(mask)) == 0 && wp == PM_REMOVE) { - // Allow posting WM_QT_SENDPOSTEDEVENTS message. - d->wakeUps.storeRelaxed(0); - if (!(msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS)) { - PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, - WMWP_QT_TOFOREIGNLOOP, 0); - } + + if (msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS + && wp == PM_REMOVE && d->sendPostedEventsTimerId == 0) { + // Start a timer to deliver posted events when the message queue is emptied. + d->sendPostedEventsTimerId = SetTimer(d->internalHwnd, SendPostedEventsTimerId, + USER_TIMER_MINIMUM, NULL); } return d->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0; } @@ -571,12 +573,15 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } if (haveMessage) { if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) { - // Set result to 'true', if the message was sent by wakeUp(). - if (msg.wParam == WMWP_QT_FROMWAKEUP) - retVal = true; + // Set result to 'true' because the message was sent by wakeUp(). + retVal = true; continue; } if (msg.message == WM_TIMER) { + // Skip timer event intended for use inside foreign loop. + if (d->internalHwnd == msg.hwnd && msg.wParam == d->sendPostedEventsTimerId) + continue; + // avoid live-lock by keeping track of the timers we've already sent bool found = false; for (int i = 0; !found && i < processedTimers.count(); ++i) { @@ -968,8 +973,7 @@ void QEventDispatcherWin32::wakeUp() Q_D(QEventDispatcherWin32); if (d->internalHwnd && d->wakeUps.testAndSetAcquire(0, 1)) { // post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending - if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, - WMWP_QT_FROMWAKEUP, 0)) + if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0)) qErrnoWarning("QEventDispatcherWin32::wakeUp: Failed to post a message"); } } @@ -1015,6 +1019,10 @@ void QEventDispatcherWin32::closingDown() if (d->getMessageHook) UnhookWindowsHookEx(d->getMessageHook); d->getMessageHook = 0; + + if (d->sendPostedEventsTimerId != 0) + KillTimer(d->internalHwnd, d->sendPostedEventsTimerId); + d->sendPostedEventsTimerId = 0; } bool QEventDispatcherWin32::event(QEvent *e) @@ -1056,6 +1064,14 @@ bool QEventDispatcherWin32::event(QEvent *e) void QEventDispatcherWin32::sendPostedEvents() { Q_D(QEventDispatcherWin32); + + if (d->sendPostedEventsTimerId != 0) + KillTimer(d->internalHwnd, d->sendPostedEventsTimerId); + d->sendPostedEventsTimerId = 0; + + // Allow posting WM_QT_SENDPOSTEDEVENTS message. + d->wakeUps.storeRelaxed(0); + QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData.loadRelaxed()); } diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a482c8b7db..dbb30ab568 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -171,6 +171,7 @@ public: HHOOK getMessageHook; // for controlling when to send posted events + UINT_PTR sendPostedEventsTimerId; QAtomicInt wakeUps; // timers |