Enable touch events on Mac for MultiPointTouchArea
authorMorten Johan Sørvig <morten.sorvig@digia.com>
Fri, 12 Apr 2013 11:44:56 +0000 (13:44 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 3 May 2013 14:17:51 +0000 (16:17 +0200)
Enabling touch events on a window causes scroll event
lag so we want to avoid avoid it as far as possible.

Enable/disable on scene changes, similar to what we
do for WA_AcceptTouchEvents for widgets.

Task-number: QTBUG-28483

Change-Id: I2e5b5e2b093cccfc5253f7228f5ec0c588c60371
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
src/quick/items/qquickmultipointtoucharea.cpp
src/quick/items/qquickmultipointtoucharea_p.h

index 384c1c7..a6c92ac 100644 (file)
@@ -47,6 +47,7 @@
 #include <QMouseEvent>
 #include <math.h>
 #include <QDebug>
+#include <qpa/qplatformnativeinterface.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -322,6 +323,7 @@ void QQuickTouchPoint::setSceneY(qreal sceneY)
 
 QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
     : QQuickItem(parent),
+      _currentWindow(0),
       _minimumTouchPoints(0),
       _maximumTouchPoints(INT_MAX),
       _stealMouse(false)
@@ -331,6 +333,9 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
     if (qmlVisualTouchDebugging()) {
         setFlag(QQuickItem::ItemHasContents);
     }
+#ifdef Q_OS_MAC
+    connect(this, &QQuickItem::windowChanged, this, &QQuickMultiPointTouchArea::setTouchEventsEnabledForWindow);
+#endif
 }
 
 QQuickMultiPointTouchArea::~QQuickMultiPointTouchArea()
@@ -542,6 +547,27 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p)
     _pressedTouchPoints.append(dtp);
 }
 
+void QQuickMultiPointTouchArea::setTouchEventsEnabledForWindow(QWindow *window)
+{
+#ifdef Q_OS_MAC
+    // Resolve function for enabling touch events from the (cocoa) platform plugin.
+    typedef void (*RegisterTouchWindowFunction)(QWindow *, bool);
+    RegisterTouchWindowFunction registerTouchWindow = reinterpret_cast<RegisterTouchWindowFunction>(
+        QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration("registertouchwindow"));
+    if (!registerTouchWindow)
+        return; // Not necessarily an error, Qt migh be using a different platform plugin.
+
+    // Disable touch on the old window, enable on the new window.
+    if (_currentWindow)
+        registerTouchWindow(_currentWindow, false);
+    if (window)
+        registerTouchWindow(window, true);
+    // Save the current window, setTouchEventsEnabledForWindow will be called
+    // with a null window on disable.
+    _currentWindow = window;
+#endif
+}
+
 void QQuickMultiPointTouchArea::addTouchPrototype(QQuickTouchPoint *prototype)
 {
     int id = _touchPrototypes.count();
index e2ae5ed..afe7d4b 100644 (file)
@@ -251,6 +251,9 @@ protected:
     void grabGesture();
     virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
 
+protected slots:
+    void setTouchEventsEnabledForWindow(QWindow *window);
+
 private:
     void ungrab();
     QMap<int,QQuickTouchPoint*> _touchPrototypes;  //TouchPoints defined in QML
@@ -258,6 +261,7 @@ private:
     QList<QObject*> _releasedTouchPoints;
     QList<QObject*> _pressedTouchPoints;
     QList<QObject*> _movedTouchPoints;
+    QWindow *_currentWindow;
     int _minimumTouchPoints;
     int _maximumTouchPoints;
     bool _stealMouse;