summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-16 11:26:54 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-20 19:21:50 +0200
commit8ba59441fc62c567b1e8dadce5f6e044caa67e49 (patch)
tree90ab700464007bb184c91fe81614cd42b3afc0b9
parentabb5f0d3768a817b7e30639107210e64b8dbc138 (diff)
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>
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp68
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h9
2 files changed, 64 insertions, 13 deletions
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 095aea2b95..41f17f5c3b 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -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.
}
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index 3b204c675b..d0f0b816d3 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -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;