Windows QPA: Pass device for synthesized touch/tablet events

Add the overloads for mouse events with device/without timestamp
and pass the active tablet or touch device.

Task-number: QTBUG-88678
Task-number: QTBUG-46412
Change-Id: I8695b493540d0cbf50e9c72afe870a7633de3ab9
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit d3caea04dc6c3a7072a43294b70bec860c199bf1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Friedemann Kleint 2020-11-24 09:20:08 +01:00 committed by Qt Cherry-pick Bot
parent b88dd5490b
commit 3b58d9814f
6 changed files with 74 additions and 12 deletions

View File

@ -381,6 +381,15 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window,
return handleMouseEvent<Delivery>(window, time, local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleMouseEvent<Delivery>(window, time, device, local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
@ -418,6 +427,17 @@ bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window,
return handleFrameStrutMouseEvent(window, time, local, global, state, button, type, mods, source);
}
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleFrameStrutMouseEvent(window, time, device, local, global, state, button, type, mods, source);
}
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp,
const QPointF &local, const QPointF &global,
Qt::MouseButtons state,

View File

@ -82,6 +82,12 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleMouseEvent(QWindow *window, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleMouseEvent(QWindow *window, ulong timestamp, const QPointF &local,
const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
@ -100,6 +106,13 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source =
Qt::MouseEventNotSynthesized);
static bool handleFrameStrutMouseEvent(QWindow *window, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source =
Qt::MouseEventNotSynthesized);
static bool handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointF &local,
const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,

View File

@ -128,6 +128,12 @@ static inline void compressMouseMove(MSG *msg)
QWindowsMouseHandler::QWindowsMouseHandler() = default;
const QPointingDevice *QWindowsMouseHandler::primaryMouse()
{
static const auto result = QPointingDevice::primaryPointingDevice();
return result;
}
void QWindowsMouseHandler::clearEvents()
{
m_lastEventType = QEvent::None;
@ -270,6 +276,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
const QPointingDevice *device = primaryMouse();
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
static const bool passSynthesizedMouseEvents =
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
@ -281,6 +289,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if ((extraInfo & signatureMask) == miWpSignature) {
if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen.
source = Qt::MouseEventSynthesizedBySystem;
if (!m_touchDevice.isNull())
device = m_touchDevice.data();
if (!passSynthesizedMouseEvents)
return false;
}
@ -305,10 +315,10 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
&& (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
&& (m_lastEventButton & buttons) == 0) {
if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, device, clientPosition, globalPosition, buttons, m_lastEventButton,
QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
} else {
QWindowSystemInterface::handleMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
QWindowSystemInterface::handleMouseEvent(window, device, clientPosition, globalPosition, buttons, m_lastEventButton,
QEvent::MouseButtonRelease, keyModifiers, source);
}
}
@ -316,7 +326,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
m_lastEventButton = mouseEvent.button;
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, device, clientPosition,
globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
keyModifiers, source);
@ -466,7 +476,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowSystemInterface::handleMouseEvent(window, device, winEventPosition, globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
keyModifiers, source);
}

View File

@ -85,6 +85,8 @@ public:
void clearWindowUnderMouse() { m_windowUnderMouse = nullptr; }
void clearEvents();
static const QPointingDevice *primaryMouse();
private:
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
MSG msg, LRESULT *result);

View File

@ -45,6 +45,7 @@
#endif
#include "qwindowspointerhandler.h"
#include "qwindowsmousehandler.h"
#if QT_CONFIG(tabletevent)
# include "qwindowstabletsupport.h"
#endif
@ -647,6 +648,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
}
const auto uniqueId = device->uniqueId().numericId();
m_activeTabletDevice = device;
switch (msg.message) {
case WM_POINTERENTER: {
@ -789,14 +791,28 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
}
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
const QPointingDevice *device = QWindowsMouseHandler::primaryMouse();
// Following the logic of the old mouse handler, only events synthesized
// for touch screen are marked as such. On some systems, using the bit 7 of
// the extra msg info for checking if synthesized for touch does not work,
// so we use the pointer type of the last pointer message.
if (isMouseEventSynthesizedFromPenOrTouch() && m_pointerType == QT_PT_TOUCH) {
if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
return false;
source = Qt::MouseEventSynthesizedBySystem;
if (isMouseEventSynthesizedFromPenOrTouch()) {
switch (m_pointerType) {
case QT_PT_TOUCH:
if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
return false;
source = Qt::MouseEventSynthesizedBySystem;
if (!m_touchDevice.isNull())
device = m_touchDevice.data();
break;
case QT_PT_PEN:
#if QT_CONFIG(tabletevent)
if (!m_activeTabletDevice.isNull())
device = m_activeTabletDevice.data();
#endif
break;
}
}
const MouseEvent mouseEvent = eventFromMsg(msg);
@ -817,10 +833,10 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
&& (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
&& (m_lastEventButton & mouseButtons) == 0) {
if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, device, localPos, globalPos, mouseButtons, m_lastEventButton,
QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
} else {
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
QWindowSystemInterface::handleMouseEvent(window, device, localPos, globalPos, mouseButtons, m_lastEventButton,
QEvent::MouseButtonRelease, keyModifiers, source);
}
}
@ -828,7 +844,7 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
m_lastEventButton = mouseEvent.button;
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
QWindowSystemInterface::handleFrameStrutMouseEvent(window, device, localPos, globalPos, mouseButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source);
return false; // Allow further event processing
}
@ -848,7 +864,7 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons,
QWindowSystemInterface::handleMouseEvent(window, device, localPos, globalPos, mouseButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source);
}

View File

@ -86,6 +86,7 @@ private:
QPointingDevicePtr m_touchDevice;
#if QT_CONFIG(tabletevent)
QList<QPointingDevicePtr> m_tabletDevices;
QPointingDevicePtr m_activeTabletDevice;
#endif
QHash<int, QPointF> m_lastTouchPositions;
QHash<DWORD, int> m_touchInputIDToTouchPointID;