src/gui/kernel/qapplication.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
--- a/src/gui/kernel/qapplication.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/gui/kernel/qapplication.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -154,14 +154,6 @@
 bool QApplicationPrivate::autoSipEnabled = true;
 #endif
 
-QGestureManager* QGestureManager::instance()
-{
-    QApplicationPrivate *d = qApp->d_func();
-    if (!d->gestureManager)
-        d->gestureManager = new QGestureManager(qApp);
-    return d->gestureManager;
-}
-
 QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type)
     : QCoreApplicationPrivate(argc, argv)
 {
@@ -185,7 +177,7 @@
     directPainters = 0;
 #endif
 
-    gestureManager = 0;
+    gestureWidget = 0;
 
     if (!self)
         self = this;
@@ -474,9 +466,6 @@
 bool QApplicationPrivate::animate_toolbox = false;
 bool QApplicationPrivate::widgetCount = false;
 bool QApplicationPrivate::load_testability = false;
-#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
-bool QApplicationPrivate::inSizeMove = false;
-#endif
 #ifdef QT_KEYPAD_NAVIGATION
 #  ifdef Q_OS_SYMBIAN
 Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
@@ -802,7 +791,8 @@
     }
 
     //make sure the plugin is loaded
-    qt_guiPlatformPlugin();
+    if (qt_is_gui_used)
+        qt_guiPlatformPlugin();
 #endif
 }
 
@@ -940,14 +930,11 @@
     graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
 #endif
 #ifndef QT_NO_WHEELEVENT
-#ifdef Q_OS_MAC
-    QApplicationPrivate::wheel_scroll_lines = 1;
-#else
     QApplicationPrivate::wheel_scroll_lines = 3;
 #endif
