Skip to content

Instantly share code, notes, and snippets.

@zenoalbisser
Created November 7, 2011 12:23
Show Gist options
  • Save zenoalbisser/1344807 to your computer and use it in GitHub Desktop.
Save zenoalbisser/1344807 to your computer and use it in GitHub Desktop.
diff --git a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
index ef38d33..824ad8c 100644
--- a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
@@ -61,20 +61,196 @@ void QtTouchWebPageProxy::renderToCurrentGLContext(const TransformationMatrix& t
drawingArea->paintToCurrentGLContext(transform, opacity);
}
-#if ENABLE(TOUCH_EVENTS)
+//#if ENABLE(TOUCH_EVENTS)
void QtTouchWebPageProxy::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
{
+ const QTouchEvent* touchEvent = event.nativeEvent();
if (wasEventHandled || event.type() == WebEvent::TouchCancel) {
m_panGestureRecognizer.reset();
m_pinchGestureRecognizer.reset();
- } else {
- // Convert the event timestamp from second to millisecond.
- qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
- m_panGestureRecognizer.recognize(event.nativeEvent(), eventTimestampMillis);
- m_pinchGestureRecognizer.recognize(event.nativeEvent());
+
+ printf("### doneWithTouchEvent - wasEventHandled\n");
+ fflush(stdout);
+
+ switch (touchEvent->type()) {
+ case QEvent::TouchBegin:
+ // Handled touch move does not cancel the synthetic click.
+ if (touchEvent->touchPoints().size() != 1)
+ resetTapState();
+ break;
+ case QEvent::TouchUpdate:
+ // If the TouchMove moves further than the threshold, we still cancel the synthetic click.
+ if (m_tapState == SingleTapStarted) {
+ const QTouchEvent::TouchPoint& touchPoint = touchEvent->touchPoints().first();
+ QPointF offset(touchPoint.scenePos() - m_touchBeginEventForTap->touchPoints().first().scenePos());
+ const qreal distX = qAbs(offset.x());
+ const qreal distY = qAbs(offset.y());
+ if (distX > initialTriggerDistanceThreshold || distY > initialTriggerDistanceThreshold)
+ resetTapState();
+ }
+ break;
+ case QEvent::TouchEnd:
+ touchEnd(touchEvent);
+ break;
+ default:
+ break;
+ }
+ } else
+ handleNativeTouchInteraction(event);
+}
+
+void QtTouchWebPageProxy::handleNativeTouchInteraction(const NativeWebTouchEvent& event)
+{
+ const QTouchEvent* touchEvent = event.nativeEvent();
+
+ // Convert the event timestamp from second to millisecond.
+ qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
+ bool gestureRecognized = m_panGestureRecognizer.recognize(touchEvent, eventTimestampMillis);
+ gestureRecognized |= m_pinchGestureRecognizer.recognize(touchEvent);
+
+ if (gestureRecognized || touchEvent->touchPoints().size() != 1)
+ resetTapState();
+ else {
+ switch (touchEvent->type()) {
+ case QEvent::TouchBegin:
+ {
+ ASSERT(m_tapState == NoPointing);
+ ASSERT(!m_tapAndHoldTimer.isActive());
+
+ m_tapAndHoldTimer.start(tapAndHoldTime, this);
+
+ if (m_tapDoubleClickTimer.isActive()) {
+ // Might be double tap.
+ ASSERT(touchBeginEventForTap);
+ m_tapDoubleClickTimer.stop();
+ QPointF lastPosition = m_touchBeginEventForTap->touchPoints().first().screenPos();
+ QPointF newPosition = touchEvent->touchPoints().first().screenPos();
+ if (QLineF(lastPosition, newPosition).length() < maxDoubleTapDistance) {
+ // Double tap.
+ resetAnchorActivationCandidate();
+ m_tapState = DoubleTapStarted;
+ } else {
+ // New unrelated tap.
+ tapTimeout();
+ beginSingleTap(touchEvent);
+ }
+ } else
+ beginSingleTap(touchEvent);
+
+ m_touchBeginEventForTap = adoptPtr(new QTouchEvent(*touchEvent));
+ m_touchBeginEventForTapTimestamp = event.timestamp();
+ break;
+ }
+ case QEvent::TouchEnd:
+ touchEnd(touchEvent);
+ break;
+ default:
+ break;
+ }
}
}
-#endif
+
+void QtTouchWebPageProxy::touchEnd(const QTouchEvent* touchEvent)
+{
+ m_tapAndHoldTimer.stop();
+
+ switch (m_tapState) {
+ case DoubleTapStarted:
+ {
+ ASSERT(!m_tapDoubleClickTimer.isActive());
+ m_tapState = NoPointing;
+
+ const QTouchEvent::TouchPoint& touchPoint = touchEvent->touchPoints().first();
+ QPointF startPosition = touchPoint.startScreenPos();
+ QPointF endPosition = touchPoint.screenPos();
+ if (QLineF(endPosition, startPosition).length() < maxDoubleTapDistance)
+ m_webPageProxy->findZoomableAreaForPoint(touchPoint.pos().toPoint());
+ break;
+ }
+
+ case SingleTapStarted:
+ ASSERT(!m_tapDoubleClickTimer.isActive());
+ m_tapDoubleClickTimer.start(doubleClickInterval, this);
+ m_tapState = NoPointing;
+// emit q->hideAnchorActivationCandidate();
+ break;
+ case TapAndHold:
+ m_tapState = NoPointing;
+ break;
+ case NoPointing:
+ default:
+ break;
+ }
+}
+
+void QtTouchWebPageProxy::tapTimeout()
+{
+ m_tapDoubleClickTimer.stop();
+// m_webPageProxy->handleSyntheticClickForTouch(NativeWebTouchEvent(touchBeginEventForTap.get()));
+ printf("@@@@@ handleSyntheticClickForTouch!!!\n");
+ fflush(stdout);
+ QTouchEvent::TouchPoint tapPoint = m_touchBeginEventForTap->touchPoints().at(0);
+ WebGestureEvent gesture(WebEvent::GestureSingleTap, tapPoint.pos().toPoint(), tapPoint.screenPos().toPoint(), WebEvent::Modifiers(0), 0);
+ m_webPageProxy->handleGestureEvent(gesture);
+ m_touchBeginEventForTap.clear();
+}
+
+void QtTouchWebPageProxy::tapAndHoldTimeout()
+{
+ ASSERT(touchBeginEventForTap);
+ m_tapAndHoldTimer.stop();
+// m_webPageProxy->handleSyntheticRightClickForTouch(NativeWebTouchEvent(touchBeginEventForTap.get()));
+ m_touchBeginEventForTap.clear();
+ resetAnchorActivationCandidate();
+ m_tapState = TapAndHold;
+
+ ASSERT(!m_tapDoubleClickTimer.isActive());
+ // Should not happen, but clean memory just in case.
+ m_tapDoubleClickTimer.stop();
+}
+
+void QtTouchWebPageProxy::resetTapState()
+{
+ if (m_tapDoubleClickTimer.isActive())
+ tapTimeout();
+ resetAnchorActivationCandidate();
+ m_tapState = NoPointing;
+ m_touchBeginEventForTap.clear();
+ m_tapAndHoldTimer.stop();
+}
+
+void QtTouchWebPageProxy::beginSingleTap(const QTouchEvent* touchEvent)
+{
+ m_tapState = SingleTapStarted;
+ printf("@@@@ begin single tap\n");
+ fflush(stdout);
+// m_webPageProxy->sendPotentialActivationNotification(NativeWebTouchEvent(touchEvent));
+ m_touchEventForActivationNotification = adoptPtr(new QTouchEvent(*touchEvent));
+}
+
+void QtTouchWebPageProxy::resetAnchorActivationCandidate()
+{
+ m_delayedActivationNotificationAreas.clear();
+ m_touchEventForActivationNotification.clear();
+// delayedActivationNotificationColor = WebCore::Color::tap;
+// if (m_tapState == SingleTapStarted)
+// emit q->resetAnchorActivationCandidate();
+}
+
+//void QtTouchWebPageProxy::cancelTouchInteraction()
+//{
+// Q_ASSERT(!trackedTouchPoint.isEmpty());
+// resetTapState();
+// directInputReceived = true;
+// if (forwardTouchToPage) {
+// if (isPageSuspended)
+// m_webPageProxy->forwardTouchEventOfGesture(NativeWebTouchEvent::createCancelEvent(trackedTouchPoint.values()));
+// else
+// m_webPageProxy->handleTouchEvent(NativeWebTouchEvent::createCancelEvent(trackedTouchPoint.values()));
+// }
+// trackedTouchPoint.clear();
+//}
+//#endif
bool QtTouchWebPageProxy::handleEvent(QEvent* ev)
{
@@ -88,6 +264,33 @@ bool QtTouchWebPageProxy::handleEvent(QEvent* ev)
return QtWebPageProxy::handleEvent(ev);
}
+void QtTouchWebPageProxy::timerEvent(QTimerEvent* ev)
+{
+ int timerId = ev->timerId();
+// if (timerId == d->tripleClickTimer.timerId())
+// d->tripleClickTimer.stop();
+//#if ENABLE(TOUCH_EVENTS)
+ if (timerId == m_tapDoubleClickTimer.timerId())
+ tapTimeout();
+ else if (timerId == m_tapAndHoldTimer.timerId())
+ tapAndHoldTimeout();
+ else if (timerId == m_delayedActivationNotificationTimer.timerId()) {
+ m_delayedActivationNotificationTimer.stop();
+ // Something canceled the event before the timer fired.
+ if (m_delayedActivationNotificationAreas.isEmpty())
+ return;
+
+// emit showAnchorActivationCandidate(delayedActivationNotificationAreas, delayedActivationNotificationColor);
+ m_delayedActivationNotificationAreas.clear();
+ // If the touch ends before the timer is received.
+// if (m_tapState != SingleTapStarted)
+// emit hideAnchorActivationCandidate();
+ }
+//#endif
+ else
+ QObject::timerEvent(ev);
+}
+
void QtTouchWebPageProxy::setVisibleContentRectAndScale(const QRectF& visibleContentRect, float scale)
{
QRect alignedVisibleContentRect = visibleContentRect.toAlignedRect();
@@ -104,6 +307,8 @@ void QtTouchWebPageProxy::setVisibleContentRectTrajectoryVector(const QPointF& t
void QtTouchWebPageProxy::touchEvent(QTouchEvent* event)
{
+ printf("there is a touchevent\n");
+ fflush(stdout);
#if ENABLE(TOUCH_EVENTS)
m_webPageProxy->handleTouchEvent(NativeWebTouchEvent(event));
event->accept();
diff --git a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
index b125a8f3..1e35183 100644
--- a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
+++ b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
@@ -29,6 +29,13 @@
#include "QtWebPageProxy.h"
#include <wtf/PassOwnPtr.h>
+const qreal initialTriggerDistanceThreshold = 5.;
+const int tapAndHoldTime = 800;
+const int doubleClickInterval = 400;
+const int activationNotificationDelay = 100;
+const qreal maxDoubleTapDistance = 120.f;
+static const double touchUpdateThrottleInterval = 100.;
+
namespace WebKit {
class QtViewportInteractionEngine;
}
@@ -40,6 +47,7 @@ public:
QtTouchWebPageProxy(QtTouchViewInterface*, QtViewportInteractionEngine*);
virtual bool handleEvent(QEvent*);
+ virtual void timerEvent(QTimerEvent*);
void setVisibleContentRectAndScale(const QRectF&, float);
void setVisibleContentRectTrajectoryVector(const QPointF&);
@@ -53,14 +61,39 @@ protected:
private:
virtual PassOwnPtr<DrawingAreaProxy> createDrawingAreaProxy();
virtual void processDidCrash();
-#if ENABLE(TOUCH_EVENTS)
+//#if ENABLE(TOUCH_EVENTS)
virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled);
-#endif
+ void handleNativeTouchInteraction(const NativeWebTouchEvent&);
+//#endif
QtTouchViewInterface* touchViewInterface() const { return static_cast<QtTouchViewInterface*>(m_viewInterface); }
void touchEvent(QTouchEvent*);
+//#if ENABLE(TOUCH_EVENTS)
+ void tapTimeout();
+ void tapAndHoldTimeout();
+ void resetTapState();
+ void beginSingleTap(const QTouchEvent*);
+ void resetAnchorActivationCandidate();
+ void touchEnd(const QTouchEvent*);
+// void cancelTouchInteraction();
+// void syntheticWheelEvent(const QPointF& position, const QPoint& screenPosition, const QPointF& delta);
+ enum {
+ NoPointing,
+ SingleTapStarted,
+ DoubleTapStarted,
+ TapAndHold
+ } m_tapState;
+ QBasicTimer m_tapAndHoldTimer;
+ QBasicTimer m_tapDoubleClickTimer;
+ QBasicTimer m_delayedActivationNotificationTimer;
+ qint64 m_touchBeginEventForTapTimestamp;
+ OwnPtr<QTouchEvent> m_touchBeginEventForTap;
+ OwnPtr<QTouchEvent> m_touchEventForActivationNotification;
+ QList<QRectF> m_delayedActivationNotificationAreas;
+ unsigned int m_delayedActivationNotificationColor;
+//#endif
QtPanGestureRecognizer m_panGestureRecognizer;
QtPinchGestureRecognizer m_pinchGestureRecognizer;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment