diff --git a/libs/ui/input/wintab/kis_tablet_support_win8.cpp b/libs/ui/input/wintab/kis_tablet_support_win8.cpp index 53bb88a43d..69367c43c0 100644 --- a/libs/ui/input/wintab/kis_tablet_support_win8.cpp +++ b/libs/ui/input/wintab/kis_tablet_support_win8.cpp @@ -38,6 +38,8 @@ #include #include +#include + #include #include @@ -624,7 +626,77 @@ bool sendProximityTabletEvent(const QEvent::Type eventType, const POINTER_PEN_IN return ev.isAccepted(); } -bool sendPositionalTabletEvent(QWidget *target, const QEvent::Type eventType, const POINTER_PEN_INFO &penInfo, const PointerDeviceItem &device, const PenPointerItem &penPointerItem) +bool synthesizeMouseEvent(const QWidget *target, const QTabletEvent &ev, const POINTER_PEN_INFO &penInfo) +{ + BOOL result = SetCursorPos(penInfo.pointerInfo.ptPixelLocationRaw.x, penInfo.pointerInfo.ptPixelLocationRaw.y); + if (!result) { + qDebug() << "SetCursorPos failed, err" << GetLastError(); + // return true; + } + QPointF localPosF = ev.posF(); + QWindow *window = target->windowHandle(); + if (!window) { + QWidget *nativeParent = target->nativeParentWidget(); + if (!nativeParent) { + warnTablet << "KisTabletSupportWin8::synthesizeMouseEvent target->nativeParentWidget is null!"; + return false; + } + window = nativeParent->windowHandle(); + const QPoint globalPos = ev.globalPosF().toPoint(); + const QPoint localPos = nativeParent->mapFromGlobal(globalPos); + const QPointF delta = ev.globalPosF() - globalPos; + localPosF = localPos + delta; + } + QWindowSystemInterfacePrivate::MouseEvent fake(window, ev.timestamp(), localPosF, + ev.globalPosF(),ev.buttons(), ev.modifiers(), Qt::MouseEventSynthesizedByQt); + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; + QGuiApplicationPrivate::processMouseEvent(&fake); + // DWORD inputDataFlags = 0; + // switch (ev.type()) { + // case QEvent::TabletPress: + // switch (ev.button()) { + // case Qt::LeftButton: + // inputDataFlags = MOUSEEVENTF_LEFTDOWN; + // break; + // case Qt::RightButton: + // inputDataFlags = MOUSEEVENTF_RIGHTDOWN; + // break; + // default: + // return true; + // } + // break; + // case QEvent::TabletRelease: + // switch (ev.button()) { + // case Qt::LeftButton: + // inputDataFlags = MOUSEEVENTF_LEFTUP; + // break; + // case Qt::RightButton: + // inputDataFlags = MOUSEEVENTF_RIGHTUP; + // break; + // default: + // return true; + // } + // break; + // case QEvent::TabletMove: + // default: + // inputDataFlags = MOUSEEVENTF_MOVE; + // break; + // } + // INPUT inputData = {}; + // inputData.type = INPUT_MOUSE; + // inputData.mi.dx = penInfo.pointerInfo.ptPixelLocationRaw.x; + // inputData.mi.dy = penInfo.pointerInfo.ptPixelLocationRaw.y; + // inputData.mi.dwFlags = inputDataFlags | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE_NOCOALESCE; + // //inputData.mi.dwExtraInfo = + // UINT result2 = SendInput(1, &inputData, sizeof(inputData)); + // if (result2 != 1) { + // qDebug() << "SendInput failed, err" << GetLastError(); + // return true; + // } + return true; +} + +bool sendPositionalTabletEvent(QWidget *target, const QEvent::Type eventType, const POINTER_PEN_INFO &penInfo, const PointerDeviceItem &device, const PenPointerItem &penPointerItem, const bool shouldSynthesizeMouseEvent = true) { KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE( eventType == QEvent::TabletMove || eventType == QEvent::TabletPress || eventType == QEvent::TabletRelease, @@ -634,7 +706,10 @@ bool sendPositionalTabletEvent(QWidget *target, const QEvent::Type eventType, co ev.setAccepted(false); ev.setTimestamp(penInfo.pointerInfo.dwTime); QCoreApplication::sendEvent(target, &ev); - return ev.isAccepted(); + if (!shouldSynthesizeMouseEvent) { + return true; + } + return synthesizeMouseEvent(target, ev, penInfo); } bool handlePenEnterMsg(const POINTER_PEN_INFO &penInfo) @@ -698,7 +773,7 @@ bool handlePenLeaveMsg(const POINTER_PEN_INFO &penInfo) return false; } -bool handleSinglePenUpdate(PenPointerItem &penPointerItem, const POINTER_PEN_INFO &penInfo, const PointerDeviceItem &device) +bool handleSinglePenUpdate(PenPointerItem &penPointerItem, const POINTER_PEN_INFO &penInfo, const PointerDeviceItem &device, const bool shouldSynthesizeMouseEvent) { QWidget *targetWidget; if (penPointerItem.isCaptured()) { @@ -745,7 +820,7 @@ bool handleSinglePenUpdate(PenPointerItem &penPointerItem, const POINTER_PEN_INF // penPointerItem.activeWidget = targetWidget; } - bool handled = sendPositionalTabletEvent(targetWidget, QEvent::TabletMove, penInfo, device, penPointerItem); + bool handled = sendPositionalTabletEvent(targetWidget, QEvent::TabletMove, penInfo, device, penPointerItem, shouldSynthesizeMouseEvent); if (!handled) { // dbgTablet << "Target widget doesn't want pen events"; } @@ -783,12 +858,13 @@ bool handlePenUpdateMsg(const POINTER_PEN_INFO &penInfo) // The returned array is in reverse chronological order const auto rbegin = penInfoArray.rbegin(); const auto rend = penInfoArray.rend(); + const auto rlast = rend - 1; // Only synthesize mouse event for the last one for (auto it = rbegin; it != rend; ++it) { - handled |= handleSinglePenUpdate(*currentPointerIt, *it, *devIt); // Bitwise OR doesn't short circuit + handled |= handleSinglePenUpdate(*currentPointerIt, *it, *devIt, it == rlast); // Bitwise OR doesn't short circuit } return handled; } else { - return handleSinglePenUpdate(*currentPointerIt, penInfo, *devIt); + return handleSinglePenUpdate(*currentPointerIt, penInfo, *devIt, true); } } @@ -979,9 +1055,7 @@ bool handlePointerMsg(const MSG &msg) case WM_POINTERLEAVE: return handlePenLeaveMsg(penInfo); case WM_POINTERUPDATE: - // HACK: Force further processing to force Windows to generate mouse move events - handlePenUpdateMsg(penInfo); - return false; + return handlePenUpdateMsg(penInfo); case WM_POINTERCAPTURECHANGED: // TODO: Should this event be handled? dbgTablet << "FIXME: WM_POINTERCAPTURECHANGED isn't handled";