-#endif
-
-    initializeMultitouch();
+
+    if (qt_is_gui_used)
+        initializeMultitouch();
 }
 
 /*!
@@ -2085,7 +2072,7 @@
         }
         QWidget *prev = focus_widget;
         focus_widget = focus;
-
+#ifndef QT_NO_IM
         if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
             && prev->testAttribute(Qt::WA_InputMethodEnabled))
             // Do reset the input context, in case the new focus widget won't accept keyboard input
@@ -2098,6 +2085,7 @@
                 qic->setFocusWidget(0);
             }
         }
+#endif //QT_NO_IM
 
         if(focus_widget)
             focus_widget->d_func()->setFocus_sys();
@@ -2108,7 +2096,11 @@
             if (prev) {
 #ifdef QT_KEYPAD_NAVIGATION
                 if (QApplication::keypadNavigationEnabled()) {
-                    if (prev->hasEditFocus() && reason != Qt::PopupFocusReason)
+                    if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+                            && reason != Qt::ActiveWindowFocusReason
+#endif
+                            )
                         prev->setEditFocus(false);
                 }
 #endif
@@ -2129,12 +2121,14 @@
                     QApplication::sendEvent(that->style(), &out);
             }
             if(focus && QApplicationPrivate::focus_widget == focus) {
+#ifndef QT_NO_IM
                 if (focus->testAttribute(Qt::WA_InputMethodEnabled)) {
                     QInputContext *qic = focus->inputContext();
                     if (qic && focus->testAttribute(Qt::WA_WState_Created)
                         && focus->isEnabled())
                         qic->setFocusWidget(focus);
                 }
+#endif //QT_NO_IM
                 QFocusEvent in(QEvent::FocusIn, reason);
                 QPointer<QWidget> that = focus;
                 QApplication::sendEvent(focus, &in);
@@ -3638,13 +3632,47 @@
     }
 
     // walk through parents and check for gestures
-    if (d->gestureManager) {
-        if (receiver->isWidgetType()) {
-            if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
-                return true;
-        } else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
-            if (d->gestureManager->filterEvent(gesture, e))
-                return true;
+    if (qt_gestureManager) {
+        switch (e->type()) {
+        case QEvent::Paint:
+        case QEvent::MetaCall:
+        case QEvent::DeferredDelete:
+        case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
+        case QEvent::Drop: case QEvent::DragResponse:
+        case QEvent::ChildAdded: case QEvent::ChildPolished:
+#ifdef QT3_SUPPORT
+        case QEvent::ChildInsertedRequest:
+        case QEvent::ChildInserted:
+        case QEvent::LayoutHint:
+#endif
+        case QEvent::ChildRemoved:
+        case QEvent::UpdateRequest:
+        case QEvent::UpdateLater:
+        case QEvent::AccessibilityPrepare:
+        case QEvent::LocaleChange:
+        case QEvent::Style:
+        case QEvent::IconDrag:
+        case QEvent::StyleChange:
+        case QEvent::AccessibilityHelp:
+        case QEvent::AccessibilityDescription:
+        case QEvent::GraphicsSceneDragEnter:
+        case QEvent::GraphicsSceneDragMove:
+        case QEvent::GraphicsSceneDragLeave:
+        case QEvent::GraphicsSceneDrop:
+        case QEvent::DynamicPropertyChange:
+        case QEvent::NetworkReplyUpdated:
+            break;
+        default:
+            if (receiver->isWidgetType()) {
+                if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+                    return true;
+            } else {
+                // a special case for events that go to QGesture objects.
+                // We pass the object to the gesture manager and it'll figure
+                // out if it's QGesture or not.
+                if (qt_gestureManager->filterEvent(receiver, e))
+                    return true;
+            }
         }
     }
 
@@ -4102,9 +4130,15 @@
             bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
             touchEvent->setWidget(widget);
             touchEvent->setAccepted(acceptTouchEvents);
+            QWeakPointer<QWidget> p = widget;
             res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
             eventAccepted = touchEvent->isAccepted();
-            widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+            if (p.isNull()) {
+                // widget was deleted
+                widget = 0;
+            } else {
+                widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+            }
             touchEvent->spont = false;
             if (res && eventAccepted) {
                 // the first widget to accept the TouchBegin gets an implicit grab.
@@ -4113,11 +4147,20 @@
                     d->widgetForTouchPointId[touchPoint.id()] = widget;
                 }
                 break;
-            } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
+            } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
                 break;
             }
+            QPoint offset = widget->pos();
             widget = widget->parentWidget();
-            d->updateTouchPointsForWidget(widget, touchEvent);
+            touchEvent->setWidget(widget);
+            for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
+                QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
+                QRectF rect = pt.rect();
+                rect.moveCenter(offset);
+                pt.d->rect = rect;
+                pt.d->startPos = pt.startPos() + offset;
+                pt.d->lastPos = pt.lastPos() + offset;
+            }
         }
 
         touchEvent->setAccepted(eventAccepted);
@@ -4156,7 +4199,7 @@
         if (receiver->isWidgetType()) {
             QWidget *w = static_cast<QWidget *>(receiver);
             QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
-            QList<QGesture *> allGestures = gestureEvent->allGestures();
+            QList<QGesture *> allGestures = gestureEvent->gestures();
 
             bool eventAccepted = gestureEvent->isAccepted();
             bool wasAccepted = eventAccepted;
@@ -4167,7 +4210,12 @@
                 for (int i = 0; i < allGestures.size();) {
                     QGesture *g = allGestures.at(i);
                     Qt::GestureType type = g->gestureType();
-                    if (wd->gestureContext.contains(type)) {
+                    QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
+                            wd->gestureContext.find(type);
+                    bool deliver = contextit != wd->gestureContext.end() &&
+                        (g->state() == Qt::GestureStarted || w == receiver ||
+                         (contextit.value() & Qt::ReceivePartialGestures));
+                    if (deliver) {
                         allGestures.removeAt(i);
                         gestures.append(g);
                     } else {
@@ -5423,9 +5471,11 @@
         const QPointF delta = screenPos - screenPos.toPoint();
 
         rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
-        touchPoint.setRect(rect);
-        touchPoint.setStartPos(widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta);
-        touchPoint.setLastPos(widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta);
+        touchPoint.d->rect = rect;
+        if (touchPoint.state() == Qt::TouchPointPressed) {
+            touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
+            touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
+        }
     }
 }
 
@@ -5469,16 +5519,20 @@
 
     for (int i = 0; i < touchPoints.count(); ++i) {
         QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
+        // explicitly detach from the original touch point that we got, so even
+        // if the touchpoint structs are reused, we will make a copy that we'll
+        // deliver to the user (which might want to store the struct for later use).
+        touchPoint.d = touchPoint.d->detach();
 
         // update state
-        QWidget *widget = 0;
+        QWeakPointer<QWidget> widget;
         switch (touchPoint.state()) {
         case Qt::TouchPointPressed:
         {
             if (deviceType == QTouchEvent::TouchPad) {
                 // on touch-pads, send all touch points to the same widget
                 widget = d->widgetForTouchPointId.isEmpty()
-                         ? 0
+                         ? QWeakPointer<QWidget>()
                          : d->widgetForTouchPointId.constBegin().value();
             }
 
@@ -5495,20 +5549,21 @@
 
             if (deviceType == QTouchEvent::TouchScreen) {
                 int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
-                QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId);
+                QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
                 if (closestWidget
-                    && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
+                    && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
                     widget = closestWidget;
                 }
             }
 
             d->widgetForTouchPointId[touchPoint.id()] = widget;
-            touchPoint.setStartScreenPos(touchPoint.screenPos());
-            touchPoint.setLastScreenPos(touchPoint.screenPos());
-            touchPoint.setStartNormalizedPos(touchPoint.normalizedPos());
-            touchPoint.setLastNormalizedPos(touchPoint.normalizedPos());
+            touchPoint.d->startScreenPos = touchPoint.screenPos();
+            touchPoint.d->lastScreenPos = touchPoint.screenPos();
+            touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
+            touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
             if (touchPoint.pressure() < qreal(0.))
-                touchPoint.setPressure(qreal(1.));
+                touchPoint.d->pressure = qreal(1.);
+
             d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
             break;
         }
@@ -5519,12 +5574,14 @@
                 continue;
 
             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
-            touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
-            touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
-            touchPoint.setStartNormalizedPos(previousTouchPoint.startNormalizedPos());
-            touchPoint.setLastNormalizedPos(previousTouchPoint.normalizedPos());
+            touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+            touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+            touchPoint.d->startPos = previousTouchPoint.startPos();
+            touchPoint.d->lastPos = previousTouchPoint.pos();
+            touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+            touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
             if (touchPoint.pressure() < qreal(0.))
-                touchPoint.setPressure(qreal(0.));
+                touchPoint.d->pressure = qreal(0.);
             break;
         }
         default:
@@ -5534,23 +5591,25 @@
 
             Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
-            touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
-            touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
-            touchPoint.setStartNormalizedPos(previousTouchPoint.startNormalizedPos());
-            touchPoint.setLastNormalizedPos(previousTouchPoint.normalizedPos());
+            touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+            touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+            touchPoint.d->startPos = previousTouchPoint.startPos();
+            touchPoint.d->lastPos = previousTouchPoint.pos();
+            touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+            touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
             if (touchPoint.pressure() < qreal(0.))
-                touchPoint.setPressure(qreal(1.));
+                touchPoint.d->pressure = qreal(1.);
             d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
             break;
         }
-        Q_ASSERT(widget != 0);
+        Q_ASSERT(widget.data() != 0);
 
         // make the *scene* functions return the same as the *screen* functions
-        touchPoint.setSceneRect(touchPoint.screenRect());
-        touchPoint.setStartScenePos(touchPoint.startScreenPos());
-        touchPoint.setLastScenePos(touchPoint.lastScreenPos());
-
-        StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget];
+        touchPoint.d->sceneRect = touchPoint.screenRect();
+        touchPoint.d->startScenePos = touchPoint.startScreenPos();
+        touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
+
+        StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
         maskAndPoints.first |= touchPoint.state();
         if (touchPoint.isPrimary())
             maskAndPoints.first |= Qt::TouchPointPrimary;
@@ -5617,37 +5676,6 @@
     QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
 }
 
-/*!
-    \since 4.6
-
-    Registers the given \a recognizer in the gesture framework and returns a gesture ID
-    for it.
-
-    The application takes ownership of the \a recognizer and returns the gesture type
-    ID associated with it. For gesture recognizers which handle custom QGesture
-    objects (i.e., those which return Qt::CustomGesture in a QGesture::gestureType()
-    function) the return value is a gesture ID between Qt::CustomGesture and
-    Qt::LastGestureType, inclusive.
-
-    \sa unregisterGestureRecognizer(), QGestureRecognizer::createGesture(), QGesture
-*/
-Qt::GestureType QApplication::registerGestureRecognizer(QGestureRecognizer *recognizer)
-{
-    return QGestureManager::instance()->registerGestureRecognizer(recognizer);
-}
-
-/*!
-    \since 4.6
-
-    Unregisters all gesture recognizers of the specified \a type.
-
-    \sa registerGestureRecognizer()
-*/
-void QApplication::unregisterGestureRecognizer(Qt::GestureType type)
-{
-    QGestureManager::instance()->unregisterGestureRecognizer(type);
-}
-
 QT_END_NAMESPACE
 
 #include "moc_qapplication.cpp"