summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowscontext.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-03-19 15:09:19 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-04-20 21:37:27 +0000
commita0a22037cdacbf51a2db560ff902a5a341561b15 (patch)
treeba8be2c7446257a02b282afab98b44b0f6799ccf /src/plugins/platforms/windows/qwindowscontext.cpp
parentab6cc41968ec6eedd16e4305cf38ef937b2a8d56 (diff)
Windows QPA: Fix duplicate/missing native events
Add utility functions to QWindowsContext input messages sent to native event filters (event dispatcher and window system interface). Do not send input and similar events to the event dispatcher since QEventDispatcherWin32::processEvents() also sends them. Note though that QEventDispatcherWin32 does not receive all windows messages. In QWindowsKeyMapper, send the WM_CHAR/WM_IMECHAR events from where the messages are removed. Task-number: QTBUG-67095 Change-Id: I5f61294fcb3aee7e0eacd840a2010d128cd02a5d Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/plugins/platforms/windows/qwindowscontext.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp74
1 files changed, 59 insertions, 15 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 072012064f..98a4b261fd 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -246,14 +246,12 @@ struct QWindowsContextPrivate {
QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
#endif
const HRESULT m_oleInitializeResult;
- const QByteArray m_eventType;
QWindow *m_lastActiveWindow = nullptr;
bool m_asyncExpose = false;
};
QWindowsContextPrivate::QWindowsContextPrivate()
: m_oleInitializeResult(OleInitialize(NULL))
- , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
{
QWindowsContext::user32dll.init();
QWindowsContext::shcoredll.init();
@@ -866,6 +864,33 @@ static bool shouldHaveNonClientDpiScaling(const QWindow *window)
;
}
+static inline bool isInputMessage(UINT m)
+{
+ switch (m) {
+ case WM_IME_STARTCOMPOSITION:
+ case WM_IME_ENDCOMPOSITION:
+ case WM_IME_COMPOSITION:
+ case WM_TOUCH:
+ case WM_MOUSEHOVER:
+ case WM_MOUSELEAVE:
+ case WM_NCHITTEST:
+ case WM_NCMOUSEHOVER:
+ case WM_NCMOUSELEAVE:
+ case WM_SIZING:
+ case WM_MOVING:
+ case WM_SYSCOMMAND:
+ case WM_COMMAND:
+ case WM_DWMNCRENDERINGCHANGED:
+ case WM_PAINT:
+ return true;
+ default:
+ break;
+ }
+ return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
+ || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
+ || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
+}
+
/*!
\brief Main windows procedure registered for windows.
@@ -901,21 +926,14 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QWindowsWindow *platformWindow = findPlatformWindow(hwnd);
*platformWindowPtr = platformWindow;
- // Run the native event filters.
- long filterResult = 0;
- QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- if (dispatcher && dispatcher->filterNativeEvent(d->m_eventType, &msg, &filterResult)) {
- *result = LRESULT(filterResult);
+ // Run the native event filters. QTBUG-67095: Exclude input messages which are sent
+ // by QEventDispatcherWin32::processEvents()
+ if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
+ return true;
+
+ if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
return true;
- }
- if (platformWindow) {
- filterResult = 0;
- if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) {
- *result = LRESULT(filterResult);
- return true;
- }
- }
if (et & QtWindows::InputMethodEventFlag) {
QWindowsInputContext *windowsInputContext = ::windowsInputContext();
// Disable IME assuming this is a special implementation hooking into keyboard input.
@@ -1393,4 +1411,30 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
return result;
}
+
+static inline QByteArray nativeEventType() { return QByteArrayLiteral("windows_generic_MSG"); }
+
+// Send to QAbstractEventDispatcher
+bool QWindowsContext::filterNativeEvent(MSG *msg, LRESULT *result)
+{
+ QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
+ long filterResult = 0;
+ if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
+ *result = LRESULT(filterResult);
+ return true;
+ }
+ return false;
+}
+
+// Send to QWindowSystemInterface
+bool QWindowsContext::filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result)
+{
+ long filterResult = 0;
+ if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), &msg, &filterResult)) {
+ *result = LRESULT(filterResult);
+ return true;
+ }
+ return false;
+}
+
QT_END_NAMESPACE