diff options
-rw-r--r-- | WebCore/platform/PlatformKeyboardEvent.h | 4 | ||||
-rw-r--r-- | WebCore/platform/android/KeyEventAndroid.cpp | 13 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 76 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 7 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.h | 3 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 88 |
6 files changed, 110 insertions, 81 deletions
diff --git a/WebCore/platform/PlatformKeyboardEvent.h b/WebCore/platform/PlatformKeyboardEvent.h index 34c05fe..75922fa 100644 --- a/WebCore/platform/PlatformKeyboardEvent.h +++ b/WebCore/platform/PlatformKeyboardEvent.h @@ -140,8 +140,8 @@ namespace WebCore { #endif #if PLATFORM(ANDROID) - PlatformKeyboardEvent(int keyCode, UChar32 unichar, Type, - int repeatCount, ModifierKey); + PlatformKeyboardEvent(int keyCode, UChar32 unichar, int repeatCount, + bool down, bool cap, bool alt, bool sym); UChar32 unichar() const { return m_unichar; } int repeatCount() const { return m_repeatCount; } #endif diff --git a/WebCore/platform/android/KeyEventAndroid.cpp b/WebCore/platform/android/KeyEventAndroid.cpp index ab848bd..998c781 100644 --- a/WebCore/platform/android/KeyEventAndroid.cpp +++ b/WebCore/platform/android/KeyEventAndroid.cpp @@ -211,9 +211,8 @@ static inline String singleCharacterString(UChar32 c) } PlatformKeyboardEvent::PlatformKeyboardEvent(int keyCode, UChar32 unichar, - Type type, int repeatCount, - ModifierKey mods) - : m_type(type) + int repeatCount, bool down, bool cap, bool alt, bool sym) + : m_type(down ? KeyDown : KeyUp) , m_text(singleCharacterString(unichar)) , m_unmodifiedText(singleCharacterString(unichar)) , m_keyIdentifier(keyIdentifierForAndroidKeyCode(keyCode)) @@ -221,10 +220,10 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(int keyCode, UChar32 unichar, , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(keyCode)) , m_nativeVirtualKeyCode(keyCode) , m_isKeypad(false) - , m_shiftKey((mods & ShiftKey)) - , m_ctrlKey((mods & CtrlKey)) - , m_altKey((mods & AltKey)) - , m_metaKey((mods & MetaKey)) + , m_shiftKey(cap ? ShiftKey : 0) + , m_ctrlKey(sym ? CtrlKey : 0) + , m_altKey(alt ? AltKey : 0) + , m_metaKey(0) // added for android , m_repeatCount(repeatCount) , m_unichar(unichar) diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 11576be..00cd64f 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -1382,9 +1382,6 @@ void WebViewCore::setSelection(int start, int end) focus->document()->frame()->revealSelection(); } -// Shortcut for no modifier keys -#define NO_MODIFIER_KEYS (static_cast<WebCore::PlatformKeyboardEvent::ModifierKey>(0)) - void WebViewCore::deleteSelection(int start, int end) { setSelection(start, end); @@ -1394,11 +1391,11 @@ void WebViewCore::deleteSelection(int start, int end) if (!focus) return; WebCore::Frame* frame = focus->document()->frame(); - WebCore::PlatformKeyboardEvent downEvent(kKeyCodeDel, WebCore::VK_BACK, - WebCore::PlatformKeyboardEvent::KeyDown, 0, NO_MODIFIER_KEYS); + WebCore::PlatformKeyboardEvent downEvent(kKeyCodeDel, 0, + true, 0, false, false, false); frame->eventHandler()->keyEvent(downEvent); - WebCore::PlatformKeyboardEvent upEvent(kKeyCodeDel, WebCore::VK_BACK, - WebCore::PlatformKeyboardEvent::KeyUp, 0, NO_MODIFIER_KEYS); + WebCore::PlatformKeyboardEvent upEvent(kKeyCodeDel, 0, + false, 0, false, false, false); frame->eventHandler()->keyEvent(upEvent); } @@ -1415,36 +1412,24 @@ void WebViewCore::replaceTextfieldText(int oldStart, setFocusControllerActive(true); } -void WebViewCore::passToJs( - int generation, const WebCore::String& current, int keyCode, - int keyValue, bool down, bool cap, bool fn, bool sym) +void WebViewCore::passToJs(int generation, const WebCore::String& current, + const PlatformKeyboardEvent& event) { WebCore::Node* focus = currentFocus(); if (!focus) { DBG_NAV_LOG("!focus"); return; } - WebCore::Frame* frame = focus->document()->frame(); - // Construct the ModifierKey value - WebCore::PlatformKeyboardEvent::ModifierKey mods = - static_cast<WebCore::PlatformKeyboardEvent::ModifierKey> - ((cap ? WebCore::PlatformKeyboardEvent::ShiftKey : 0) - | (fn ? WebCore::PlatformKeyboardEvent::AltKey : 0) - | (sym ? WebCore::PlatformKeyboardEvent::CtrlKey : 0)); - WebCore::PlatformKeyboardEvent event(keyCode, keyValue, - down ? WebCore::PlatformKeyboardEvent::KeyDown : - WebCore::PlatformKeyboardEvent::KeyUp, 0, mods); - // Block text field updates during a key press. - m_blockTextfieldUpdates = true; - frame->eventHandler()->keyEvent(event); - m_blockTextfieldUpdates = false; - m_textGeneration = generation; - DBG_NAV_LOGD("focus=%p keyCode=%d keyValue=%d", focus, keyCode, keyValue); WebCore::RenderObject* renderer = focus->renderer(); if (!renderer || (!renderer->isTextField() && !renderer->isTextArea())) { DBG_NAV_LOGD("renderer==%p || not text", renderer); return; } + // Block text field updates during a key press. + m_blockTextfieldUpdates = true; + key(event); + m_blockTextfieldUpdates = false; + m_textGeneration = generation; setFocusControllerActive(true); WebCore::RenderTextControl* renderText = static_cast<WebCore::RenderTextControl*>(renderer); @@ -1634,26 +1619,15 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s m_popupReply = reply; } -bool WebViewCore::key(int keyCode, UChar32 unichar, int repeatCount, bool isShift, bool isAlt, bool isDown) +bool WebViewCore::key(const PlatformKeyboardEvent& event) { WebCore::EventHandler* eventHandler = m_mainFrame->eventHandler(); WebCore::Node* focusNode = currentFocus(); - if (focusNode) { + if (focusNode) eventHandler = focusNode->document()->frame()->eventHandler(); - } - - int mods = 0; // PlatformKeyboardEvent::ModifierKey - if (isShift) { - mods |= WebCore::PlatformKeyboardEvent::ShiftKey; - } - if (isAlt) { - mods |= WebCore::PlatformKeyboardEvent::AltKey; - } - DBG_NAV_LOGD("keyCode=%d focusNode=%p", keyCode, focusNode); - WebCore::PlatformKeyboardEvent evt(keyCode, unichar, - isDown ? WebCore::PlatformKeyboardEvent::KeyDown : WebCore::PlatformKeyboardEvent::KeyUp, - repeatCount, static_cast<WebCore::PlatformKeyboardEvent::ModifierKey> (mods)); - return eventHandler->keyEvent(evt); + DBG_NAV_LOGD("keyCode=%s unichar=%d focusNode=%p", + event.keyIdentifier().utf8().data(), event.unichar(), focusNode); + return eventHandler->keyEvent(event); } // For when the user clicks the trackball @@ -2031,15 +2005,14 @@ static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h, } static jboolean Key(JNIEnv *env, jobject obj, jint keyCode, jint unichar, - jint repeatCount, jboolean isShift, jboolean isAlt, jboolean isDown) + jint repeatCount, jboolean isShift, jboolean isAlt, jboolean isSym, + jboolean isDown) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); #endif - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in Key"); - - return viewImpl->key(keyCode, unichar, repeatCount, isShift, isAlt, isDown); + return GET_NATIVE_VIEW(env, obj)->key(PlatformKeyboardEvent(keyCode, + unichar, repeatCount, isDown, isShift, isAlt, isSym)); } static void Click(JNIEnv *env, jobject obj, int framePtr, int nodePtr) @@ -2092,12 +2065,9 @@ static void PassToJs(JNIEnv *env, jobject obj, #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); #endif - LOGV("webviewcore::nativePassToJs()\n"); - WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(viewImpl, "viewImpl not set in nativePassToJs"); WebCore::String current = to_string(env, currentText); - viewImpl->passToJs( - generation, current, keyCode, keyValue, down, cap, fn, sym); + GET_NATIVE_VIEW(env, obj)->passToJs(generation, current, + PlatformKeyboardEvent(keyCode, keyValue, 0, down, cap, fn, sym)); } static void SetFocusControllerInactive(JNIEnv *env, jobject obj) @@ -2480,7 +2450,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) CopyContentToPicture }, { "nativeDrawContent", "(Landroid/graphics/Canvas;I)Z", (void*) DrawContent } , - { "nativeKey", "(IIIZZZ)Z", + { "nativeKey", "(IIIZZZZ)Z", (void*) Key }, { "nativeClick", "(II)V", (void*) Click }, diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index b9fff87..06e9100 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -48,6 +48,7 @@ namespace WebCore { class RenderPart; class RenderText; class Node; + class PlatformKeyboardEvent; class RenderTextControl; class ScrollView; class TimerBase; @@ -211,7 +212,7 @@ namespace android { * Handle key events from Java. * @return Whether keyCode was handled by this class. */ - bool key(int keyCode, UChar32 unichar, int repeatCount, bool isShift, bool isAlt, bool isDown); + bool key(const WebCore::PlatformKeyboardEvent& event); /** * Handle (trackball) click event from Java @@ -257,8 +258,7 @@ namespace android { void replaceTextfieldText(int oldStart, int oldEnd, const WebCore::String& replace, int start, int end); void passToJs(int generation, - const WebCore::String& currentText, int jKeyCode, int keyVal, - bool down, bool cap, bool fn, bool sym); + const WebCore::String& , const WebCore::PlatformKeyboardEvent& ); void setFocusControllerActive(bool active); void saveDocumentState(WebCore::Frame* frame); @@ -302,7 +302,6 @@ namespace android { // other public functions public: - // reset the picture set to empty void clearContent(); diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h index 9361309..2efbaf7 100644 --- a/WebKit/android/nav/CachedNode.h +++ b/WebKit/android/nav/CachedNode.h @@ -117,6 +117,9 @@ public: return clip.intersects(mBounds); } bool isPassword() const { return mIsPassword; } + bool isPlugin() const { + return mWantsKeyEvents && !mIsTextArea && !mIsTextField; + } bool isRtlText() const { return mIsRtlText; } bool isTextArea() const { return mIsTextArea; } bool isTextField() const { return mIsTextField; } diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index ec33948..022ca6f 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -161,6 +161,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_matches = 0; m_hasCurrentLocation = false; m_isFindPaintSetUp = false; + m_pluginReceivesEvents = false; } ~WebView() @@ -404,21 +405,25 @@ void drawMatches(SkCanvas* canvas) } } +void resetCursorRing() +{ + m_followedLink = m_pluginReceivesEvents = false; + m_viewImpl->m_hasCursorBounds = false; +} + void drawCursorRing(SkCanvas* canvas) { const CachedRoot* root = getFrameCache(AllowNewer); if (!root) { DBG_NAV_LOG("!root"); - m_followedLink = false; - m_viewImpl->m_hasCursorBounds = false; + resetCursorRing(); return; } const CachedFrame* frame; const CachedNode* node = root->currentCursor(&frame); if (!node) { DBG_NAV_LOG("!node"); - m_followedLink = false; - m_viewImpl->m_hasCursorBounds = false; + resetCursorRing(); return; } if (!node->hasCursorRing()) { @@ -466,29 +471,31 @@ void drawCursorRing(SkCanvas* canvas) DBG_NAV_LOGD("canvas->quickReject cursorNode=%d (nodePointer=%p)" " bounds=(%d,%d,w=%d,h=%d)", node->index(), node->nodePointer(), bounds.x(), bounds.y(), bounds.width(), bounds.height()); - m_followedLink = false; + m_followedLink = m_pluginReceivesEvents = false; return; } CursorRing::Flavor flavor = CursorRing::NORMAL_FLAVOR; if (!isButton) { flavor = node->type() != NORMAL_CACHEDNODETYPE ? CursorRing::FAKE_FLAVOR : CursorRing::NORMAL_FLAVOR; + if (m_pluginReceivesEvents && node->isPlugin()) { + return; + } if (m_followedLink) { - if (node->wantsKeyEvents() && !node->isTextArea() - && !node->isTextField()) { - return; // don't draw after click on plugin - } flavor = static_cast<CursorRing::Flavor> (flavor + CursorRing::NORMAL_ANIMATING); } #if DEBUG_NAV_UI const WebCore::IntRect& ring = (*rings)[0]; DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) flavor=%s rings=%d" - " (%d, %d, %d, %d)", node->index(), node->nodePointer(), + " (%d, %d, %d, %d) pluginReceivesEvents=%s isPlugin=%s", + node->index(), node->nodePointer(), flavor == CursorRing::FAKE_FLAVOR ? "FAKE_FLAVOR" : flavor == CursorRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" : flavor == CursorRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR", - rings->size(), ring.x(), ring.y(), ring.width(), ring.height()); + rings->size(), ring.x(), ring.y(), ring.width(), ring.height(), + m_pluginReceivesEvents ? "true" : "false", + node->isPlugin() ? "true" : "false"); #endif } if (isButton || flavor >= CursorRing::NORMAL_ANIMATING) { @@ -668,7 +675,7 @@ static CachedFrame::Direction KeyToDirection(KeyCode keyCode) DBG_NAV_LOGD("keyCode=%s", "up"); return CachedFrame::UP; default: - LOGD("------- bad key sent to WebView::moveCursor"); + DBG_NAV_LOGD("bad key %d sent", keyCode); return CachedFrame::UNINITIALIZED; } } @@ -720,6 +727,7 @@ void updateCursorBounds(const CachedRoot* root, const CachedFrame* cachedFrame, /* returns true if the key had no effect (neither scrolled nor changed cursor) */ bool moveCursor(int keyCode, int count, bool ignoreScroll) { + m_pluginReceivesEvents = false; CachedRoot* root = getFrameCache(AllowNewer); if (!root) { DBG_NAV_LOG("!root"); @@ -804,6 +812,21 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) return result; } +bool pluginEatsNavKey() +{ + CachedRoot* root = getFrameCache(DontAllowNewer); + if (!root) { + DBG_NAV_LOG("!root"); + return false; + } + const CachedNode* cursor = root->currentCursor(); + DBG_NAV_LOGD("cursor=%p isPlugin=%s pluginReceivesEvents=%s", + cursor, cursor && cursor->isPlugin() ? "true" : "false", + m_pluginReceivesEvents ? "true" : "false"); + // FIXME: check to see if plugin wants keys + return cursor && cursor->isPlugin() && m_pluginReceivesEvents; +} + void notifyProgressFinished() { DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); @@ -876,7 +899,7 @@ void setNavBounds(const WebCore::IntRect& rect) bool motionUp(int x, int y, int slop) { bool pageScrolled = false; - m_followedLink = false; + m_followedLink = m_pluginReceivesEvents = false; const CachedFrame* frame; WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, slop * 2, slop * 2); int rx, ry; @@ -906,6 +929,7 @@ bool motionUp(int x, int y, int slop) updateCursorBounds(root, frame, result); root->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(result)); + updatePluginReceivesEvents(); CachedNodeType type = result->type(); if (type == NORMAL_CACHEDNODETYPE) { sendMotionUp( @@ -941,6 +965,17 @@ void setFindIsUp(bool up) m_hasCurrentLocation = false; } +void updatePluginReceivesEvents() +{ + CachedRoot* root = getFrameCache(DontAllowNewer); + if (!root) + return; + const CachedNode* cursor = root->currentCursor(); + m_pluginReceivesEvents = cursor && cursor->isPlugin(); + DBG_NAV_LOGD("m_pluginReceivesEvents=%s cursor=%p", m_pluginReceivesEvents + ? "true" : "false", cursor); +} + void setFollowedLink(bool followed) { if ((m_followedLink = followed) != false) { @@ -1263,6 +1298,7 @@ private: // local state for WebView int m_generation; // associate unique ID with sent kit focus to match with ui SkPicture* m_navPictureUI; bool m_followedLink; + bool m_pluginReceivesEvents; SkMSec m_ringAnimationEnd; // Corresponds to the same-named boolean on the java side. bool m_heightCanMeasure; @@ -1404,6 +1440,12 @@ static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj) return node ? node->isAnchor() : false; } +static bool nativeCursorIsPlugin(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + return node ? node->isPlugin() : false; +} + static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj) { const CachedNode* node = getCursorNode(env, obj); @@ -1654,6 +1696,11 @@ static void nativeSetFindIsDown(JNIEnv *env, jobject obj) view->setFindIsUp(false); } +static void nativeUpdatePluginReceivesEvents(JNIEnv *env, jobject obj) +{ + GET_NATIVE_VIEW(env, obj)->updatePluginReceivesEvents(); +} + static void nativeSetFollowedLink(JNIEnv *env, jobject obj, bool followed) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -1777,7 +1824,7 @@ static int nativeMoveGeneration(JNIEnv *env, jobject obj) WebView* view = GET_NATIVE_VIEW(env, obj); if (!view) return 0; - return GET_NATIVE_VIEW(env, obj)->moveGeneration(); + return view->moveGeneration(); } static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y, bool ex) @@ -1787,6 +1834,11 @@ static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y, bool ex) view->moveSelection(x, y, ex); } +static bool nativePluginEatsNavKey(JNIEnv *env, jobject obj) +{ + return GET_NATIVE_VIEW(env, obj)->pluginEatsNavKey(); +} + static jobject nativeGetSelection(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -1851,6 +1903,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeCursorIntersects }, { "nativeCursorIsAnchor", "()Z", (void*) nativeCursorIsAnchor }, + { "nativeCursorIsPlugin", "()Z", + (void*) nativeCursorIsPlugin }, { "nativeCursorIsTextInput", "()Z", (void*) nativeCursorIsTextInput }, { "nativeCursorPosition", "()Landroid/graphics/Point;", @@ -1919,6 +1973,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeMoveGeneration }, { "nativeMoveSelection", "(IIZ)V", (void*) nativeMoveSelection }, + { "nativePluginEatsNavKey", "()Z", + (void*) nativePluginEatsNavKey }, { "nativeRecordButtons", "(ZZZ)V", (void*) nativeRecordButtons }, { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V", @@ -1932,7 +1988,9 @@ static JNINativeMethod gJavaWebViewMethods[] = { { "nativeTextGeneration", "()I", (void*) nativeTextGeneration }, { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", - (void*) nativeUpdateCachedTextfield } + (void*) nativeUpdateCachedTextfield }, + { "nativeUpdatePluginReceivesEvents", "()V", + (void*) nativeUpdatePluginReceivesEvents } }; int register_webview(JNIEnv* env) |