Warning, /graphics/krita/3rdparty/ext_qt/0051-Add-workaround-for-handling-table-press-correctly-in.patch is written in an unsupported language. File is not indexed.

0001 From d27aa35ac1cf870157e957eae4c58ab69662b665 Mon Sep 17 00:00:00 2001
0002 From: Dmitry Kazakov <dimula73@gmail.com>
0003 Date: Wed, 15 May 2019 19:54:52 +0300
0004 Subject: [PATCH 12/47] Add workaround for handling table press correctly in
0005  WinInk mode
0006 
0007 Original problem: widgets do not get synthesized mouse-down and
0008 mouse-press events until the stylus is released
0009 
0010 Reason: if the app accepts the event, WndProc should report
0011 that to the system (by returning true). This is the only way to
0012 prevent Windows from starting some system-wide gestures, like
0013 click+hold -> right button click. If we ignore the event, then
0014 OS postpones all synthesized mouse events until the entire gesture
0015 is completed.
0016 
0017 The patch implements a "hackish" workaround for the original problem
0018 by using the following rules:
0019 
0020 1) All tablet-move events are ignored (without synthesized mouse events
0021    OS doesn't generate any Enter/Leave events)
0022 
0023 2) All not-accepted tablet press- and release-events and also reported as
0024    ignored (without it D&D doesn't work).
0025 
0026 3) All accepted tablet press- and release-events are reported as "accepted",
0027    **but** we artificially synthesize mouse events for them.
0028 
0029 TODO: there are still one problem:
0030 
0031 1) Perhaps this synthesizeMouseEvent() is not needed at all. But we should
0032    first check if Qt relies on these synthesized messages anywhere in the
0033    code or not.
0034 
0035 See bug: https://bugs.kde.org/show_bug.cgi?id=406668
0036 ---
0037  src/gui/kernel/qguiapplication.cpp            |  1 +
0038  src/gui/kernel/qwindowsysteminterface.cpp     | 20 ++---
0039  src/gui/kernel/qwindowsysteminterface.h       |  8 +-
0040  .../windows/qwindowspointerhandler.cpp        | 88 ++++++++++++++++++-
0041  4 files changed, 99 insertions(+), 18 deletions(-)
0042 
0043 diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
0044 index 0f574ff526..a86bd22588 100644
0045 --- a/src/gui/kernel/qguiapplication.cpp
0046 +++ b/src/gui/kernel/qguiapplication.cpp
0047 @@ -2593,6 +2593,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
0048      tabletEvent.setTimestamp(e->timestamp);
0049      QGuiApplication::sendSpontaneousEvent(window, &tabletEvent);
0050      pointData.state = e->buttons;
0051 +    e->eventAccepted = tabletEvent.isAccepted();
0052      if (!tabletEvent.isAccepted()
0053          && !QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse
0054          && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) {
0055 diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
0056 index 2900cb40ea..62f309a1da 100644
0057 --- a/src/gui/kernel/qwindowsysteminterface.cpp
0058 +++ b/src/gui/kernel/qwindowsysteminterface.cpp
0059 @@ -954,7 +954,7 @@ void QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(boo
0060      platformSynthesizesMouse = v;
0061  }
0062  
0063 -void QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global,
0064 +bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global,
0065                                                 int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
0066                                                 qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0067                                                 Qt::KeyboardModifiers modifiers)
0068 @@ -965,36 +965,36 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp,
0069                                                         QHighDpi::fromNativePixels(global, window),
0070                                                         device, pointerType, buttons, pressure,
0071                                                         xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0072 -    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
0073 +    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::SynchronousDelivery>(e);
0074  }
0075  
0076 -void QWindowSystemInterface::handleTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
0077 +bool QWindowSystemInterface::handleTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
0078                                                 int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
0079                                                 qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0080                                                 Qt::KeyboardModifiers modifiers)
0081  {
0082      ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
0083 -    handleTabletEvent(window, time, local, global, device, pointerType, buttons, pressure,
0084 +    return handleTabletEvent(window, time, local, global, device, pointerType, buttons, pressure,
0085                        xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0086  }
0087  
0088  #if QT_DEPRECATED_SINCE(5, 10)
0089 -void QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
0090 +bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
0091                                                 int device, int pointerType, qreal pressure, int xTilt, int yTilt,
0092                                                 qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0093                                                 Qt::KeyboardModifiers modifiers)
0094  {
0095 -    handleTabletEvent(window, timestamp, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
0096 -                      xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0097 +    return handleTabletEvent(window, timestamp, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
0098 +                             xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0099  }
0100  
0101 -void QWindowSystemInterface::handleTabletEvent(QWindow *window, bool down, const QPointF &local, const QPointF &global,
0102 +bool QWindowSystemInterface::handleTabletEvent(QWindow *window, bool down, const QPointF &local, const QPointF &global,
0103                                                 int device, int pointerType, qreal pressure, int xTilt, int yTilt,
0104                                                 qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0105                                                 Qt::KeyboardModifiers modifiers)
0106  {
0107 -    handleTabletEvent(window, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
0108 -                      xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0109 +    return handleTabletEvent(window, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
0110 +                             xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
0111  }
0112  #endif // QT_DEPRECATED_SINCE(5, 10)
0113  
0114 diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
0115 index 66af163f05..8d1e7597a1 100644
0116 --- a/src/gui/kernel/qwindowsysteminterface.h
0117 +++ b/src/gui/kernel/qwindowsysteminterface.h
0118 @@ -247,20 +247,20 @@ public:
0119      static void handleFileOpenEvent(const QString& fileName);
0120      static void handleFileOpenEvent(const QUrl &url);
0121  
0122 -    static void handleTabletEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global,
0123 +    static bool handleTabletEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global,
0124                                    int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
0125                                    qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0126                                    Qt::KeyboardModifiers modifiers = Qt::NoModifier);
0127 -    static void handleTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
0128 +    static bool handleTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
0129                                    int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
0130                                    qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0131                                    Qt::KeyboardModifiers modifiers = Qt::NoModifier);
0132  #if QT_DEPRECATED_SINCE(5, 10)
0133 -    QT_DEPRECATED static void handleTabletEvent(QWindow *window, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
0134 +    QT_DEPRECATED static bool handleTabletEvent(QWindow *window, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
0135                                                  int device, int pointerType, qreal pressure, int xTilt, int yTilt,
0136                                                  qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0137                                                  Qt::KeyboardModifiers modifiers = Qt::NoModifier);
0138 -    QT_DEPRECATED static void handleTabletEvent(QWindow *window, bool down, const QPointF &local, const QPointF &global,
0139 +    QT_DEPRECATED static bool handleTabletEvent(QWindow *window, bool down, const QPointF &local, const QPointF &global,
0140                                                  int device, int pointerType, qreal pressure, int xTilt, int yTilt,
0141                                                  qreal tangentialPressure, qreal rotation, int z, qint64 uid,
0142                                                  Qt::KeyboardModifiers modifiers = Qt::NoModifier);
0143 diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
0144 index 71a09304c5..07a5722de9 100644
0145 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
0146 +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
0147 @@ -543,6 +543,58 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
0148      return false; // Allow mouse messages to be generated.
0149  }
0150  
0151 +void synthesizeMouseEvent(QEvent::Type type, Qt::MouseButton button, const POINTER_PEN_INFO &penInfo)
0152 +{
0153 +    // Update the cursor position
0154 +    BOOL result = SetCursorPos(penInfo.pointerInfo.ptPixelLocationRaw.x, penInfo.pointerInfo.ptPixelLocationRaw.y);
0155 +    if (!result) {
0156 +        qCDebug(lcQpaEvents).noquote().nospace() << showbase
0157 +            << __FUNCTION__ << "SetCursorPos failed, err" << GetLastError();
0158 +        return;
0159 +    }
0160 +    // Send mousebutton down/up events. Windows stores the button state.
0161 +    DWORD inputDataFlags = 0;
0162 +    switch (type) {
0163 +    case QEvent::TabletPress:
0164 +        switch (button) {
0165 +        case Qt::LeftButton:
0166 +            inputDataFlags = MOUSEEVENTF_LEFTDOWN;
0167 +            break;
0168 +        case Qt::RightButton:
0169 +            inputDataFlags = MOUSEEVENTF_RIGHTDOWN;
0170 +            break;
0171 +        default:
0172 +            return;
0173 +        }
0174 +        break;
0175 +    case QEvent::TabletRelease:
0176 +        switch (button) {
0177 +        case Qt::LeftButton:
0178 +            inputDataFlags = MOUSEEVENTF_LEFTUP;
0179 +            break;
0180 +        case Qt::RightButton:
0181 +            inputDataFlags = MOUSEEVENTF_RIGHTUP;
0182 +            break;
0183 +        default:
0184 +            return;
0185 +        }
0186 +        break;
0187 +    case QEvent::TabletMove:
0188 +    default:
0189 +        return;
0190 +    }
0191 +    INPUT inputData = {};
0192 +    inputData.type = INPUT_MOUSE;
0193 +    inputData.mi.dwFlags = inputDataFlags;
0194 +    inputData.mi.dwExtraInfo = 0xFF515700 | 0x01; // https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320%28v=vs.85%29.aspx
0195 +    UINT result2 = SendInput(1, &inputData, sizeof(inputData));
0196 +    if (result2 != 1) {
0197 +        qCDebug(lcQpaEvents).noquote().nospace() << showbase
0198 +            << __FUNCTION__ << "SendInput failed, err" << GetLastError();
0199 +        return;
0200 +    }
0201 +}
0202 +
0203  bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et,
0204                                                 MSG msg, PVOID vPenInfo)
0205  {
0206 @@ -633,10 +685,38 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
0207          }
0208          const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
0209  
0210 -        QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
0211 -                                                  pressure, xTilt, yTilt, tangentialPressure, rotation, z,
0212 -                                                  sourceDevice, keyModifiers);
0213 -        return false;  // Allow mouse messages to be generated.
0214 +        const Qt::MouseButtons oldButtons = QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).state;
0215 +
0216 +        const bool accepted =
0217 +            QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
0218 +                                                      pressure, xTilt, yTilt, tangentialPressure, rotation, z,
0219 +                                                      sourceDevice, keyModifiers);
0220 +
0221 +        const Qt::MouseButtons changedButtons =
0222 +            oldButtons ^ QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).state;
0223 +
0224 +        Qt::MouseButton pressedButton = Qt::NoButton;
0225 +
0226 +        const QVector<Qt::MouseButton> supportedButtons =
0227 +            {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton};
0228 +
0229 +        for (Qt::MouseButton button : supportedButtons) {
0230 +            if (changedButtons & button) {
0231 +                pressedButton = button;
0232 +                break;
0233 +            }
0234 +        }
0235 +
0236 +        if (accepted && pressedButton != Qt::NoButton &&
0237 +            (msg.message == WM_POINTERDOWN || msg.message == WM_POINTERUP)) {
0238 +
0239 +            QEvent::Type type = (msg.message == WM_POINTERDOWN) ? QEvent::TabletPress : QEvent::TabletRelease;
0240 +
0241 +            synthesizeMouseEvent(type, pressedButton, *penInfo);
0242 +            return true;
0243 +        } else {
0244 +            return false; // Allow mouse messages to be generated by OS
0245 +        }
0246      }
0247      }
0248      return true;
0249 -- 
0250 2.20.1.windows.1
0251