Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-77826

Wacom tablet: Cursor input offset from cursor position

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 5.14.1, 5.15.0 Alpha, 6.0.1
    • 5.12.4, 5.13.0
    • None
    • Arch Linux
      openSUSE Tumbleweed (Linux)
    • Linux/X11
    • 1535fc9fb9ddbfce1680979c0634b4fdf8d75fca (qt/qtbase/5.14)

    Description

      Temporary workaround:

      Start afflicted application from command line like this:

      QT_XCB_TABLET_LEGACY_COORDINATES="" application

      Greetings,

      at least four people using at least two different models of Wacom drawing tablets, are experiencing that the cursor/pointer input coordinate is offset from the visible cursor/pointer position on the screen.
      That is, clicks with the tablet do not register at the coordinate where the visible cursor/pointer is on the screen.
      Currently the two tablets are:

      • Wacom One M, connected with a wire.
      • Wacom Intuos 4 (8x13) (PTK-840), connected with a USB wire.

      Please see images here: https://imgur.com/a/jF9Jpxq
      Please see attached image [Screenshot_20190805_145209.png]
      The problem is being discussed on this forum thread: https://bbs.archlinux.org/viewtopic.php?id=248540

      So far, this has been reproduced on the two Linux distributions Arch Linux and openSUSE Tumbleweed. Both rolling releases currently using qt5 5.13.0

      On Arch Linux the problem starts when upgrading from qt5 5.12.3 to 5.12.4, verified in a test installation using the Arch Linux Archive from where the entire system can be reset to the specific full system package set on a specific date.
      On openSUSE the problem starts when upgrading from openSUSE Leap (which uses qt5 5.9.7) to openSUSE Tumbleweed (which uses qt5 5.13.0)
      The problem has likely been introduced by one of these 5 modules, since downgrading these from 5.12.4 to 5.12.3 fixes the problem on Arch Linux:

      • qtbase
      • qtdeclarative
      • qtquickcontrols
      • qtquickcontrols2
      • qtsvg

      Searching the qt source code for files changed between 5.12.3 and 5.12.4, and whos names or contents contain either of the strings "wacom" or "tablet", one particular file seems to have added code that makes calculations on pointer coordinates in relation to screen size and windows:

      • qtbase/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp

      In qt source module subdirectory "qtbase":

      git diff v5.12.3 v5.12.4 src/plugins/platforms/xcb/qxcbconnection_xi2.cpp:

      diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
      index 04ddd3c98c..450706fc53 100644
      --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
      +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
      @@ -240,6 +240,10 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
           } else if (name.contains("uc-logic") && isTablet) {
               tabletData.pointerType = QTabletEvent::Pen;
               dbgType = QLatin1String("pen");
      +    } else if (name.contains("ugee")) {
      +        isTablet = true;
      +        tabletData.pointerType = QTabletEvent::Pen;
      +        dbgType = QLatin1String("pen");
           } else {
               isTablet = false;
           }
      @@ -1208,6 +1212,11 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
           return handled;
       }
       
      +inline qreal scaleOneValuator(qreal normValue, qreal screenMin, qreal screenSize)
      +{
      +    return screenMin + normValue * screenSize;
      +}
      +
       void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
       {
           auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
      @@ -1220,6 +1229,17 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
           QPointF global(fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y));
           double pressure = 0, rotation = 0, tangentialPressure = 0;
           int xTilt = 0, yTilt = 0;
      +    static const bool useValuators = !qEnvironmentVariableIsSet("QT_XCB_TABLET_LEGACY_COORDINATES");
      +
      +    // Valuators' values are relative to the physical size of the current virtual
      +    // screen. Therefore we cannot use QScreen/QWindow geometry and should use
      +    // QPlatformWindow/QPlatformScreen instead.
      +    QRect physicalScreenArea;
      +    if (Q_LIKELY(useValuators)) {
      +        const QList<QPlatformScreen *> siblings = window->screen()->handle()->virtualSiblings();
      +        for (const QPlatformScreen *screen : siblings)
      +            physicalScreenArea |= screen->geometry();
      +    }
       
           for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData->valuatorInfo.begin(),
                   ite = tabletData->valuatorInfo.end(); it != ite; ++it) {
      @@ -1228,6 +1248,20 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
               xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
               double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal);
               switch (valuator) {
      +        case QXcbAtom::AbsX:
      +            if (Q_LIKELY(useValuators)) {
      +                const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width());
      +                global.setX(value);
      +                local.setX(value - window->handle()->geometry().x());
      +            }
      +            break;
      +        case QXcbAtom::AbsY:
      +            if (Q_LIKELY(useValuators)) {
      +                qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height());
      +                global.setY(value);
      +                local.setY(value - window->handle()->geometry().y());
      +            }
      +            break;
               case QXcbAtom::AbsPressure:
                   pressure = normalizedValue;
                   break;
      

       The offset is only there when controlling the cursor with the tablet.
      There is no offset when controlling the cursor with a regular mouse or a touchpad.

      The offset is only in some qt based applications, most seem to not have the offset.
      The offset is not in any non-qt based applications, except for LibreOffice which makes use of qt if run in a qt based environment, like KDE Plasma.
      The offset is only inside the application window. Not in the window manager widgets, like the window title bar with the close button, or the window frames where the window can be resized.

      In a qt environment, like KDE Plasma, a temporary fix for LibreOffice is to start the application forcing it to use gtk3, like this:

      SAL_USE_VCLPLUGIN=gtk3 libreoffice

      When starting LibreOffice in a non-qt environment, like Icewm, there is no offset.

      For some qt based applications there is no offset when sending them to full screen mode.
      In others the offset is reduced in full screen mode, but it is still there.

      When running the KDE System Settings in console, the logs do not indicate any particular warning or error when the problem is triggered.
      However, once the issue appears, when highlighting the left menu entries to make their contextual info appear, this message is logged:

      QWidgetWindow(0x<address>, name="FocusHackWidgetClassWindow") must be a top level window.

      This is the case for both the Activities module and the Connections module, but not for any of the other modules.

      Best regards

      Johnny

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-77826
          # Subject Branch Project Status CR V

          Activity

            People

              srutledg Shawn Rutledge
              johnny1000 Johnny Nielsen
              Votes:
              6 Vote for this issue
              Watchers:
              21 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: