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 <andre.rocha@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Romain Pokrzywka 2018-08-22 21:54:13 -05:00 committed by Romain Pokrzywka
parent 231273b130
commit 226d196ab0
3 changed files with 29 additions and 7 deletions

View File

@ -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()

View File

@ -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;

View File

@ -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<POINTER_PEN_INFO *>(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;
}
}