diff options
Diffstat (limited to 'WebKit/android/nav/WebView.cpp')
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 89 |
1 files changed, 81 insertions, 8 deletions
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 22b07bc..116cfdd 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -128,7 +128,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); - m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "()V"); + m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V"); m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIIII)V"); m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); @@ -536,6 +536,50 @@ void cursorRingBounds(WebCore::IntRect* bounds) *bounds = WebCore::IntRect(0, 0, 0, 0); } +void fixCursor() +{ + m_viewImpl->gCursorBoundsMutex.lock(); + bool hasCursorBounds = m_viewImpl->m_hasCursorBounds; + IntRect bounds = m_viewImpl->m_cursorBounds; + m_viewImpl->gCursorBoundsMutex.unlock(); + if (!hasCursorBounds) + return; + int x, y; + const CachedFrame* frame; + const CachedNode* node = m_frameCacheUI->findAt(bounds, &frame, &x, &y, false); + if (!node) + return; + // require that node have approximately the same bounds (+/- 4) and the same + // center (+/- 2) + IntPoint oldCenter = IntPoint(bounds.x() + (bounds.width() >> 1), + bounds.y() + (bounds.height() >> 1)); + IntRect newBounds = node->bounds(); + IntPoint newCenter = IntPoint(newBounds.x() + (newBounds.width() >> 1), + newBounds.y() + (newBounds.height() >> 1)); + DBG_NAV_LOGD("oldCenter=(%d,%d) newCenter=(%d,%d)" + " bounds=(%d,%d,w=%d,h=%d) newBounds=(%d,%d,w=%d,h=%d)", + oldCenter.x(), oldCenter.y(), newCenter.x(), newCenter.y(), + bounds.x(), bounds.y(), bounds.width(), bounds.height(), + newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); + if (abs(oldCenter.x() - newCenter.x()) > 2) + return; + if (abs(oldCenter.y() - newCenter.y()) > 2) + return; + if (abs(bounds.x() - newBounds.x()) > 4) + return; + if (abs(bounds.y() - newBounds.y()) > 4) + return; + if (abs(bounds.right() - newBounds.right()) > 4) + return; + if (abs(bounds.bottom() - newBounds.bottom()) > 4) + return; + DBG_NAV_LOGD("node=%p frame=%p x=%d y=%d bounds=(%d,%d,w=%d,h=%d)", + node, frame, x, y, bounds.x(), bounds.y(), bounds.width(), + bounds.height()); + m_frameCacheUI->setCursor(const_cast<CachedFrame*>(frame), + const_cast<CachedNode*>(node)); +} + CachedRoot* getFrameCache(FrameCachePermission allowNewer) { if (!m_viewImpl->m_updatedFrameCache) { @@ -558,6 +602,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer) m_viewImpl->m_frameCacheKit = 0; m_viewImpl->m_navPictureKit = 0; m_viewImpl->gFrameCacheMutex.unlock(); + fixCursor(); if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) viewInvalidate(); // redraw in case cursor ring is still visible return m_frameCacheUI; @@ -680,8 +725,10 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) } if (cachedNode) { m_viewImpl->gCursorBoundsMutex.lock(); - m_viewImpl->m_hasCursorBounds = true; + m_viewImpl->m_hasCursorBounds = cachedNode->hasCursorRing(); m_viewImpl->m_cursorBounds = cachedNode->bounds(); + m_viewImpl->m_cursorFrame = cachedFrame->framePointer(); + root->getSimulatedMousePosition(&m_viewImpl->m_cursorLocation); m_viewImpl->m_cursorNode = cachedNode->nodePointer(); m_viewImpl->gCursorBoundsMutex.unlock(); } @@ -710,8 +757,11 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) } bool result = false; if (cachedNode) { - root->setCursor((CachedFrame*) cachedFrame, (CachedNode*) cachedNode); - sendMoveMouseIfLatest(); + root->setCursor(const_cast<CachedFrame*>(cachedFrame), + const_cast<CachedNode*>(cachedNode)); + bool disableFocusController = cachedNode != root->currentFocus() + && cachedNode->wantsKeyEvents(); + sendMoveMouseIfLatest(disableFocusController); viewInvalidate(); } else { int docHeight = root->documentHeight(); @@ -763,18 +813,23 @@ void selectBestAt(const WebCore::IntRect& rect) { const CachedFrame* frame; int rx, ry; + bool disableFocusController = false; CachedRoot* root = getFrameCache(DontAllowNewer); const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); if (!node) { DBG_NAV_LOGD("no nodes found root=%p", root); + disableFocusController = true; if (root) root->setCursor(0, 0); } else { DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); + const_cast<CachedNode*>(node)); + if (!node->wantsKeyEvents()) { + disableFocusController = true; + } } - sendMoveMouseIfLatest(); + sendMoveMouseIfLatest(disableFocusController); viewInvalidate(); } @@ -1014,12 +1069,12 @@ void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int checkException(env); } -void sendMoveMouseIfLatest() +void sendMoveMouseIfLatest(bool disableFocusController) { LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); env->CallVoidMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_sendMoveMouseIfLatest); + m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController); checkException(env); } @@ -1291,6 +1346,19 @@ static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) return reinterpret_cast<int>(node ? node->nodePointer() : 0); } +static jobject nativeCursorPosition(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + WebCore::IntPoint pos = WebCore::IntPoint(0, 0); + if (root) + root->getSimulatedMousePosition(&pos); + jclass pointClass = env->FindClass("android/graphics/Point"); + jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); + jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); + return point; +} + static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) { int L, T, R, B; @@ -1681,6 +1749,9 @@ static void nativeDestroy(JNIEnv *env, jobject obj) 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(); } @@ -1757,6 +1828,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeCursorIsAnchor }, { "nativeCursorIsTextInput", "()Z", (void*) nativeCursorIsTextInput }, + { "nativeCursorPosition", "()Landroid/graphics/Point;", + (void*) nativeCursorPosition }, { "nativeCursorText", "()Ljava/lang/String;", (void*) nativeCursorText }, { "nativeCursorWantsKeyEvents", "()Z", |