summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/CMakeLists.txt6
-rw-r--r--src/plugins/platforms/windows/qwindowsapplication.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsapplication.h6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h9
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp87
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h17
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp289
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h47
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h6
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp2
20 files changed, 355 insertions, 167 deletions
diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt
index 2f1182190d..77d2f2a714 100644
--- a/src/plugins/platforms/windows/CMakeLists.txt
+++ b/src/plugins/platforms/windows/CMakeLists.txt
@@ -198,3 +198,9 @@ qt_internal_extend_target(QWindowsIntegrationPlugin CONDITION MINGW AND QT_FEATU
PUBLIC_LIBRARIES
uuid
)
+
+# begin special case
+if (MINGW)
+ set_source_files_properties(qwindowspointerhandler.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
+endif()
+# end special case
diff --git a/src/plugins/platforms/windows/qwindowsapplication.cpp b/src/plugins/platforms/windows/qwindowsapplication.cpp
index fc495d999f..9997e0a903 100644
--- a/src/plugins/platforms/windows/qwindowsapplication.cpp
+++ b/src/plugins/platforms/windows/qwindowsapplication.cpp
@@ -112,13 +112,13 @@ void QWindowsApplication::setDarkModeHandling(QWindowsApplication::DarkModeHandl
m_darkModeHandling = handling;
}
-void QWindowsApplication::registerMime(QPlatformInterface::Private::QWindowsMime *mime)
+void QWindowsApplication::registerMime(QNativeInterface::Private::QWindowsMime *mime)
{
if (auto ctx = QWindowsContext::instance())
ctx->mimeConverter().registerMime(mime);
}
-void QWindowsApplication::unregisterMime(QPlatformInterface::Private::QWindowsMime *mime)
+void QWindowsApplication::unregisterMime(QNativeInterface::Private::QWindowsMime *mime)
{
if (auto ctx = QWindowsContext::instance())
ctx->mimeConverter().unregisterMime(mime);
diff --git a/src/plugins/platforms/windows/qwindowsapplication.h b/src/plugins/platforms/windows/qwindowsapplication.h
index 25a0cc7437..d57ce263c9 100644
--- a/src/plugins/platforms/windows/qwindowsapplication.h
+++ b/src/plugins/platforms/windows/qwindowsapplication.h
@@ -44,7 +44,7 @@
QT_BEGIN_NAMESPACE
-class QWindowsApplication : public QPlatformInterface::Private::QWindowsApplication
+class QWindowsApplication : public QNativeInterface::Private::QWindowsApplication
{
public:
void setTouchWindowTouchType(TouchWindowTouchTypes type) override;
@@ -62,8 +62,8 @@ public:
DarkModeHandling darkModeHandling() const override;
void setDarkModeHandling(DarkModeHandling handling) override;
- void registerMime(QPlatformInterface::Private::QWindowsMime *mime) override;
- void unregisterMime(QPlatformInterface::Private::QWindowsMime *mime) override;
+ void registerMime(QNativeInterface::Private::QWindowsMime *mime) override;
+ void unregisterMime(QNativeInterface::Private::QWindowsMime *mime) override;
int registerMimeType(const QString &mime) override;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 1e5b247f0f..b2cbae408c 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -349,19 +349,16 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
return true;
const bool usePointerHandler = (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) != 0;
auto touchDevice = usePointerHandler ? d->m_pointerHandler.touchDevice() : d->m_mouseHandler.touchDevice();
- if (!touchDevice) {
+ if (touchDevice.isNull()) {
const bool mouseEmulation =
(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) == 0;
touchDevice = QWindowsPointerHandler::createTouchDevice(mouseEmulation);
}
- if (!touchDevice)
+ if (touchDevice.isNull())
return false;
- if (usePointerHandler)
- d->m_pointerHandler.setTouchDevice(touchDevice);
- else
- d->m_mouseHandler.setTouchDevice(touchDevice);
-
- QWindowSystemInterface::registerInputDevice(touchDevice);
+ d->m_pointerHandler.setTouchDevice(touchDevice);
+ d->m_mouseHandler.setTouchDevice(touchDevice);
+ QWindowSystemInterface::registerInputDevice(touchDevice.data());
d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
@@ -1637,12 +1634,6 @@ void QWindowsContext::setAsyncExpose(bool value)
d->m_asyncExpose = value;
}
-QPointingDevice *QWindowsContext::touchDevice() const
-{
- return (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
- d->m_pointerHandler.touchDevice() : d->m_mouseHandler.touchDevice();
-}
-
DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue)
{
const auto value =
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 0cc5f0f595..aacdafebb6 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -266,8 +266,6 @@ public:
static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue);
- QPointingDevice *touchDevice() const;
-
static bool filterNativeEvent(MSG *msg, LRESULT *result);
static bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result);
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 2970f3d333..0e8383e5c0 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -200,7 +200,7 @@ public:
static QWindowsOpengl32DLL opengl32;
};
-class QWindowsGLContext : public QWindowsOpenGLContext, public QPlatformInterface::QWGLContext
+class QWindowsGLContext : public QWindowsOpenGLContext, public QNativeInterface::QWGLContext
{
public:
explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 6ec5f6e37f..74e6985980 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -183,8 +183,8 @@ bool parseIntOption(const QString &parameter,const QLatin1String &option,
return true;
}
-using DarkModeHandlingFlag = QPlatformInterface::Private::QWindowsApplication::DarkModeHandlingFlag;
-using DarkModeHandling = QPlatformInterface::Private::QWindowsApplication::DarkModeHandling;
+using DarkModeHandlingFlag = QNativeInterface::Private::QWindowsApplication::DarkModeHandlingFlag;
+using DarkModeHandling = QNativeInterface::Private::QWindowsApplication::DarkModeHandling;
static inline unsigned parseOptions(const QStringList &paramList,
int *tabletAbsoluteRange,
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index e0af1e6512..b5449b4a45 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -58,7 +58,7 @@ class QWindowsStaticOpenGLContext;
class QWindowsIntegration : public QPlatformIntegration
#ifndef QT_NO_OPENGL
- , public QPlatformInterface::Private::QWindowsGLIntegration
+ , public QNativeInterface::Private::QWindowsGLIntegration
#endif
, public QWindowsApplication
{
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
index 5f63adba52..f5e7465aff 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
@@ -104,7 +104,7 @@ QVariant QWindowsInternalMimeData::retrieveData_sys(const QString &mimeType, QMe
if (QWindowsContext::verbose) {
qCDebug(lcQpaMime) <<__FUNCTION__ << ' ' << mimeType << ' ' << type.name()
<< " returns " << result.metaType().name()
- << (result.userType() != QVariant::ByteArray ? result.toString() : QStringLiteral("<data>"));
+ << (result.metaType().id() != QMetaType::QByteArray ? result.toString() : QStringLiteral("<data>"));
}
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 9c43045d6a..49bbe88d34 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -544,7 +544,7 @@ QDebug operator<<(QDebug d, IDataObject *dataObj)
All subclasses must reimplement this pure virtual function.
*/
-class QWindowsMimeText : public QPlatformInterface::Private::QWindowsMime
+class QWindowsMimeText : public QNativeInterface::Private::QWindowsMime
{
public:
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
@@ -700,7 +700,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData
return ret;
}
-class QWindowsMimeURI : public QPlatformInterface::Private::QWindowsMime
+class QWindowsMimeURI : public QNativeInterface::Private::QWindowsMime
{
public:
QWindowsMimeURI();
@@ -866,7 +866,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD
return QVariant();
}
-class QWindowsMimeHtml : public QPlatformInterface::Private::QWindowsMime
+class QWindowsMimeHtml : public QNativeInterface::Private::QWindowsMime
{
public:
QWindowsMimeHtml();
@@ -1004,7 +1004,7 @@ bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeDa
#ifndef QT_NO_IMAGEFORMAT_BMP
-class QWindowsMimeImage : public QPlatformInterface::Private::QWindowsMime
+class QWindowsMimeImage : public QNativeInterface::Private::QWindowsMime
{
public:
QWindowsMimeImage();
@@ -1158,7 +1158,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *
}
#endif
-class QBuiltInMimes : public QPlatformInterface::Private::QWindowsMime
+class QBuiltInMimes : public QNativeInterface::Private::QWindowsMime
{
public:
QBuiltInMimes();
@@ -1279,7 +1279,7 @@ QString QBuiltInMimes::mimeForFormat(const FORMATETC &formatetc) const
}
-class QLastResortMimes : public QPlatformInterface::Private::QWindowsMime
+class QLastResortMimes : public QNativeInterface::Private::QWindowsMime
{
public:
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 891ec44ecd..e131dba848 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -56,7 +56,7 @@ class QWindowsMimeConverter
{
Q_DISABLE_COPY_MOVE(QWindowsMimeConverter)
public:
- using QWindowsMime = QPlatformInterface::Private::QWindowsMime;
+ using QWindowsMime = QNativeInterface::Private::QWindowsMime;
QWindowsMimeConverter();
~QWindowsMimeConverter();
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 02c59d4d27..060b3a84bb 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -652,7 +652,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
m_touchInputIDToTouchPointID.clear();
QWindowSystemInterface::handleTouchEvent(window,
- m_touchDevice,
+ m_touchDevice.data(),
touchPoints,
QWindowsKeyMapper::queryKeyboardModifiers());
return true;
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 0b7f26f6c6..c007cf5a5b 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -45,6 +45,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qhash.h>
+#include <QtCore/qsharedpointer.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -56,10 +57,12 @@ class QWindowsMouseHandler
{
Q_DISABLE_COPY_MOVE(QWindowsMouseHandler)
public:
+ using QPointingDevicePtr = QSharedPointer<QPointingDevice>;
+
QWindowsMouseHandler();
- QPointingDevice *touchDevice() const { return m_touchDevice; }
- void setTouchDevice(QPointingDevice *d) { m_touchDevice = d; }
+ const QPointingDevicePtr &touchDevice() const { return m_touchDevice; }
+ void setTouchDevice(const QPointingDevicePtr &d) { m_touchDevice = d; }
bool translateMouseEvent(QWindow *widget, HWND hwnd,
QtWindows::WindowsEventType t, MSG msg,
@@ -90,7 +93,7 @@ private:
QPointer<QWindow> m_trackedWindow;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QHash<int, QPointF> m_lastTouchPositions;
- QPointingDevice *m_touchDevice = nullptr;
+ QPointingDevicePtr m_touchDevice;
bool m_leftButtonDown = false;
QWindow *m_previousCaptureWindow = nullptr;
QEvent::Type m_lastEventType = QEvent::None;
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 0c348a9b71..0b1af47a65 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -283,7 +283,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
#if defined(QT_NO_OPENGL)
Q_UNUSED(gpu);
Q_UNUSED(requested);
- return 0;
+ return {};
#else
QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description);
SupportedRenderersCache *srCache = supportedRenderersCache();
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 095aea2b95..7c021700f2 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"
@@ -79,7 +82,6 @@ qint64 QWindowsPointerHandler::m_nextInputDeviceId = 1;
QWindowsPointerHandler::~QWindowsPointerHandler()
{
- delete m_touchDevice;
}
bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
@@ -317,7 +319,7 @@ static bool isValidWheelReceiver(QWindow *candidate)
return false;
}
-QPointingDevice *QWindowsPointerHandler::createTouchDevice(bool mouseEmulation)
+QWindowsPointerHandler::QPointingDevicePtr QWindowsPointerHandler::createTouchDevice(bool mouseEmulation)
{
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
@@ -336,15 +338,19 @@ QPointingDevice *QWindowsPointerHandler::createTouchDevice(bool mouseEmulation)
capabilities.setFlag(QInputDevice::Capability::MouseEmulation);
}
- qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY)
+ const int flags = digitizers & ~NID_READY;
+ qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << flags
<< "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase
<< "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints << "Capabilities:" << capabilities;
const int buttonCount = type == QInputDevice::DeviceType::TouchScreen ? 1 : 3;
// TODO: use system-provided name and device ID rather than empty-string and m_nextInputDeviceId
- return new QPointingDevice(QString(), m_nextInputDeviceId++,
- type, QPointingDevice::PointerType::Finger,
- capabilities, maxTouchPoints, buttonCount);
+ const qint64 systemId = m_nextInputDeviceId++ | (qint64(flags << 2));
+ auto d = new QPointingDevice(QString(), systemId, type,
+ QPointingDevice::PointerType::Finger,
+ capabilities, maxTouchPoints, buttonCount,
+ QString(), QPointingDeviceUniqueId::fromNumericId(systemId));
+ return QPointingDevicePtr(d);
}
void QWindowsPointerHandler::clearEvents()
@@ -463,7 +469,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
return false;
if (msg.message == WM_POINTERCAPTURECHANGED) {
- QWindowSystemInterface::handleTouchCancelEvent(window, m_touchDevice,
+ QWindowSystemInterface::handleTouchCancelEvent(window, m_touchDevice.data(),
QWindowsKeyMapper::queryKeyboardModifiers());
m_lastTouchPositions.clear();
return true;
@@ -547,11 +553,22 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
if (allStates == QEventPoint::State::Released)
m_touchInputIDToTouchPointID.clear();
- QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
+ QWindowSystemInterface::handleTouchEvent(window, m_touchDevice.data(), touchPoints,
QWindowsKeyMapper::queryKeyboardModifiers());
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 +582,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 +624,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 +663,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 +688,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..6b02412e74 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,14 +58,16 @@ 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);
bool translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
- QPointingDevice *touchDevice() const { return m_touchDevice; }
- void setTouchDevice(QPointingDevice *d) { m_touchDevice = d; }
- static QPointingDevice *createTouchDevice(bool mouseEmulation);
+ const QPointingDevicePtr &touchDevice() const { return m_touchDevice; }
+ void setTouchDevice(const QPointingDevicePtr &d) { m_touchDevice = d; }
+ static QPointingDevicePtr createTouchDevice(bool mouseEmulation);
QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
@@ -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;
+ QPointingDevicePtr m_touchDevice;
+#if QT_CONFIG(tabletevent)
+ QList<QPointingDevicePtr> m_tabletDevices;
+#endif
QHash<int, QPointF> m_lastTouchPositions;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QPointer<QWindow> m_windowUnderPointer;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index f86dbb0c5f..fe4a0d4054 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -133,11 +133,10 @@ QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure
+ d << "TabletDevice id:" << t.systemId << " pressure: " << t.minPressure
<< ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".."
<< t.maxTanPressure << " area: (" << t.minX << ',' << t.minY << ',' << t.minZ
- << ")..(" << t.maxX << ',' << t.maxY << ',' << t.maxZ << ") device "
- << t.currentDevice << " pointer " << t.currentPointerType;
+ << ")..(" << t.maxX << ',' << t.maxY << ',' << t.maxZ << ')';
return d;
}
@@ -166,6 +165,48 @@ QDebug operator<<(QDebug d, const LOGCONTEXT &lc)
}
#endif // !QT_NO_DEBUG_STREAM
+QWinTabPointingDevice *createInputDevice(const QSharedPointer<QWindowsTabletDeviceData> &d,
+ QInputDevice::DeviceType devType,
+ QPointingDevice::PointerType pointerType)
+{
+ const qint64 uniqueId = d->systemId | (qint64(devType) << 32)
+ | (qint64(pointerType) << 48L);
+ QInputDevice::Capabilities caps(QInputDevice::Capability::Position
+ | QInputDevice::Capability::Pressure
+ | QInputDevice::Capability::MouseEmulation
+ | QInputDevice::Capability::Hover);
+ if (d->zCapability)
+ caps |= QInputDevice::Capability::ZPosition;
+ if (d->tiltCapability) {
+ caps |= QInputDevice::Capability::XTilt
+ | QInputDevice::Capability::YTilt
+ | QInputDevice::Capability::Rotation
+ | QInputDevice::Capability::TangentialPressure;
+ }
+
+ auto result = new QWinTabPointingDevice(d, QStringLiteral("wintab"), d->systemId,
+ devType, pointerType, caps, 1,
+ d->buttonsMap.size(), QString(),
+ QPointingDeviceUniqueId::fromNumericId(uniqueId));
+ QWindowSystemInterface::registerInputDevice(result);
+ return result;
+}
+
+QWinTabPointingDevice::QWinTabPointingDevice(const QWinTabPointingDevice::DeviceDataPtr &data,
+ const QString &name, qint64 systemId,
+ QInputDevice::DeviceType devType,
+ QPointingDevice::PointerType pType,
+ QInputDevice::Capabilities caps,
+ int maxPoints, int buttonCount,
+ const QString &seatName,
+ QPointingDeviceUniqueId uniqueId,
+ QObject *parent)
+ : QPointingDevice(name, systemId, devType, pType, caps, maxPoints, buttonCount,
+ seatName, uniqueId, parent),
+ m_deviceData(data)
+{
+}
+
QWindowsWinTab32DLL QWindowsTabletSupport::m_winTab32DLL;
/*!
@@ -320,14 +361,6 @@ void QWindowsTabletSupport::notifyActivate()
qCDebug(lcQpaTablet) << __FUNCTION__ << result;
}
-static inline int indexOfDevice(const QList<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
-{
- for (int i = 0; i < devices.size(); ++i)
- if (devices.at(i).uniqueId == uniqueId)
- return i;
- return -1;
-}
-
static inline QInputDevice::DeviceType deviceType(const UINT cursorType)
{
if (((cursorType & 0x0006) == 0x0002) && ((cursorType & CursorTypeBitMask) != 0x0902))
@@ -366,10 +399,65 @@ static inline QPointingDevice::PointerType pointerType(unsigned currentCursor)
return QPointingDevice::PointerType::Unknown;
}
-QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT cursorType) const
+inline void QWindowsTabletSupport::enterProximity(ulong time, QWindow *window)
+{
+ enterLeaveProximity(true, time, window);
+}
+
+inline void QWindowsTabletSupport::leaveProximity(ulong time, QWindow *window)
+{
+ enterLeaveProximity(false, time, window);
+}
+
+void QWindowsTabletSupport::enterLeaveProximity(bool enter, ulong time, QWindow *window)
+{
+ Q_ASSERT(!m_currentDevice.isNull());
+ if (time == 0) // Some leave events do not have a time associated
+ ++m_eventTime;
+ else
+ m_eventTime = time;
+ QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(window, m_eventTime,
+ m_currentDevice.data(),
+ enter);
+}
+
+QWindowsTabletSupport::DevicePtr QWindowsTabletSupport::findDevice(qint64 systemId) const
+{
+ for (const auto &d : m_devices) {
+ if (d->deviceData()->systemId == systemId)
+ return d;
+ }
+ return {};
+}
+
+QWindowsTabletSupport::DevicePtr QWindowsTabletSupport::findDevice(qint64 systemId,
+ QInputDevice::DeviceType deviceType,
+ QPointingDevice::PointerType pointerType) const
+{
+ for (const auto &d : m_devices) {
+ if (d->deviceData()->systemId == systemId && d->type() == deviceType
+ && d->pointerType() == pointerType) {
+ return d;
+ }
+ }
+ return {};
+}
+
+// Clone a device for a new pointer type.
+QWindowsTabletSupport::DevicePtr QWindowsTabletSupport::clonePhysicalDevice(qint64 systemId,
+ QInputDevice::DeviceType deviceType,
+ QPointingDevice::PointerType pointerType)
+{
+ auto similar = findDevice(systemId);
+ if (similar.isNull())
+ return {};
+ DevicePtr result(createInputDevice(similar->deviceData(), deviceType, pointerType));
+ m_devices.append(result);
+ return result;
+}
+
+void QWindowsTabletSupport::updateData(QWindowsTabletDeviceData *data) const
{
- QWindowsTabletDeviceData result;
- result.uniqueId = uniqueId;
/* browse WinTab's many info items to discover pressure handling. */
AXIS axis;
LOGCONTEXT lc;
@@ -377,22 +465,40 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT
QWindowsTabletSupport::m_winTab32DLL.wTGet(m_context, &lc);
/* get the size of the pressure axis. */
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &axis);
- result.minPressure = int(axis.axMin);
- result.maxPressure = int(axis.axMax);
+ data->minPressure = int(axis.axMin);
+ data->maxPressure = int(axis.axMax);
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &axis);
- result.minTanPressure = int(axis.axMin);
- result.maxTanPressure = int(axis.axMax);
+ data->minTanPressure = int(axis.axMin);
+ data->maxTanPressure = int(axis.axMax);
LOGCONTEXT defaultLc;
/* get default region */
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFCONTEXT, 0, &defaultLc);
- result.maxX = int(defaultLc.lcInExtX) - int(defaultLc.lcInOrgX);
- result.maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
- result.maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
- result.currentDevice = deviceType(cursorType);
- result.zCapability = (cursorType == 0x0004);
- return result;
+ data->maxX = int(defaultLc.lcInExtX) - int(defaultLc.lcInOrgX);
+ data->maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
+ data->maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
+}
+
+void QWindowsTabletSupport::updateButtons(unsigned currentCursor, QWindowsTabletDeviceData *data) const
+{
+ // We should check button map for changes on every proximity event, not
+ // only during initialization phase.
+ // WARNING: in 2016 there were some Wacom tablet drivers, which could mess up
+ // button mapping if the remapped button was pressed, while the
+ // application **didn't have input focus**. This bug is somehow
+ // related to the fact that Wacom drivers allow user to configure
+ // per-application button-mappings. If the bug shows up again,
+ // just move this button-map fetching into initialization block.
+ //
+ // See https://bugs.kde.org/show_bug.cgi?id=359561
+ BYTE logicalButtons[32];
+ memset(logicalButtons, 0, 32);
+ m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_SYSBTNMAP, &logicalButtons);
+ data->buttonsMap.clear();
+ data->buttonsMap[0x1] = logicalButtons[0];
+ data->buttonsMap[0x2] = logicalButtons[1];
+ data->buttonsMap[0x4] = logicalButtons[2];
}
bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
@@ -401,21 +507,11 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
if (!LOWORD(lParam)) {
- qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
- if (m_currentDevice < 0 || m_currentDevice >= m_devices.size()) // QTBUG-65120, spurious leave observed
+ if (m_currentDevice.isNull()) // QTBUG-65120, spurious leave observed
return false;
+ qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice.data();
m_state = PenUp;
- if (totalPacks > 0) {
- QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
- int(m_devices.at(m_currentDevice).currentDevice),
- int(m_devices.at(m_currentDevice).currentPointerType),
- m_devices.at(m_currentDevice).uniqueId);
- } else {
- QWindowSystemInterface::handleTabletLeaveProximityEvent(int(m_devices.at(m_currentDevice).currentDevice),
- int(m_devices.at(m_currentDevice).currentPointerType),
- m_devices.at(m_currentDevice).uniqueId);
-
- }
+ leaveProximity(totalPacks > 0 ? proximityBuffer[0].pkTime : 0u);
return true;
}
@@ -425,48 +521,37 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
const UINT currentCursor = proximityBuffer[0].pkCursor;
UINT physicalCursorId;
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
+ const qint64 systemId = physicalCursorId;
UINT cursorType;
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &cursorType);
- const qint64 uniqueId = (qint64(cursorType & DeviceIdMask) << 32L) | qint64(physicalCursorId);
+
+ const QInputDevice::DeviceType currentType = deviceType(cursorType);
+ const QPointingDevice::PointerType currentPointerType = pointerType(currentCursor);
// initializing and updating the cursor should be done in response to
// WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
// the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
- m_currentDevice = indexOfDevice(m_devices, uniqueId);
- if (m_currentDevice < 0) {
- m_currentDevice = m_devices.size();
- m_devices.push_back(tabletInit(uniqueId, cursorType));
+ m_currentDevice = findDevice(systemId, currentType, currentPointerType);
+ if (m_currentDevice.isNull())
+ m_currentDevice = clonePhysicalDevice(systemId, currentType, currentPointerType);
+ if (m_currentDevice.isNull()) {
+ QWinTabPointingDevice::DeviceDataPtr data(new QWindowsTabletDeviceData);
+ data->systemId = systemId;
+ data->tiltCapability = m_tiltSupport;
+ data->zCapability = (cursorType == 0x0004);
+ updateButtons(currentCursor, data.data());
+ m_currentDevice.reset(createInputDevice(data, currentType, currentPointerType));
+ m_devices.append(m_currentDevice);
}
- /**
- * We should check button map for changes on every proximity event, not
- * only during initialization phase.
- *
- * WARNING: in 2016 there were some Wacom table drivers, which could mess up
- * button mapping if the remapped button was pressed, while the
- * application **didn't have input focus**. This bug is somehow
- * related to the fact that Wacom drivers allow user to configure
- * per-application button-mappings. If the bug shows up again,
- * just move this button-map fetching into initialization block.
- *
- * See https://bugs.kde.org/show_bug.cgi?id=359561
- */
- BYTE logicalButtons[32];
- memset(logicalButtons, 0, 32);
- m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_SYSBTNMAP, &logicalButtons);
- m_devices[m_currentDevice].buttonsMap[0x1] = logicalButtons[0];
- m_devices[m_currentDevice].buttonsMap[0x2] = logicalButtons[1];
- m_devices[m_currentDevice].buttonsMap[0x4] = logicalButtons[2];
+ // The user can switch pressure sensitivity level in the driver,which
+ // will make our saved values invalid (this option is provided by Wacom
+ // drivers for compatibility reasons, and it can be adjusted on the fly)
+ updateData(m_currentDevice->deviceData().data());
- m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
m_state = PenProximity;
qCDebug(lcQpaTablet) << "enter proximity for device #"
- << m_currentDevice << m_devices.at(m_currentDevice);
- // TODO use the version taking a QPointingDevice, and own those instances; replace QWindowsTabletDeviceData
- // TODO QWindowSystemInterface::registerInputDevice() as early as possible, and before sending any events from it
- QWindowSystemInterface::handleTabletEnterProximityEvent(proximityBuffer[0].pkTime,
- int(m_devices.at(m_currentDevice).currentDevice),
- int(m_devices.at(m_currentDevice).currentPointerType),
- m_devices.at(m_currentDevice).uniqueId);
+ << m_currentDevice.data();
+ enterProximity(proximityBuffer[0].pkTime);
return true;
}
@@ -520,12 +605,10 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
{
static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
const int packetCount = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, TabletPacketQSize, &localPacketBuf);
- if (!packetCount || m_currentDevice < 0)
+ if (!packetCount || m_currentDevice.isNull())
return false;
- const auto currentDevice = m_devices.at(m_currentDevice).currentDevice;
- const auto currentPointer = m_devices.at(m_currentDevice).currentPointerType;
- const qint64 uniqueId = m_devices.at(m_currentDevice).uniqueId;
+ const QWindowsTabletDeviceData &current = *m_currentDevice->deviceData();
// The tablet can be used in 2 different modes (reflected in enum Mode),
// depending on its settings:
@@ -545,8 +628,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
if (QWindowsContext::verbose > 1) {
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing" << packetCount
- << "mode=" << m_mode << "target:"
- << QGuiApplicationPrivate::tabletDevicePoint(uniqueId).target;
+ << "mode=" << m_mode;
}
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
@@ -554,12 +636,31 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
for (int i = 0; i < packetCount ; ++i) {
const PACKET &packet = localPacketBuf[i];
- const int z = m_devices.at(m_currentDevice).zCapability ? int(packet.pkZ) : 0;
+ const int z = current.zCapability ? int(packet.pkZ) : 0;
+
+ const auto packetPointerType = pointerType(packet.pkCursor);
+
+ const Qt::MouseButtons buttons =
+ convertTabletButtons(packet.pkButtons, current);
+
+ if (buttons == Qt::NoButton && packetPointerType != m_currentDevice->pointerType()) {
+ leaveProximity(packet.pkTime);
+ Q_ASSERT(!m_currentDevice.isNull());
+ // Pointer type changed, find or clone a new device for this physical cursor.
+ const qint64 systemId = m_currentDevice->systemId();
+ const QInputDevice::DeviceType type = m_currentDevice->type();
+ m_currentDevice = findDevice(systemId, type, packetPointerType);
+ if (m_currentDevice.isNull())
+ m_currentDevice = clonePhysicalDevice(systemId, type, packetPointerType);
+ Q_ASSERT(!m_currentDevice.isNull());
+ enterProximity(packet.pkTime);
+ }
QPointF globalPosF =
- m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+ current.scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
- QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(uniqueId).target; // Pass to window that grabbed it.
+ // Pass to window that grabbed it.
+ QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(m_currentDevice->uniqueId().numericId()).target;
// Get Mouse Position and compare to tablet info
const QPoint mouseLocation = QWindowsCursor::mousePosition();
@@ -583,12 +684,12 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
Q_ASSERT(platformWindow);
const QPoint localPos = platformWindow->mapFromGlobal(globalPos);
- const qreal pressureNew = packet.pkButtons && (currentPointer == QPointingDevice::PointerType::Pen || currentPointer == QPointingDevice::PointerType::Eraser) ?
- m_devices.at(m_currentDevice).scalePressure(packet.pkNormalPressure) :
- qreal(0);
- const qreal tangentialPressure = currentDevice == QInputDevice::DeviceType::Airbrush ?
- m_devices.at(m_currentDevice).scaleTangentialPressure(packet.pkTangentPressure) :
- qreal(0);
+ const qreal pressureNew = packet.pkButtons
+ && (m_currentDevice->pointerType() == QPointingDevice::PointerType::Pen
+ || m_currentDevice->pointerType() == QPointingDevice::PointerType::Eraser)
+ ? current.scalePressure(packet.pkNormalPressure) : qreal(0);
+ const qreal tangentialPressure = m_currentDevice->type() == QInputDevice::DeviceType::Airbrush
+ ? current.scaleTangentialPressure(packet.pkTangentPressure) : qreal(0);
int tiltX = 0;
int tiltY = 0;
@@ -617,20 +718,18 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
qCDebug(lcQpaTablet)
<< "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
<< globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
- << packet.pkY << ") dev:" << currentDevice << "pointer:"
- << currentPointer << "P:" << pressureNew << "tilt:" << tiltX << ','
- << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
+ << packet.pkY << ") dev:" << m_currentDevice->type() << "pointer:"
+ << m_currentDevice->pointerType() << "P:" << pressureNew << "tilt:" << tiltX << ','
+ << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation
+ << " target=" << target;
}
- Qt::MouseButtons buttons =
- convertTabletButtons(packet.pkButtons, m_devices.at(m_currentDevice));
-
- QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
- int(currentDevice), int(currentPointer),
- buttons,
- pressureNew, tiltX, tiltY,
+ m_eventTime = packet.pkTime;
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkTime,
+ m_currentDevice.data(),
+ QPointF(localPos), globalPosF,
+ buttons, pressureNew, tiltX, tiltY,
tangentialPressure, rotation, z,
- uniqueId,
keyboardModifiers);
}
return true;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
index 229677dae4..dca2800215 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.h
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -47,6 +47,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
#include <QtCore/qpoint.h>
+#include <QtCore/qsharedpointer.h>
#include <wintab.h>
@@ -83,6 +84,8 @@ struct QWindowsWinTab32DLL
PtrWTQueueSizeSet wTQueueSizeSet = nullptr;
};
+// Data associated with a physical cursor (system ID) which is shared between
+// devices of varying device type/pointer type.
struct QWindowsTabletDeviceData
{
QPointF scaleCoordinates(int coordX, int coordY,const QRect &targetArea) const;
@@ -99,13 +102,31 @@ struct QWindowsTabletDeviceData
int maxY = 0;
int minZ = 0;
int maxZ = 0;
- qint64 uniqueId = 0;
- QInputDevice::DeviceType currentDevice = QInputDevice::DeviceType::Unknown;
- QPointingDevice::PointerType currentPointerType = QPointingDevice::PointerType::Unknown;
+ qint64 systemId = 0;
bool zCapability = false;
+ bool tiltCapability = false;
QHash<quint8, quint8> buttonsMap;
};
+class QWinTabPointingDevice : public QPointingDevice
+{
+public:
+ using DeviceDataPtr = QSharedPointer<QWindowsTabletDeviceData>;
+
+ explicit QWinTabPointingDevice(const DeviceDataPtr &data,
+ const QString &name, qint64 systemId,
+ QInputDevice::DeviceType devType,
+ PointerType pType, Capabilities caps, int maxPoints,
+ int buttonCount, const QString &seatName = QString(),
+ QPointingDeviceUniqueId uniqueId = QPointingDeviceUniqueId(),
+ QObject *parent = nullptr);
+
+ const DeviceDataPtr &deviceData() const { return m_deviceData; }
+
+private:
+ DeviceDataPtr m_deviceData;
+};
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t);
#endif
@@ -117,6 +138,9 @@ class QWindowsTabletSupport
explicit QWindowsTabletSupport(HWND window, HCTX context);
public:
+ using DevicePtr = QSharedPointer<QWinTabPointingDevice>;
+ using Devices = QList<DevicePtr>;
+
enum Mode
{
PenMode,
@@ -146,16 +170,29 @@ public:
private:
unsigned options() const;
QWindowsTabletDeviceData tabletInit(qint64 uniqueId, UINT cursorType) const;
+ void updateData(QWindowsTabletDeviceData *data) const;
+ void updateButtons(unsigned currentCursor, QWindowsTabletDeviceData *data) const;
+ void enterProximity(ulong time = 0, QWindow *window = nullptr);
+ void leaveProximity(ulong time = 0, QWindow *window = nullptr);
+ void enterLeaveProximity(bool enter, ulong time, QWindow *window = nullptr);
+ DevicePtr findDevice(qint64 systemId) const;
+ DevicePtr findDevice(qint64 systemId,
+ QInputDevice::DeviceType deviceType,
+ QPointingDevice::PointerType pointerType) const;
+ DevicePtr clonePhysicalDevice(qint64 systemId,
+ QInputDevice::DeviceType deviceType,
+ QPointingDevice::PointerType pointerType);
static QWindowsWinTab32DLL m_winTab32DLL;
const HWND m_window;
const HCTX m_context;
static int m_absoluteRange;
bool m_tiltSupport = false;
- QList<QWindowsTabletDeviceData> m_devices;
- int m_currentDevice = -1;
+ Devices m_devices;
+ DevicePtr m_currentDevice;
Mode m_mode = PenMode;
State m_state = PenUp;
+ ulong m_eventTime = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 827e4cc288..1f1af82da2 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -125,12 +125,12 @@ struct QWindowsWindowData
};
class QWindowsBaseWindow : public QPlatformWindow,
- public QPlatformInterface::Private::QWindowsWindow
+ public QNativeInterface::Private::QWindowsWindow
{
Q_DISABLE_COPY_MOVE(QWindowsBaseWindow)
public:
- using TouchWindowTouchType = QPlatformInterface::Private::QWindowsApplication::TouchWindowTouchType;
- using TouchWindowTouchTypes = QPlatformInterface::Private::QWindowsApplication::TouchWindowTouchTypes;
+ using TouchWindowTouchType = QNativeInterface::Private::QWindowsApplication::TouchWindowTouchType;
+ using TouchWindowTouchTypes = QNativeInterface::Private::QWindowsApplication::TouchWindowTouchTypes;
explicit QWindowsBaseWindow(QWindow *window) : QPlatformWindow(window) {}
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 9808d5481c..43a53d7cfc 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -164,7 +164,7 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve
}
}
}
- if (event->value().type() == QVariant::String) {
+ if (event->value().typeId() == QMetaType::QString) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
// Tries to notify the change using UiaRaiseNotificationEvent(), which is only available on