From 0f8ad242fb9c82e542ace1d2595038edf87f7b3d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 20 Jan 2012 08:57:17 +0100 Subject: [PATCH] Add a virtual sendPostedEvents() to QEventDispatcherWin32. Reimplement this in QWindowGuiEventDispatcher to send both Qt posted events and queued QPA window system events. We need to do this at a well defined place, instead of sending events outside of the eventloop from the Windows proc. This fixes various hangs for example in tst_qinputdialog, which used a 0-timer to close a dialog. Change-Id: I64e0b8f1209fb434059a7fa667ed585902c19db4 Initial-patch-by: bhughes Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qeventdispatcher_win.cpp | 10 ++++++++-- src/corelib/kernel/qeventdispatcher_win_p.h | 1 + src/plugins/platforms/windows/qwindowscontext.cpp | 11 ++--------- .../platforms/windows/qwindowsguieventdispatcher.cpp | 7 +++++++ .../platforms/windows/qwindowsguieventdispatcher.h | 1 + 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 3ade11ca60..3ad61fee7c 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -408,7 +408,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA const int localSerialNumber = d->serialNumber.load(); if (localSerialNumber != d->lastSerialNumber) { d->lastSerialNumber = localSerialNumber; - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); + q->sendPostedEvents(); } return 0; } else if (message == WM_TIMER) { @@ -761,7 +761,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) if (!seenWM_QT_SENDPOSTEDEVENTS && (flags & QEventLoop::EventLoopExec) == 0) { // when called "manually", always send posted events - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); + sendPostedEvents(); } if (needWM_QT_SENDPOSTEDEVENTS) @@ -1076,4 +1076,10 @@ bool QEventDispatcherWin32::event(QEvent *e) return QAbstractEventDispatcher::event(e); } +void QEventDispatcherWin32::sendPostedEvents() +{ + Q_D(QEventDispatcherWin32); + QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 833fcf13ac..524dbb4249 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -104,6 +104,7 @@ public: protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); + virtual void sendPostedEvents(); private: friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 5e101d1869..4f42f7fa3b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -747,18 +747,11 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR LRESULT result; const QtWindows::WindowsEventType et = windowsEventType(message, wParam); const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result); - const bool guiEventsQueued = QWindowSystemInterface::windowSystemEventsQueued(); if (QWindowsContext::verboseEvents > 1) if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) - qDebug("EVENT: hwd=%p %s msg=0x%x et=0x%x wp=%d at %d,%d handled=%d gui=%d", + qDebug("EVENT: hwd=%p %s msg=0x%x et=0x%x wp=%d at %d,%d handled=%d", hwnd, eventName, message, et, int(wParam), - GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled, guiEventsQueued); - if (guiEventsQueued) { - const QWindowsGuiEventDispatcher::DispatchContext dispatchContext = - QWindowsGuiEventDispatcher::currentDispatchContext(); - if (dispatchContext.first) - QWindowSystemInterface::sendWindowSystemEvents(dispatchContext.first, dispatchContext.second); - } + GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled); if (!handled) result = DefWindowProc(hwnd, message, wParam, lParam); return result; diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp index cd5d28317e..4dd409a2ab 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp @@ -97,6 +97,13 @@ bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags fl return rc; } +void QWindowsGuiEventDispatcher::sendPostedEvents() +{ + QWindowsGuiEventDispatcher::DispatchContext context = currentDispatchContext(); + Q_ASSERT(context.first != 0); + QWindowSystemInterface::sendWindowSystemEvents(context.first, context.second); +} + QWindowsGuiEventDispatcher::DispatchContext QWindowsGuiEventDispatcher::currentDispatchContext() { const DispatchContextStack &stack = *dispatchContextStack(); diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h index 8d2bc1997b..87a0c915ce 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h @@ -64,6 +64,7 @@ public: static const char *windowsMessageName(UINT msg); virtual bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags); + virtual void sendPostedEvents(); }; QT_END_NAMESPACE