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

Using WinTab leads to TWO MouseButtonPress events being synthesize

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.5, 6.7
    • None
    • Windows

    Description

       
      Using Wintab (using the private headers or command line argument) leads to two
      MouseButtonPress events being synthesized.
      This messes up basically anything which toggles a state on press, like Menus for example.

      So far only tested and confirmed with
      XP-Pen devices (Artist Pro 16 and Artist 24 Pro)
      Huion device (HS610)
       
      Example demonstrating the issue with a Button with a menu and a simple button flipping a state on click.
      I also included an ugly workaround with event filters (just accepting the Tablet event was not enough in my tests)
       

      #include <QtGui/private/qguiapplication_p.h>
      #include <QtGui/qpa/qplatformintegration.h>
      #include <QDebug>
      #include <QApplication>
      #include <QPushButton>
      #include <QPainter>
      #include <QTabletEvent>
      #include <QMainWindow>
      #include <QMenu>
      using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
      bool is_wintab_enabled(){
          auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
          return nativeWindowsApp && nativeWindowsApp->isWinTabEnabled();
      }
      void enable_wintab(bool state){
          qDebug() << "Set wintab status to:" << state << "Current: " << is_wintab_enabled();
          if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration()))
              nativeWindowsApp->setWinTabEnabled(state);
          qDebug() << "Post set wintab status to:" << state << "Current: " << is_wintab_enabled();
      }
      
      class MainWindow : public QMainWindow {
          Q_OBJECT
      public:
          MainWindow(QWidget *parent=nullptr) : QMainWindow(parent) {
              setMinimumSize(500, 500);
              // Simple state issue demonstration.
              // Ti all boils down to this issue
              QPushButton *btn = new QPushButton("Click me", this);
              connect(btn, &QPushButton::pressed, this, [this](){
                  state = !state;
                  qDebug() << "Button pressed";
                  update();
              });
              // Demonstrating the issue with a simple menu
              QPushButton *menuButton = new QPushButton("Show menu", this);
              QMenu *menu = new QMenu(menuButton);
              menu->addMenu("TEst 1");
              menu->addMenu("TEst 2");
              menu->addMenu("TEst 3");
              menuButton->setMenu(menu);
              menuButton->move(0, 30);
          }
      protected:
          bool state = false;
          void mousePressEvent(QMouseEvent *event) override {
              // Just to demonstrate the two press events we receive
              QMainWindow::mousePressEvent(event);
              qDebug() << "Mouse pressed" << event->pointingDevice()->pointerType();
          }
          void mouseReleaseEvent(QMouseEvent *event) override {
              // We do NOT get two Release events
              QMainWindow::mouseReleaseEvent(event);
              qDebug() << "Mouse released";
          }
          void paintEvent(QPaintEvent *event) override {
              // Just draw a different background based on state
              QPainter p(this);
              p.fillRect(rect(), state ? Qt::red : Qt::black);
          }
      
      };
      class WinTabClickWorkaround : public QObject{
          Q_OBJECT
      public:
          bool eventFilter(QObject *watched, QEvent *event) override{
              if(event->type() == QEvent::MouseButtonPress){
                  QMouseEvent *evt = static_cast<QMouseEvent*>(event);
                  if(evt->pointingDevice()->pointerType() == QPointingDevice::PointerType::Pen || evt->pointingDevice()->pointerType() == QPointingDevice::PointerType::Eraser){
                      assert(is_wintab_enabled());  // in my experience Windows Ink synthetised mouse events are never this type
                      qDebug() << "Supress mouse";
                      return true;
                  }
              }
              return QObject::eventFilter(watched, event);
          }
      };
      #include "main.moc"
      int main(int argc, char *argv[])
      {
          bool USE_WINTAB = true;
          bool USE_WORKAROUND = false;
      
          QApplication a(argc, argv);
          if(USE_WORKAROUND){
              a.installEventFilter(new WinTabClickWorkaround());
          }
          MainWindow w;
          if(USE_WINTAB){
              enable_wintab(true);
          }
          w.show();
          return a.exec();
      }
      

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            srutledg Shawn Rutledge
            sleepprogger peter lustig
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes