summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp39
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h2
-rw-r--r--src/gui/kernel/qapplication.cpp48
-rw-r--r--src/gui/kernel/qapplication_p.h7
-rw-r--r--src/gui/kernel/qapplication_win.cpp2
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm9
-rw-r--r--src/gui/kernel/qevent.cpp32
-rw-r--r--src/gui/kernel/qevent.h11
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;