diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-07 01:00:12 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-04-08 20:11:39 +0200 |
commit | 8823bb8d306d78dd6a2e121a708dc607beff58c8 (patch) | |
tree | 5ca170aa36aa1381b0f31dae6709fd2ce68be344 /src/corelib/kernel/qeventdispatcher_win.cpp | |
parent | 5422fb79486a1818d6355d75f019fe63120a43d0 (diff) | |
parent | 14c55e29794b4f1d6e010fdf7082ef55cbf8f275 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
examples/opengl/doc/src/cube.qdoc
src/corelib/global/qlibraryinfo.cpp
src/corelib/text/qbytearray_p.h
src/corelib/text/qlocale_data_p.h
src/corelib/time/qhijricalendar_data_p.h
src/corelib/time/qjalalicalendar_data_p.h
src/corelib/time/qromancalendar_data_p.h
src/network/ssl/qsslcertificate.h
src/widgets/doc/src/graphicsview.qdoc
src/widgets/widgets/qcombobox.cpp
src/widgets/widgets/qcombobox.h
tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro
tests/manual/diaglib/debugproxystyle.cpp
tests/manual/diaglib/qwidgetdump.cpp
tests/manual/diaglib/qwindowdump.cpp
tests/manual/diaglib/textdump.cpp
util/locale_database/cldr2qlocalexml.py
util/locale_database/qlocalexml.py
util/locale_database/qlocalexml2cpp.py
Resolution of util/locale_database/ are based on:
https://codereview.qt-project.org/c/qt/qtbase/+/294250
and src/corelib/{text,time}/*_data_p.h were then regenerated by
running those scripts.
Updated CMakeLists.txt in each of
tests/auto/corelib/serialization/qcborstreamreader/
tests/auto/corelib/serialization/qcborvalue/
tests/auto/gui/kernel/
and generated new ones in each of
tests/auto/gui/kernel/qaddpostroutine/
tests/auto/gui/kernel/qhighdpiscaling/
tests/libfuzzer/corelib/text/qregularexpression/optimize/
tests/libfuzzer/gui/painting/qcolorspace/fromiccprofile/
tests/libfuzzer/gui/text/qtextdocument/sethtml/
tests/libfuzzer/gui/text/qtextdocument/setmarkdown/
tests/libfuzzer/gui/text/qtextlayout/beginlayout/
by running util/cmake/pro2cmake.py on their changed .pro files.
Changed target name in
tests/auto/gui/kernel/qaction/qaction.pro
tests/auto/gui/kernel/qaction/qactiongroup.pro
tests/auto/gui/kernel/qshortcut/qshortcut.pro
to ensure unique target names for CMake
Changed tst_QComboBox::currentIndex to not test the
currentIndexChanged(QString), as that one does not exist in Qt 6
anymore.
Change-Id: I9a85705484855ae1dc874a81f49d27a50b0dcff7
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_win.cpp')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 82 |
1 files changed, 49 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()); } |