From 226d196ab0edb04e98c12d3f7ff091bc021425e3 Mon Sep 17 00:00:00 2001 From: Romain Pokrzywka Date: Wed, 22 Aug 2018 21:54:13 -0500 Subject: Windows QPA: Improve Pointer Pen events translation Compute QPointF hi-res screen coordinates based on the HIMETRIC values contained in the native message. This gives the same high-precision screen coordinates as what the old WinTab handler supported. Add the possibility to not synthesize mouse events if the platform plugin option DontPassOsMouseEventsSynthesizedFromTouch is set, just like we do for finger touches. This makes it possible to have clean Pen events without mouse duplicates for an application that handles both input types in parallel. Add raw event logging when the platform verbose level is >1. Change-Id: Ibf68b6275400388a76f8d5c573eed8f4b9bf4e9d Reviewed-by: Andre de la Rocha Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 4 ++- src/plugins/platforms/windows/qwindowscontext.h | 2 ++ .../platforms/windows/qwindowspointerhandler.cpp | 30 +++++++++++++++++----- 3 files changed, 29 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index e29e5b8187..0df6264bcb 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -197,6 +197,7 @@ void QWindowsUser32DLL::init() enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer"); getPointerType = (GetPointerType)library.resolve("GetPointerType"); getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo"); + getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects"); getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo"); getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo"); getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo"); @@ -212,7 +213,8 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::supportsPointerApi() { - return enableMouseInPointer && getPointerType && getPointerInfo && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo; + return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects + && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo; } void QWindowsShcoreDLL::init() diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 3709d9deee..33bd42a669 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -89,6 +89,7 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL); typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID); + typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *); typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID); typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID); @@ -105,6 +106,7 @@ struct QWindowsUser32DLL EnableMouseInPointer enableMouseInPointer = nullptr; GetPointerType getPointerType = nullptr; GetPointerInfo getPointerInfo = nullptr; + GetPointerDeviceRects getPointerDeviceRects = nullptr; GetPointerTouchInfo getPointerTouchInfo = nullptr; GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr; GetPointerPenInfo getPointerPenInfo = nullptr; diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index c11be972b0..abd4d56da0 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -428,9 +428,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin return false; // Let DefWindowProc() handle Non Client messages. POINTER_PEN_INFO *penInfo = static_cast(vPenInfo); + + RECT pRect, dRect; + if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect)) + return false; + const quint32 pointerId = penInfo->pointerInfo.pointerId; const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y); const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); + const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left) + / (pRect.right - pRect.left) * (dRect.right - dRect.left), + dRect.top + qreal(penInfo->pointerInfo.ptHimetricLocation.y - pRect.top) + / (pRect.bottom - pRect.top) * (dRect.bottom - dRect.top)); const qreal pressure = (penInfo->penMask & PEN_MASK_PRESSURE) ? qreal(penInfo->pressure) / 1024.0 : 0.5; const qreal rotation = (penInfo->penMask & PEN_MASK_ROTATION) ? qreal(penInfo->rotation) : 0.0; const qreal tangentialPressure = 0.0; @@ -438,6 +447,13 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin const int yTilt = (penInfo->penMask & PEN_MASK_TILT_Y) ? penInfo->tiltY : 0; const int z = 0; + if (QWindowsContext::verbose > 1) + qCDebug(lcQpaEvents).noquote().nospace() << showbase + << __FUNCTION__ << " pointerId=" << pointerId + << " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos + << " message=" << hex << msg.message + << " flags=" << hex << penInfo->pointerInfo.pointerFlags; + const QTabletEvent::TabletDevice device = QTabletEvent::Stylus; QTabletEvent::PointerType type; Qt::MouseButtons mouseButtons; @@ -491,16 +507,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - QWindowSystemInterface::handleTabletEvent(target, localPos, globalPos, device, type, mouseButtons, + QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, pressure, xTilt, yTilt, tangentialPressure, rotation, z, pointerId, keyModifiers); - QEvent::Type eventType; - Qt::MouseButton button; - getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button); + if (!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) { + QEvent::Type eventType; + Qt::MouseButton button; + getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button); - QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType, - keyModifiers, Qt::MouseEventSynthesizedByQt); + QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType, + keyModifiers, Qt::MouseEventSynthesizedByQt); + } break; } } -- cgit v1.2.3