Enable longpress and doubletap to WebKit as touch
event if it is requested.
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index 930ef3a..b2db177 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -96,6 +96,8 @@
macro(touchmove) \
macro(touchend) \
macro(touchcancel) \
+ macro(touchlongpress) \
+ macro(touchdoubletap) \
/* #endif */ \
macro(unload) \
macro(updateready) \
diff --git a/WebCore/dom/TouchEvent.cpp b/WebCore/dom/TouchEvent.cpp
index d02bac8..7ce856f 100644
--- a/WebCore/dom/TouchEvent.cpp
+++ b/WebCore/dom/TouchEvent.cpp
@@ -39,6 +39,8 @@
, m_touches(touches)
, m_targetTouches(targetTouches)
, m_changedTouches(changedTouches)
+ , m_longPressPrevented(false)
+ , m_doubleTapPrevented(false)
{
}
diff --git a/WebCore/dom/TouchEvent.h b/WebCore/dom/TouchEvent.h
index e8423e5..6b7d384 100644
--- a/WebCore/dom/TouchEvent.h
+++ b/WebCore/dom/TouchEvent.h
@@ -57,6 +57,14 @@
TouchList* targetTouches() const {return m_targetTouches.get();}
TouchList* changedTouches() const {return m_changedTouches.get();}
+ bool longPressPrevented() const { return m_longPressPrevented; }
+ void preventLongPress() { m_longPressPrevented = true; }
+ void setLongPressPrevented(bool prevented) { m_longPressPrevented = prevented; }
+
+ bool doubleTapPrevented() const { return m_doubleTapPrevented; }
+ void preventDoubleTap() { m_doubleTapPrevented = true; }
+ void setDoubleTapPrevented(bool prevented) { m_doubleTapPrevented = prevented; }
+
private:
TouchEvent() {}
TouchEvent(TouchList* touches, TouchList* targetTouches,
@@ -69,6 +77,9 @@
RefPtr<TouchList> m_touches;
RefPtr<TouchList> m_targetTouches;
RefPtr<TouchList> m_changedTouches;
+
+ bool m_longPressPrevented;
+ bool m_doubleTapPrevented;
};
} // namespace WebCore
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 9d45ca7..6a92aa8 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -2525,7 +2525,7 @@
}
#if ENABLE(TOUCH_EVENTS) // Android
-bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
+int EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
{
// only handle the touch event in the top frame handler
if (m_frame->tree()->parent(true))
@@ -2533,17 +2533,17 @@
Document* doc = m_frame->document();
if (!doc)
- return false;
+ return 0;
RenderObject* docRenderer = doc->renderer();
if (!docRenderer)
- return false;
+ return 0;
if (doc->touchEventListeners().size() == 0)
- return false;
+ return 0;
TouchEventType type = e.eventType();
- if (type == TouchEventStart) {
+ if (type == TouchEventStart || type == TouchEventLongPress || type == TouchEventDoubleTap) {
Frame* frame = m_frame;
IntPoint vPoint = frame->view()->windowToContents(e.pos());
HitTestRequest request(HitTestRequest::ReadOnly);
@@ -2583,13 +2583,13 @@
if ((type == TouchEventMove) && (e.x() == m_touch->screenX()) &&
(e.y() == m_touch->screenY())) {
// don't trigger the event if it hasn't really moved
- return false;
+ return 0;
}
IntPoint vPoint = m_touch->frame()->view()->windowToContents(e.pos());
m_touch->updateLocation(e.x(), e.y(), vPoint.x(), vPoint.y());
} else {
- return false;
+ return 0;
}
RefPtr<TouchList> touchList = TouchList::create();
@@ -2622,15 +2622,30 @@
m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
break;
+ case TouchEventLongPress:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchlongpressEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
+ case TouchEventDoubleTap:
+ te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
+ eventNames().touchdoubletapEvent, m_touch->frame()->document()->defaultView(),
+ m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
+ break;
+
default:
return false;
}
ExceptionCode ec = 0;
m_touch->target()->dispatchEvent(te.get(), ec);
- if (type == TouchEventEnd || type == TouchEventCancel) {
+ if (type == TouchEventEnd || type == TouchEventCancel)
m_touch = 0;
- }
- return te->defaultPrevented();
+ if (type == TouchEventLongPress || type == TouchEventDoubleTap)
+ return 0;
+ return (te->defaultPrevented() ? preventTouch : 0)
+ | (te->longPressPrevented() ? preventLongPress : 0)
+ | (te->doubleTapPrevented() ? preventDoubleTap : 0);
}
#endif
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index daf5a67..d8cd3a2 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -75,6 +75,14 @@
enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
+#if ENABLE(TOUCH_EVENTS) // Android
+enum TouchResultMask {
+ preventTouch = 1 << 0,
+ preventLongPress = 1 << 1,
+ preventDoubleTap = 1 << 2,
+};
+#endif
+
class EventHandler : public Noncopyable {
public:
EventHandler(Frame*);
@@ -144,7 +152,8 @@
bool handleWheelEvent(PlatformWheelEvent&);
#if ENABLE(TOUCH_EVENTS) // Android
- bool handleTouchEvent(const PlatformTouchEvent&);
+ // See TouchResultMask for the return value options
+ int handleTouchEvent(const PlatformTouchEvent&);
#endif
#if ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/PlatformTouchEvent.h b/WebCore/platform/PlatformTouchEvent.h
index 4f547b2..6c8629c 100644
--- a/WebCore/platform/PlatformTouchEvent.h
+++ b/WebCore/platform/PlatformTouchEvent.h
@@ -32,7 +32,7 @@
namespace WebCore {
- enum TouchEventType {TouchEventStart, TouchEventMove, TouchEventEnd, TouchEventCancel};
+ enum TouchEventType {TouchEventStart, TouchEventMove, TouchEventEnd, TouchEventCancel, TouchEventLongPress, TouchEventDoubleTap};
class PlatformTouchEvent {
public:
diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp
index 08ac7c8..4266a9a 100644
--- a/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -183,6 +183,7 @@
ANPEvent evt;
SkANP::InitEvent(&evt, kTouch_ANPEventType);
+ bool ignoreRet = false;
const AtomicString& type = event->type();
if (eventNames().touchstartEvent == type)
evt.data.touch.action = kDown_ANPTouchAction;
@@ -192,7 +193,13 @@
evt.data.touch.action = kMove_ANPTouchAction;
else if (eventNames().touchcancelEvent == type)
evt.data.touch.action = kCancel_ANPTouchAction;
- else
+ else if (eventNames().touchlongpressEvent == type) {
+ evt.data.touch.action = kLongPress_ANPTouchAction;
+ ignoreRet = true;
+ } else if (eventNames().touchdoubletapEvent == type) {
+ evt.data.touch.action = kDoubleTap_ANPTouchAction;
+ ignoreRet = true;
+ } else
return;
evt.data.touch.modifiers = 0; // todo
@@ -203,14 +210,22 @@
evt.data.touch.x = event->pageX() - m_npWindow.x;
evt.data.touch.y = event->pageY() - m_npWindow.y;
- if (m_plugin->pluginFuncs()->event(m_instance, &evt)) {
+ int16 ret = m_plugin->pluginFuncs()->event(m_instance, &evt);
+ if (ignoreRet)
+ return;
+ if (ret & kHandleTouch_ANPTouchResult) {
// The plugin needs focus to receive keyboard events
if (evt.data.touch.action == kDown_ANPTouchAction) {
if (Page* page = m_parentFrame->page())
page->focusController()->setFocusedFrame(m_parentFrame);
m_parentFrame->document()->setFocusedNode(m_element);
}
- event->setDefaultPrevented(true);
+ event->preventDefault();
+ } else {
+ if (ret & kHandleLongPress_ANPTouchResult)
+ event->preventLongPress();
+ if (ret & kHandleDoubleTap_ANPTouchResult)
+ event->preventDoubleTap();
}
}
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 135d1b2..0b7e63b 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2052,9 +2052,9 @@
}
}
-bool WebViewCore::handleTouchEvent(int action, int x, int y)
+int WebViewCore::handleTouchEvent(int action, int x, int y)
{
- bool preventDefault = false;
+ int preventDefault = 0;
#if ENABLE(TOUCH_EVENTS) // Android
WebCore::TouchEventType type = WebCore::TouchEventCancel;
@@ -2071,6 +2071,12 @@
case 3: // MotionEvent.ACTION_CANCEL
type = WebCore::TouchEventCancel;
break;
+ case 0x100: // WebViewCore.ACTION_LONGPRESS
+ type = WebCore::TouchEventLongPress;
+ break;
+ case 0x200: // WebViewCore.ACTION_DOUBLETAP
+ type = WebCore::TouchEventDoubleTap;
+ break;
}
WebCore::IntPoint pt(x - m_scrollOffsetX, y - m_scrollOffsetY);
WebCore::PlatformTouchEvent te(pt, pt, type);
@@ -2829,7 +2835,7 @@
return ret;
}
-static jboolean HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, jint y)
+static jint HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, jint y)
{
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
@@ -3216,7 +3222,7 @@
(void*) SaveDocumentState },
{ "nativeFindAddress", "(Ljava/lang/String;Z)Ljava/lang/String;",
(void*) FindAddress },
- { "nativeHandleTouchEvent", "(III)Z",
+ { "nativeHandleTouchEvent", "(III)I",
(void*) HandleTouchEvent },
{ "nativeTouchUp", "(IIIII)V",
(void*) TouchUp },
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 09f02a5..d1c8511 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -278,7 +278,7 @@
/**
* Handle touch event
*/
- bool handleTouchEvent(int action, int x, int y);
+ int handleTouchEvent(int action, int x, int y);
/**
* Handle motionUp event from the UI thread (called touchUp in the
diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h
index e52debb..14553ff 100644
--- a/WebKit/android/plugins/android_npapi.h
+++ b/WebKit/android/plugins/android_npapi.h
@@ -790,13 +790,29 @@
the plugin chooses to not handle this action then no other events
related to that particular touch gesture will be generated.
*/
- kDown_ANPTouchAction = 0,
- kUp_ANPTouchAction = 1,
- kMove_ANPTouchAction = 2,
- kCancel_ANPTouchAction = 3,
+ kDown_ANPTouchAction = 0,
+ kUp_ANPTouchAction = 1,
+ kMove_ANPTouchAction = 2,
+ kCancel_ANPTouchAction = 3,
+ // The web view will ignore the return value from the following actions
+ kLongPress_ANPTouchAction = 4,
+ kDoubleTap_ANPTouchAction = 5,
};
typedef int32_t ANPTouchAction;
+/**
+ * When a plugin returns from NPP_HandleEvent() for a touch event, it can use
+ * ANPTouchResultMask to tell the web view which touch event it wants to handle.
+ * kHandleTouch_ANPTouchResult will handle all touch event inside the plugin. If
+ * it is not set, a plugin can choose only handle individual event like long
+ * press, or double tap.
+ */
+enum ANPTouchResultMask {
+ kHandleTouch_ANPTouchResult = 1,
+ kHandleLongPress_ANPTouchResult = 2,
+ kHandleDoubleTap_ANPTouchResult = 4,
+};
+
enum ANPLifecycleActions {
/** The web view containing this plugin has been paused. See documentation
on the android activity lifecycle for more information.