summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-06-18 10:49:11 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-06-18 10:49:11 (GMT)
commit3b04dba36b31360d94583f382b9054bcdea0e2a7 (patch)
treef56d1329980987a21d0c457e21ebb99f820e3ef2 /src/gui/kernel
parent9756f523fd1c31192a87c65449434280a59b49f7 (diff)
downloadQt-3b04dba36b31360d94583f382b9054bcdea0e2a7.zip
Qt-3b04dba36b31360d94583f382b9054bcdea0e2a7.tar.gz
Qt-3b04dba36b31360d94583f382b9054bcdea0e2a7.tar.bz2
Change behavior of how touch and mouse events work together
We now send both types of events, i.e. accepting TouchBegin doesn't block mouse events anymore. We are also introducing the idea of a "primary" touch point, which is the one that the system is also generating mouse events for. This lets us reuse existing mouse event code while still being able to add multi-touch support.
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp22
-rw-r--r--src/gui/kernel/qapplication_p.h2
-rw-r--r--src/gui/kernel/qapplication_win.cpp26
-rw-r--r--src/gui/kernel/qapplication_x11.cpp61
-rw-r--r--src/gui/kernel/qevent.cpp16
-rw-r--r--src/gui/kernel/qevent.h3
-rw-r--r--src/gui/kernel/qevent_p.h2
-rw-r--r--src/gui/kernel/qwidget.cpp37
8 files changed, 76 insertions, 93 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 72acbdc..5ef453d 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -5296,7 +5296,7 @@ int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
return closestTouchPointId;
}
-bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
+void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
const QList<QTouchEvent::TouchPoint> &touchPoints)
{
QApplicationPrivate *d = self;
@@ -5365,13 +5365,13 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget];
maskAndPoints.first |= touchPoint.state();
+ if (touchPoint.isPrimary())
+ maskAndPoints.first |= Qt::TouchPointPrimary;
maskAndPoints.second.append(touchPoint);
}
if (widgetsNeedingEvents.isEmpty())
- return false;
-
- bool returnValue = false;
+ return;
QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
@@ -5381,7 +5381,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
continue;
QEvent::Type eventType;
- switch(it.value().first) {
+ switch (it.value().first & Qt::TouchPointStateMask) {
case Qt::TouchPointPressed:
eventType = QEvent::TouchBegin;
break;
@@ -5402,15 +5402,13 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
it.value().second);
updateTouchPointsForWidget(widget, &touchEvent);
- bool res = false;
switch (touchEvent.type()) {
case QEvent::TouchBegin:
{
// if the TouchBegin handler recurses, we assume that means the event
// has been implicitly accepted and continue to send touch events
widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
- res = QApplication::sendSpontaneousEvent(widget, &touchEvent)
- && touchEvent.isAccepted();
+ (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
break;
}
default:
@@ -5418,20 +5416,16 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
if (touchEvent.type() == QEvent::TouchEnd)
widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
(void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
- res = true;
}
break;
}
- returnValue = returnValue || res;
}
-
- return returnValue;
}
-Q_GUI_EXPORT bool qt_translateRawTouchEvent(const QList<QTouchEvent::TouchPoint> &touchPoints,
+Q_GUI_EXPORT void qt_translateRawTouchEvent(const QList<QTouchEvent::TouchPoint> &touchPoints,
QWidget *window)
{
- return QApplicationPrivate::translateRawTouchEvent(window, touchPoints);
+ QApplicationPrivate::translateRawTouchEvent(window, touchPoints);
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index fcdd353..f2226ce 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -447,7 +447,7 @@ public:
int findClosestTouchPointId(const QPointF &screenPos);
void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
void removeTouchPoint(int touchPointId);
- static bool translateRawTouchEvent(QWidget *widget,
+ static void translateRawTouchEvent(QWidget *widget,
const QList<QTouchEvent::TouchPoint> &touchPoints);
#if defined(Q_WS_WIN)
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 376a449..66dfee2 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -4047,29 +4047,27 @@ bool QApplicationPrivate::translateTouchEvent(const MSG &msg)
qreal(touchInput.cyContact) / qreal(100.)));
screenRect.moveCenter(screenPos);
+ Qt::TouchPointStates state;
if (touchInput.dwFlags & TOUCHEVENTF_DOWN) {
- touchPoint.setState(Qt::TouchPointPressed);
- touchPoint.setScreenPos(screenPos);
- touchPoint.setRect(screenRect);
+ state = Qt::TouchPointPressed;
} else if (touchInput.dwFlags & TOUCHEVENTF_UP) {
- touchPoint.setState(Qt::TouchPointReleased);
- touchPoint.setScreenPos(screenPos);
- touchPoint.setRect(screenRect);
+ state = Qt::TouchPointReleased;
} else {
- touchPoint.setState(screenPos == touchPoint.screenPos()
- ? Qt::TouchPointStationary
- : Qt::TouchPointMoved);
- touchPoint.setScreenPos(screenPos);
- touchPoint.setRect(screenRect);
+ state = (screenPos == touchPoint.screenPos()
+ ? Qt::TouchPointStationary
+ : Qt::TouchPointMoved);
}
+ if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY)
+ state |= Qt::TouchPointPrimary;
+ touchPoint.setState(state);
+ touchPoint.setScreenRect(screenRect);
touchPoints.append(touchPoint);
}
QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam);
- extern bool qt_translateRawTouchEvent(const QList<QTouchEvent::TouchPoint> &, QWidget *);
- qt_tabletChokeMouse = qt_translateRawTouchEvent(touchPoints, widgetForHwnd);
- return qt_tabletChokeMouse;
+ translateRawTouchEvent(widgetForHwnd, touchPoints);
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 79ddded..fef51f9 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -3221,20 +3221,6 @@ int QApplication::x11ProcessEvent(XEvent* event)
Q_D(QApplication);
QScopedLoopLevelCounter loopLevelCounter(d->threadData);
-#ifdef QT_RX71_MULTITOUCH
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- // if multitouch is active, we have to block all pointer events from X11
- if (d->hasRX71MultiTouch)
- return 1;
- break;
- default:
- break;
- }
-#endif
-
#ifdef ALIEN_DEBUG
//qDebug() << "QApplication::x11ProcessEvent:" << event->type;
#endif
@@ -6223,52 +6209,7 @@ void QApplicationPrivate::_q_readRX71MultiTouchEvents()
for (int i = 0; i < allRX71TouchPoints.count(); ++i)
touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
- if (!translateRawTouchEvent(0, touchPoints))
- fakeMouseEventFromRX71TouchEvent();
-}
-
-void QApplicationPrivate::fakeMouseEventFromRX71TouchEvent()
-{
- // we only fake mouse events from the first touch point
- const QTouchEvent::TouchPoint &touchPoint = allRX71TouchPoints.first().touchPoint;
-
- QEvent::Type mouseEventType;
- switch (touchPoint.state()) {
- case Qt::TouchPointPressed:
- mouseEventType = QEvent::MouseButtonPress;
- break;
- case Qt::TouchPointMoved:
- mouseEventType = QEvent::MouseMove;
- break;
- case Qt::TouchPointReleased:
- mouseEventType = QEvent::MouseButtonRelease;
- break;
- case Qt::TouchPointStationary:
- default:
- // finger didn't move, ignore the event
- return;
- }
-
- QPoint screenPos = touchPoint.screenPos().toPoint();
- Q_Q(QApplication);
- QWidget *window = q->activePopupWidget();
- if (!window)
- window = q->topLevelAt(screenPos);
- if (!window)
- return;
-
- QPoint pos = window->mapFromGlobal(screenPos);
- QWidget *widget = window->childAt(pos);
- if (!widget)
- widget = window;
-
- QMouseEvent mouseEvent(mouseEventType,
- pos,
- screenPos,
- Qt::LeftButton,
- Qt::LeftButton,
- q->keyboardModifiers());
- (void) QApplication::sendEvent(widget, &mouseEvent);
+ translateRawTouchEvent(0, touchPoints);
}
#else // !QT_RX71_MULTITOUCH
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c30de7f..c9b9bc8 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3724,6 +3724,9 @@ void QGestureEvent::accept(const QString &type)
\value TouchPointMoved The touch point moved.
\value TouchPointStationary The touch point did not move.
\value TouchPointReleased The touch point was released.
+
+ \omitvalue TouchPointStateMask
+ \omitvalue TouchPointPrimary
*/
/*! \class QTouchEvent::TouchPoint
@@ -3833,7 +3836,16 @@ int QTouchEvent::TouchPoint::id() const
*/
Qt::TouchPointState QTouchEvent::TouchPoint::state() const
{
- return d->state;
+ return Qt::TouchPointState(int(d->state) & Qt::TouchPointStateMask);
+}
+
+/*!
+ Returns true if this touch point is the primary touch point. The primary touch point is the
+ point for which the windowing system generates mouse events.
+*/
+bool QTouchEvent::TouchPoint::isPrimary() const
+{
+ return (d->state & Qt::TouchPointPrimary) != 0;
}
/*!
@@ -3956,7 +3968,7 @@ void QTouchEvent::TouchPoint::setId(int id)
}
/*! \internal */
-void QTouchEvent::TouchPoint::setState(Qt::TouchPointState state)
+void QTouchEvent::TouchPoint::setState(Qt::TouchPointStates state)
{
if (d->ref != 1)
d = d->detach();
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index be7c6d0..ee81e78 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -772,6 +772,7 @@ public:
int id() const;
Qt::TouchPointState state() const;
+ bool isPrimary() const;
QPointF pos() const;
QPointF startPos() const;
@@ -793,7 +794,7 @@ public:
// internal
void setId(int id);
- void setState(Qt::TouchPointState state);
+ void setState(Qt::TouchPointStates state);
void setPos(const QPointF &pos);
void setScenePos(const QPointF &scenePos);
void setScreenPos(const QPointF &screenPos);
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 4c066a3..53d7a23 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -110,7 +110,7 @@ public:
QAtomicInt ref;
int id;
- Qt::TouchPointState state;
+ Qt::TouchPointStates state;
QRectF rect, sceneRect, screenRect;
QPointF startPos, startScenePos, startScreenPos;
QPointF lastPos, lastScenePos, lastScreenPos;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index f05672e..8dd32f5 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -7883,6 +7883,43 @@ bool QWidget::event(QEvent *event)
case QEvent::Gesture:
event->ignore();
break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
+ if (touchPoint.isPrimary())
+ break;
+
+ // fake a mouse event!
+ QEvent::Type eventType = QEvent::None;
+ switch (touchEvent->type()) {
+ case QEvent::TouchBegin:
+ eventType = QEvent::MouseButtonPress;
+ break;
+ case QEvent::TouchUpdate:
+ eventType = QEvent::MouseMove;
+ break;
+ case QEvent::TouchEnd:
+ eventType = QEvent::MouseButtonRelease;
+ break;
+ default:
+ Q_ASSERT(!true);
+ break;
+ }
+ if (eventType == QEvent::None)
+ break;
+
+ QMouseEvent mouseEvent(eventType,
+ touchPoint.pos().toPoint(),
+ touchPoint.screenPos().toPoint(),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ touchEvent->modifiers());
+ (void) QApplication::sendEvent(this, &mouseEvent);
+ break;
+ }
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange: {
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();