macro(touchmove) \
macro(touchend) \
macro(touchcancel) \
+ macro(touchlongpress) \
+ macro(touchdoubletap) \
/* #endif */ \
macro(unload) \
macro(updateready) \
, m_touches(touches)
, m_targetTouches(targetTouches)
, m_changedTouches(changedTouches)
+ , m_longPressPrevented(false)
+ , m_doubleTapPrevented(false)
{
}
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,
RefPtr<TouchList> m_touches;
RefPtr<TouchList> m_targetTouches;
RefPtr<TouchList> m_changedTouches;
+
+ bool m_longPressPrevented;
+ bool m_doubleTapPrevented;
};
} // namespace WebCore
}
#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))
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);
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();
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
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*);
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)
namespace WebCore {
- enum TouchEventType {TouchEventStart, TouchEventMove, TouchEventEnd, TouchEventCancel};
+ enum TouchEventType {TouchEventStart, TouchEventMove, TouchEventEnd, TouchEventCancel, TouchEventLongPress, TouchEventDoubleTap};
class PlatformTouchEvent {
public:
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;
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
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();
}
}
}
}
-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;
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);
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);
(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 },
/**
* 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
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.