Windows QPA/WmPointer: Register tablet devices of pointer handler
Task-number: QTBUG-46412 Change-Id: Ib9b5fd6056a5474ce46c7bde53be7a12c1494611 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>bb10
parent
abb5f0d376
commit
8ba59441fc
|
|
@ -45,6 +45,9 @@
|
|||
#endif
|
||||
|
||||
#include "qwindowspointerhandler.h"
|
||||
#if QT_CONFIG(tabletevent)
|
||||
# include "qwindowstabletsupport.h"
|
||||
#endif
|
||||
#include "qwindowskeymapper.h"
|
||||
#include "qwindowscontext.h"
|
||||
#include "qwindowswindow.h"
|
||||
|
|
@ -552,6 +555,17 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
|
|||
return false; // Allow mouse messages to be generated.
|
||||
}
|
||||
|
||||
#if QT_CONFIG(tabletevent)
|
||||
QWindowsPointerHandler::QPointingDevicePtr QWindowsPointerHandler::findTabletDevice(QPointingDevice::PointerType pointerType) const
|
||||
{
|
||||
for (const auto &d : m_tabletDevices) {
|
||||
if (d->pointerType() == pointerType)
|
||||
return d;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et,
|
||||
MSG msg, PVOID vPenInfo)
|
||||
{
|
||||
|
|
@ -565,28 +579,31 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
|
||||
return false;
|
||||
|
||||
const auto sourceDevice = (qint64)penInfo->pointerInfo.sourceDevice;
|
||||
const auto systemId = (qint64)penInfo->pointerInfo.sourceDevice;
|
||||
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 bool hasPressure = (penInfo->penMask & PEN_MASK_PRESSURE) != 0;
|
||||
const bool hasRotation = (penInfo->penMask & PEN_MASK_ROTATION) != 0;
|
||||
const qreal pressure = hasPressure ? qreal(penInfo->pressure) / 1024.0 : 0.5;
|
||||
const qreal rotation = hasRotation ? qreal(penInfo->rotation) : 0.0;
|
||||
const qreal tangentialPressure = 0.0;
|
||||
const int xTilt = (penInfo->penMask & PEN_MASK_TILT_X) ? penInfo->tiltX : 0;
|
||||
const int yTilt = (penInfo->penMask & PEN_MASK_TILT_Y) ? penInfo->tiltY : 0;
|
||||
const bool hasTiltX = (penInfo->penMask & PEN_MASK_TILT_X) != 0;
|
||||
const bool hasTiltY = (penInfo->penMask & PEN_MASK_TILT_Y) != 0;
|
||||
const int xTilt = hasTiltX ? penInfo->tiltX : 0;
|
||||
const int yTilt = hasTiltY ? penInfo->tiltY : 0;
|
||||
const int z = 0;
|
||||
|
||||
if (QWindowsContext::verbose > 1)
|
||||
qCDebug(lcQpaEvents).noquote().nospace() << Qt::showbase
|
||||
<< __FUNCTION__ << " sourceDevice=" << sourceDevice
|
||||
<< __FUNCTION__ << " systemId=" << systemId
|
||||
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
|
||||
<< " message=" << Qt::hex << msg.message
|
||||
<< " flags=" << Qt::hex << penInfo->pointerInfo.pointerFlags;
|
||||
|
||||
const QInputDevice::DeviceType device = QInputDevice::DeviceType::Stylus;
|
||||
QPointingDevice::PointerType type;
|
||||
// Since it may be the middle button, so if the checks fail then it should
|
||||
// be set to Middle if it was used.
|
||||
|
|
@ -604,9 +621,33 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||
mouseButtons = Qt::RightButton; // Either left or right, not both
|
||||
}
|
||||
|
||||
auto device = findTabletDevice(type);
|
||||
if (device.isNull()) {
|
||||
QInputDevice::Capabilities caps(QInputDevice::Capability::Position
|
||||
| QInputDevice::Capability::MouseEmulation
|
||||
| QInputDevice::Capability::Hover);
|
||||
if (hasPressure)
|
||||
caps |= QInputDevice::Capability::Pressure;
|
||||
if (hasRotation)
|
||||
caps |= QInputDevice::Capability::Rotation;
|
||||
if (hasTiltX)
|
||||
caps |= QInputDevice::Capability::XTilt;
|
||||
if (hasTiltY)
|
||||
caps |= QInputDevice::Capability::YTilt;
|
||||
const qint64 uniqueId = systemId | (qint64(type) << 32L);
|
||||
device.reset(new QPointingDevice(QStringLiteral("wmpointer"),
|
||||
systemId, QInputDevice::DeviceType::Stylus,
|
||||
type, caps, 1, 3, QString(),
|
||||
QPointingDeviceUniqueId::fromNumericId(uniqueId)));
|
||||
QWindowSystemInterface::registerInputDevice(device.data());
|
||||
m_tabletDevices.append(device);
|
||||
}
|
||||
|
||||
const auto uniqueId = device->uniqueId().numericId();
|
||||
|
||||
switch (msg.message) {
|
||||
case WM_POINTERENTER: {
|
||||
QWindowSystemInterface::handleTabletEnterProximityEvent(int(device), int(type), sourceDevice);
|
||||
QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(window, device.data(), true);
|
||||
m_windowUnderPointer = window;
|
||||
// The local coordinates may fall outside the window.
|
||||
// Wait until the next update to send the enter event.
|
||||
|
|
@ -619,12 +660,12 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||
m_windowUnderPointer = nullptr;
|
||||
m_currentWindow = nullptr;
|
||||
}
|
||||
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(device), int(type), sourceDevice);
|
||||
QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(window, device.data(), false);
|
||||
break;
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUP:
|
||||
case WM_POINTERUPDATE: {
|
||||
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).target; // Pass to window that grabbed it.
|
||||
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(uniqueId).target; // Pass to window that grabbed it.
|
||||
if (!target && m_windowUnderPointer)
|
||||
target = m_windowUnderPointer;
|
||||
if (!target)
|
||||
|
|
@ -644,9 +685,10 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||
}
|
||||
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||
|
||||
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, int(device), int(type), mouseButtons,
|
||||
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
|
||||
sourceDevice, keyModifiers);
|
||||
QWindowSystemInterface::handleTabletEvent(target, device.data(),
|
||||
localPos, hiResGlobalPos, mouseButtons,
|
||||
pressure, xTilt, yTilt, tangentialPressure,
|
||||
rotation, z, keyModifiers);
|
||||
return false; // Allow mouse messages to be generated.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
|
|
@ -57,6 +58,8 @@ class QWindowsPointerHandler
|
|||
{
|
||||
Q_DISABLE_COPY_MOVE(QWindowsPointerHandler)
|
||||
public:
|
||||
using QPointingDevicePtr = QSharedPointer<QPointingDevice>;
|
||||
|
||||
QWindowsPointerHandler() = default;
|
||||
~QWindowsPointerHandler();
|
||||
bool translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
|
||||
|
|
@ -76,8 +79,14 @@ private:
|
|||
bool translateMouseWheelEvent(QWindow *window, QWindow *currentWindowUnderPointer, MSG msg, QPoint globalPos, Qt::KeyboardModifiers keyModifiers);
|
||||
void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons);
|
||||
void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos);
|
||||
#if QT_CONFIG(tabletevent)
|
||||
QPointingDevicePtr findTabletDevice(QPointingDevice::PointerType pointerType) const;
|
||||
#endif
|
||||
|
||||
QPointingDevice *m_touchDevice = nullptr;
|
||||
#if QT_CONFIG(tabletevent)
|
||||
QList<QPointingDevicePtr> m_tabletDevices;
|
||||
#endif
|
||||
QHash<int, QPointF> m_lastTouchPositions;
|
||||
QHash<DWORD, int> m_touchInputIDToTouchPointID;
|
||||
QPointer<QWindow> m_windowUnderPointer;
|
||||
|
|
|
|||
Loading…
Reference in New Issue