diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index a3d00faf31f92525df2ef220cc43a9ad47587235..62e6e9f051fc7f1392db0e945c8a724245d200e3 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -434,9 +434,10 @@ static inline UINT inputTimerMask() LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { + QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); + Q_ASSERT(q != 0); + if (wp == PM_REMOVE) { - QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); - Q_ASSERT(q != 0); if (q) { MSG *msg = (MSG *) lp; QEventDispatcherWin32Private *d = q->d_func(); @@ -472,7 +473,7 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) #ifdef Q_OS_WINCE return 0; #else - return CallNextHookEx(0, code, wp, lp); + return q->d_func()->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0; #endif } @@ -643,15 +644,7 @@ void QEventDispatcherWin32::createInternalHwnd() return; d->internalHwnd = qt_create_internal_window(this); -#ifndef Q_OS_WINCE - // setup GetMessage hook needed to drive our posted events - d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); - if (!d->getMessageHook) { - int errorCode = GetLastError(); - qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s", - errorCode, qPrintable(qt_error_string(errorCode))); - } -#endif + installMessageHook(); // register all socket notifiers QList<int> sockets = (d->sn_read.keys().toSet() @@ -665,6 +658,35 @@ void QEventDispatcherWin32::createInternalHwnd() d->registerTimer(d->timerVec.at(i)); } +void QEventDispatcherWin32::installMessageHook() +{ + Q_D(QEventDispatcherWin32); + + if (d->getMessageHook) + return; + +#ifndef Q_OS_WINCE + // setup GetMessage hook needed to drive our posted events + d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); + if (!d->getMessageHook) { + int errorCode = GetLastError(); + qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s", + errorCode, qPrintable(qt_error_string(errorCode))); + } +#endif +} + +void QEventDispatcherWin32::uninstallMessageHook() +{ + Q_D(QEventDispatcherWin32); + +#ifndef Q_OS_WINCE + if (d->getMessageHook) + UnhookWindowsHookEx(d->getMessageHook); +#endif + d->getMessageHook = 0; +} + QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherWin32Private, parent) { @@ -750,10 +772,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } if (haveMessage) { -#ifdef Q_OS_WINCE // WinCE doesn't support hooks at all, so we have to call this by hand :( - (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg); -#endif + if (!d->getMessageHook) + (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg); if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) { if (seenWM_QT_SENDPOSTEDEVENTS) { @@ -1134,11 +1155,7 @@ void QEventDispatcherWin32::closingDown() d->timerVec.clear(); d->timerDict.clear(); -#ifndef Q_OS_WINCE - if (d->getMessageHook) - UnhookWindowsHookEx(d->getMessageHook); - d->getMessageHook = 0; -#endif + uninstallMessageHook(); } bool QEventDispatcherWin32::event(QEvent *e) diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 369c2766150702b4d307ae696567ba51e1d110a2..a68f6cfa28993dcfab9a154b10c5735e7bc32db8 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -67,6 +67,8 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher protected: void createInternalHwnd(); + void installMessageHook(); + void uninstallMessageHook(); public: explicit QEventDispatcherWin32(QObject *parent = 0); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 142362a0653dafeeb45b3500e8381509263dfdd6..351f94be2bfe1bc9dd594a3ae133ad2a3bfadcaf 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -39,6 +39,7 @@ #include "qwindowsdirect2dwindow.h" #include "qwindowscontext.h" +#include "qwindowsguieventdispatcher.h" #include <qplatformdefs.h> #include <QtCore/QCoreApplication> @@ -47,6 +48,16 @@ QT_BEGIN_NAMESPACE +class QWindowsDirect2DEventDispatcher : public QWindowsGuiEventDispatcher +{ +public: + QWindowsDirect2DEventDispatcher(QObject *parent = 0) + : QWindowsGuiEventDispatcher(parent) + { + uninstallMessageHook(); // ### Workaround for QTBUG-42428 + } +}; + class QWindowsDirect2DIntegrationPrivate { public: @@ -237,6 +248,11 @@ QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(Q return new QWindowsDirect2DBackingStore(window); } +QAbstractEventDispatcher *QWindowsDirect2DIntegration::createEventDispatcher() const +{ + return new QWindowsDirect2DEventDispatcher; +} + QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const { return &d->m_d2dContext; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h index b4104643721eb6c9610f79357e819cefef8f3961..c72b22a6e82364855aa3ee95d02117ea5b01f402 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h @@ -56,6 +56,7 @@ public: QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; QWindowsDirect2DContext *direct2DContext() const;