From: Grace Kloba Date: Thu, 10 Dec 2009 00:00:52 +0000 (-0800) Subject: am 3d0d3fda: Enable longpress and doubletap to WebKit as touch event if it is requested. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=dc417b235a5d3dc193fa6a4e1884fd04428b79e2;p=android-x86%2Fexternal-webkit.git am 3d0d3fda: Enable longpress and doubletap to WebKit as touch event if it is requested. Merge commit '3d0d3fdaa1308448b47592c03cda81c7f9e1f789' into eclair-mr2-plus-aosp * commit '3d0d3fdaa1308448b47592c03cda81c7f9e1f789': Enable longpress and doubletap to WebKit as touch --- diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h index 578b7d5f7..40ff71d2e 100644 --- a/WebCore/dom/EventNames.h +++ b/WebCore/dom/EventNames.h @@ -96,6 +96,8 @@ namespace WebCore { 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 d02bac8b0..7ce856fff 100644 --- a/WebCore/dom/TouchEvent.cpp +++ b/WebCore/dom/TouchEvent.cpp @@ -39,6 +39,8 @@ TouchEvent::TouchEvent(TouchList* touches, TouchList* targetTouches, , 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 e8423e5ad..6b7d3847c 100644 --- a/WebCore/dom/TouchEvent.h +++ b/WebCore/dom/TouchEvent.h @@ -57,6 +57,14 @@ namespace WebCore { 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 @@ namespace WebCore { RefPtr m_touches; RefPtr m_targetTouches; RefPtr m_changedTouches; + + bool m_longPressPrevented; + bool m_doubleTapPrevented; }; } // namespace WebCore diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 9d45ca718..6a92aa860 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -2525,7 +2525,7 @@ bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& } #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 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) 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 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) 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::create(); @@ -2622,15 +2622,30 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) 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 daf5a6724..d8cd3a2af 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -75,6 +75,14 @@ extern const int GeneralDragHysteresis; 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 @@ public: 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 4f547b245..6c8629cc0 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 08ac7c891..4266a9a6b 100644 --- a/WebCore/plugins/android/PluginViewAndroid.cpp +++ b/WebCore/plugins/android/PluginViewAndroid.cpp @@ -183,6 +183,7 @@ void PluginView::handleTouchEvent(TouchEvent* event) 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 @@ void PluginView::handleTouchEvent(TouchEvent* event) 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 @@ void PluginView::handleTouchEvent(TouchEvent* event) 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 3243db274..8542db4a0 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -1977,9 +1977,9 @@ void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) { } } -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; @@ -1996,6 +1996,12 @@ bool WebViewCore::handleTouchEvent(int action, int x, int y) 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); @@ -2663,7 +2669,7 @@ static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr, 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); @@ -3037,7 +3043,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (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 8a0df235a..7385dacce 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -277,7 +277,7 @@ namespace android { /** * 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 40a31fa55..ca628195f 100644 --- a/WebKit/android/plugins/android_npapi.h +++ b/WebKit/android/plugins/android_npapi.h @@ -786,13 +786,29 @@ enum ANPTouchActions { 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.