diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 39 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 48 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 7 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaview_mac.mm | 9 | ||||
-rw-r--r-- | src/gui/kernel/qevent.cpp | 32 | ||||
-rw-r--r-- | src/gui/kernel/qevent.h | 11 |
9 files changed, 110 insertions, 42 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6998429..fb3a01c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -6054,18 +6054,32 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) // update state QGraphicsItem *item = 0; if (touchPoint.state() == Qt::TouchPointPressed) { - // determine which item this event will go to - cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(), - touchPoint.scenePos(), - sceneTouchEvent->widget()); - item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first(); - int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos()); - QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId); - if (!item - || (closestItem - && (item->isAncestorOf(closestItem) - || closestItem->isAncestorOf(item)))) { - item = closestItem; + if (sceneTouchEvent->deviceType() == QTouchEvent::TouchPad) { + // on touch-pad devices, send all touch points to the same item + item = itemForTouchPointId.isEmpty() + ? 0 + : itemForTouchPointId.constBegin().value(); + } + + if (!item) { + // determine which item this touch point will go to + cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(), + touchPoint.scenePos(), + sceneTouchEvent->widget()); + item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first(); + } + + if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) { + // on touch-screens, combine this touch point with the closest one we find if it + // is a a direct descendent or ancestor ( + int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos()); + QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId); + if (!item + || (closestItem + && (item->isAncestorOf(closestItem) + || closestItem->isAncestorOf(item)))) { + item = closestItem; + } } if (!item) continue; @@ -6124,6 +6138,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) QTouchEvent touchEvent(eventType); touchEvent.setWidget(sceneTouchEvent->widget()); + touchEvent.setDeviceType(sceneTouchEvent->deviceType()); touchEvent.setModifiers(sceneTouchEvent->modifiers()); touchEvent.setTouchPointStates(it.value().first); touchEvent.setTouchPoints(it.value().second); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index ebc854f..3c3a811 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -317,7 +317,7 @@ public: void sendGestureEvent(const QSet<QGesture*> &gestures, const QSet<QString> &cancelled); QMap<int, QTouchEvent::TouchPoint> sceneCurrentTouchPoints; - QHash<int, QGraphicsItem *> itemForTouchPointId; + QMap<int, QGraphicsItem *> itemForTouchPointId; static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent); int findClosestTouchPointId(const QPointF &scenePos); void touchEventHandler(QTouchEvent *touchEvent); diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 9a22fd5..0b01b73 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5296,6 +5296,7 @@ int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos) } void QApplicationPrivate::translateRawTouchEvent(QWidget *window, + QTouchEvent::DeviceType deviceType, const QList<QTouchEvent::TouchPoint> &touchPoints) { QApplicationPrivate *d = self; @@ -5312,21 +5313,33 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, switch (touchPoint.state()) { case Qt::TouchPointPressed: { - // determine which widget this event will go to - if (!window) - window = q->topLevelAt(touchPoint.screenPos().toPoint()); - if (!window) - continue; - widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint())); - if (!widget) - widget = window; + if (deviceType == QTouchEvent::TouchPad) { + // on touch-pads, send all touch points to the same widget + widget = d->widgetForTouchPointId.isEmpty() + ? 0 + : d->widgetForTouchPointId.constBegin().value(); + } + + if (!widget) { + // determine which widget this event will go to + if (!window) + window = q->topLevelAt(touchPoint.screenPos().toPoint()); + if (!window) + continue; + widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint())); + if (!widget) + widget = window; + } - int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos()); - QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId); - if (closestWidget - && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) { - widget = closestWidget; + if (deviceType == QTouchEvent::TouchScreen) { + int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos()); + QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId); + if (closestWidget + && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) { + widget = closestWidget; + } } + d->widgetForTouchPointId[touchPoint.id()] = widget; touchPoint.setStartScreenPos(touchPoint.screenPos()); touchPoint.setLastScreenPos(touchPoint.screenPos()); @@ -5356,6 +5369,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, widget = d->widgetForTouchPointId.value(touchPoint.id()); if (!widget) continue; + Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id())); QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id()); touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos()); @@ -5408,6 +5422,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, } QTouchEvent touchEvent(eventType, + deviceType, q->keyboardModifiers(), it.value().first, it.value().second); @@ -5433,10 +5448,11 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, } } -Q_GUI_EXPORT void qt_translateRawTouchEvent(const QList<QTouchEvent::TouchPoint> &touchPoints, - QWidget *window) +Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, + QTouchEvent::DeviceType deviceType, + const QList<QTouchEvent::TouchPoint> &touchPoints) { - QApplicationPrivate::translateRawTouchEvent(window, touchPoints); + QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index f2226ce..c5d9235 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -437,7 +437,7 @@ public: // map<gesture name -> number of widget subscribed to it> QMap<QString, int> grabbedGestures; - QHash<int, QWidget *> widgetForTouchPointId; + QMap<int, QWidget *> widgetForTouchPointId; QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints; static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); void initializeMultitouch(); @@ -448,6 +448,7 @@ public: void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint); void removeTouchPoint(int touchPointId); static void translateRawTouchEvent(QWidget *widget, + QTouchEvent::DeviceType deviceType, const QList<QTouchEvent::TouchPoint> &touchPoints); #if defined(Q_WS_WIN) @@ -491,6 +492,10 @@ private: static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy); }; +Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, + QTouchEvent::DeviceType deviceType, + const QList<QTouchEvent::TouchPoint> &touchPoints); + QT_END_NAMESPACE #endif // QAPPLICATION_P_H diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 85b6bf8..0daabde 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -4078,7 +4078,7 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg) touchInputIDToTouchPointID.clear(); } - translateRawTouchEvent(widgetForHwnd, touchPoints); + translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints); return true; } diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 76e76de..9acdf6d 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -6217,7 +6217,7 @@ void QApplicationPrivate::_q_readRX71MultiTouchEvents() for (int i = 0; i < allRX71TouchPoints.count(); ++i) touchPoints.append(allRX71TouchPoints.at(i).touchPoint); - translateRawTouchEvent(0, touchPoints); + translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints); } #else // !QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 827094d..28179b7 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -69,7 +69,6 @@ Q_GLOBAL_STATIC(DnDParams, qMacDnDParams); extern void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos); // qcursor_mac.mm extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp -extern bool qt_translateRawTouchEvent(const QList<QTouchEvent::TouchPoint> &touchPoints, QWidget *window); // qapplication.cpp extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm @@ -874,25 +873,25 @@ extern "C" { - (void)touchesBeganWithEvent:(NSEvent *)event; { bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); } - (void)touchesMovedWithEvent:(NSEvent *)event; { bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); } - (void)touchesEndedWithEvent:(NSEvent *)event; { bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); } - (void)touchesCancelledWithEvent:(NSEvent *)event; { bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); } - (void)magnifyWithEvent:(NSEvent *)event; diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 759aeb9..1d1a73d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3734,15 +3734,39 @@ void QGestureEvent::accept(const QString &type) \since 4.6 */ +/*! \enum QTouchEvent::DeviceType + \since 4.6 + + This enum represents the type of device that generated a QTouchEvent. + + \value TouchScreen In this type of device, the touch surface and display are integrated. This + means the surface and display typically have the same size, such that there + is a direct relationship between the touch points' physical positions and the + coordinate reported by QTouchEvent::TouchPoint. As a result, Qt allows the + user to interact directly with multiple QWidgets and QGraphicsItems at the + same time. + + \value TouchPad In this type of device, the touch surface is separate from the display. There + is not a direct relationship between the physical touch location and the + on-screen coordinates. Instead, they are calculated relative to the current + mouse position, and the user must use the touch-pad to move this reference + point. Unlike touch-screens, Qt allows users to only interact with a single + QWidget or QGraphicsItem at a time. +*/ + /*! - Constructs a QTouchEvent with the given \a type and \a touchPoints. The \a touchPointStates and - \a modifiers are the current touch point states and keyboard modifiers at the time of the event. + Constructs a QTouchEvent with the given \a eventType, \a deviceType, and \a touchPoints. + The \a touchPointStates and \a modifiers are the current touch point states and keyboard + modifiers at the time of the event. */ -QTouchEvent::QTouchEvent(QEvent::Type type, +QTouchEvent::QTouchEvent(QEvent::Type eventType, + QTouchEvent::DeviceType deviceType, Qt::KeyboardModifiers modifiers, Qt::TouchPointStates touchPointStates, const QList<QTouchEvent::TouchPoint> &touchPoints) - : QInputEvent(type, modifiers), + : QInputEvent(eventType, modifiers), + _widget(0), + _deviceType(deviceType), _touchPointStates(touchPointStates), _touchPoints(touchPoints) { } diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 04303fb..146ceed 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -821,23 +821,32 @@ public: QTouchEventTouchPointPrivate *d; }; - QTouchEvent(QEvent::Type type, + enum DeviceType { + TouchScreen, + TouchPad + }; + + QTouchEvent(QEvent::Type eventType, + QTouchEvent::DeviceType deviceType = TouchScreen, Qt::KeyboardModifiers modifiers = Qt::NoModifier, Qt::TouchPointStates touchPointStates = 0, const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>()); ~QTouchEvent(); inline QWidget *widget() const { return _widget; } + inline QTouchEvent::DeviceType deviceType() const { return _deviceType; } inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; } inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; } // internal inline void setWidget(QWidget *widget) { _widget = widget; } + inline void setDeviceType(DeviceType deviceType) { _deviceType = deviceType; } inline void setTouchPointStates(Qt::TouchPointStates touchPointStates) { _touchPointStates = touchPointStates; } inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints) { _touchPoints = touchPoints; } protected: QWidget *_widget; + QTouchEvent::DeviceType _deviceType; Qt::TouchPointStates _touchPointStates; QList<QTouchEvent::TouchPoint> _touchPoints; |