diff options
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 144 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 17 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 65 |
3 files changed, 101 insertions, 125 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index f175880..58dae8c 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -288,7 +288,6 @@ void WebViewCore::reset(bool fromConstructor) m_updatedFrameCache = true; m_frameCacheOutOfDate = true; m_snapAnchorNode = 0; - m_useReplay = false; m_skipContentDraw = false; m_findIsUp = false; m_domtree_version = 0; @@ -862,9 +861,10 @@ void WebViewCore::doMaxScroll(CacheBuilder::Direction dir) this->scrollBy(dx, dy, true); } -void WebViewCore::setScrollOffset(int dx, int dy) +void WebViewCore::setScrollOffset(int moveGeneration, int dx, int dy) { - DBG_NAV_LOGD("{%d,%d}", dx, dy); + DBG_NAV_LOGD("{%d,%d} m_scrollOffset=(%d,%d)", dx, dy, + m_scrollOffsetX, m_scrollOffsetY); if (m_scrollOffsetX != dx || m_scrollOffsetY != dy) { m_scrollOffsetX = dx; m_scrollOffsetY = dy; @@ -875,6 +875,14 @@ void WebViewCore::setScrollOffset(int dx, int dy) m_scrollOffsetY); m_mainFrame->eventHandler()->sendScrollEvent(); } + gCursorBoundsMutex.lock(); + bool hasCursorBounds = m_hasCursorBounds; + Frame* frame = (Frame*) m_cursorFrame; + IntPoint location = m_cursorLocation; + gCursorBoundsMutex.unlock(); + if (!hasCursorBounds) + return; + moveMouseIfLatest(moveGeneration, frame, location.x(), location.y()); } void WebViewCore::setGlobalBounds(int x, int y, int h, int v) @@ -997,11 +1005,11 @@ WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* return anchor->href(); } -bool WebViewCore::prepareFrameCache() +void WebViewCore::updateFrameCache() { if (!m_frameCacheOutOfDate) { DBG_NAV_LOG("!m_frameCacheOutOfDate"); - return false; + return; } #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreBuildNavTimeCounter); @@ -1030,61 +1038,9 @@ bool WebViewCore::prepareFrameCache() recordPicture(m_tempPict); m_temp->setPicture(m_tempPict); m_temp->setTextGeneration(m_textGeneration); -// if (m_temp->currentFocus()) -// return true; WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); m_temp->setVisibleRect(WebCore::IntRect(m_scrollOffsetX, m_scrollOffsetY, window->width(), window->height())); - bool hasCursorBounds; - gCursorBoundsMutex.lock(); - hasCursorBounds = m_hasCursorBounds; - IntRect bounds = m_cursorBounds; - gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return true; - int x, y; - const CachedFrame* frame; - const CachedNode* node = m_temp->findAt(bounds, &frame, &x, &y, false); - if (!node) - return true; - // 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 true; - if (abs(oldCenter.y() - newCenter.y()) > 2) - return true; - if (abs(bounds.x() - newBounds.x()) > 4) - return true; - if (abs(bounds.y() - newBounds.y()) > 4) - return true; - if (abs(bounds.right() - newBounds.right()) > 4) - return true; - if (abs(bounds.bottom() - newBounds.bottom()) > 4) - return true; - 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_temp->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - return true; -} - -void WebViewCore::releaseFrameCache(bool newCache) -{ - if (!newCache) { - DBG_NAV_LOG("!newCache"); - return; - } gFrameCacheMutex.lock(); delete m_frameCacheKit; delete m_navPictureKit; @@ -1092,25 +1048,12 @@ void WebViewCore::releaseFrameCache(bool newCache) m_navPictureKit = m_tempPict; m_updatedFrameCache = true; #if DEBUG_NAV_UI - const CachedNode* cachedCursorNode = m_frameCacheKit->currentCursor(); const CachedNode* cachedFocusNode = m_frameCacheKit->currentFocus(); - DBG_NAV_LOGD("cachedCursor=%d (%p) cachedFocusNode=%d (nodePointer=%p)", - cachedCursorNode ? cachedCursorNode->index() : 0, - cachedCursorNode ? cachedCursorNode->nodePointer() : 0, + DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", cachedFocusNode ? cachedFocusNode->index() : 0, cachedFocusNode ? cachedFocusNode->nodePointer() : 0); #endif gFrameCacheMutex.unlock(); - // it's tempting to send an invalidate here, but it's a bad idea - // the cache is now up to date, but the focus is not -- the event - // may need to be recomputed from the prior history. An invalidate - // will draw the stale location causing the ring to flash at the wrong place. -} - -void WebViewCore::updateFrameCache() -{ - m_useReplay = false; - releaseFrameCache(prepareFrameCache()); } /////////////////////////////////////////////////////////////////////////////// @@ -1177,30 +1120,18 @@ void WebViewCore::sendPluginEvent(const ANPEvent& evt) /////////////////////////////////////////////////////////////////////////////// void WebViewCore::moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus) + WebCore::Frame* frame, int x, int y) { DBG_NAV_LOGD("m_moveGeneration=%d moveGeneration=%d" - " frame=%p node=%p x=%d y=%d", - m_moveGeneration, moveGeneration, frame, node, x, y); + " frame=%p x=%d y=%d", + m_moveGeneration, moveGeneration, frame, x, y); if (m_moveGeneration > moveGeneration) { DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", m_moveGeneration, moveGeneration); return; // short-circuit if a newer move has already been generated } - m_useReplay = true; - bool newCache = prepareFrameCache(); // must wait for possible recompute before using - if (m_moveGeneration > moveGeneration) { - DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", - m_moveGeneration, moveGeneration); - releaseFrameCache(newCache); - return; // short-circuit if a newer move has already been generated - } - releaseFrameCache(newCache); m_lastGeneration = moveGeneration; - if (!node && ignoreNullFocus) - return; - moveMouse(frame, node, x, y); + moveMouse(frame, x, y); } static bool nodeIsPlugin(Node* node) { @@ -1213,10 +1144,10 @@ static bool nodeIsPlugin(Node* node) { } // Update mouse position and may change focused node. -bool WebViewCore::moveMouse(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) +void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y) { - DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d ", frame, node, x, y); + DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame, + x, y, m_scrollOffsetX, m_scrollOffsetY); if (!frame || CacheBuilder::validNode(m_mainFrame, frame, NULL) == false) frame = m_mainFrame; // mouse event expects the position in the window coordinate @@ -1227,16 +1158,6 @@ bool WebViewCore::moveMouse(WebCore::Frame* frame, WebCore::Node* node, WebCore::NoButton, WebCore::MouseEventMoved, 1, false, false, false, false, WTF::currentTime()); frame->eventHandler()->handleMouseMoveEvent(mouseEvent); - bool valid = CacheBuilder::validNode(m_mainFrame, frame, node); - if (!node || !valid) { - DBG_NAV_LOGD("exit: node=%p valid=%s", node, valid ? "true" : "false"); - return false; - } - - // hack to give the plugin focus (for keys). better fix on the way - if (nodeIsPlugin(node)) - node->document()->setFocusedNode(node); - return true; } static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt) @@ -1722,7 +1643,7 @@ void WebViewCore::touchUp(int touchGeneration, " x=%d y=%d", m_touchGeneration, touchGeneration, x, y); return; // short circuit if a newer touch has been generated } - moveMouse(frame, node, x, y); + moveMouse(frame, x, y); m_lastGeneration = touchGeneration; if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); @@ -2020,7 +1941,7 @@ static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, realScreenWidth, screenHeight); } -static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy) +static void SetScrollOffset(JNIEnv *env, jobject obj, jint gen, jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2028,7 +1949,7 @@ static void SetScrollOffset(JNIEnv *env, jobject obj, jint dx, jint dy) WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "need viewImpl"); - viewImpl->setScrollOffset(dx, dy); + viewImpl->setScrollOffset(gen, x, y); } static void SetGlobalBounds(JNIEnv *env, jobject obj, jint x, jint y, jint h, @@ -2254,7 +2175,7 @@ static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame, return 0; } -static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint node, +static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint x, jint y) { #ifdef ANDROID_INSTRUMENT @@ -2262,13 +2183,11 @@ static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint node, #endif WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->moveMouse((WebCore::Frame*) frame, (WebCore::Node*) node, x, - y); + viewImpl->moveMouse((WebCore::Frame*) frame, x, y); } static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, - jint frame, jint node, jint x, jint y, - jboolean ignoreNullFocus) + jint frame, jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); @@ -2276,8 +2195,7 @@ static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); viewImpl->moveMouseIfLatest(moveGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, - ignoreNullFocus); + (WebCore::Frame*) frame, x, y); } static void UpdateFrameCache(JNIEnv *env, jobject obj) @@ -2507,7 +2425,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SendListBoxChoice }, { "nativeSetSize", "(IIIFII)V", (void*) SetSize }, - { "nativeSetScrollOffset", "(II)V", + { "nativeSetScrollOffset", "(III)V", (void*) SetScrollOffset }, { "nativeSetGlobalBounds", "(IIII)V", (void*) SetGlobalBounds }, @@ -2517,9 +2435,9 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) DeleteSelection } , { "nativeReplaceTextfieldText", "(IILjava/lang/String;II)V", (void*) ReplaceTextfieldText } , - { "nativeMoveMouse", "(IIII)V", + { "nativeMoveMouse", "(III)V", (void*) MoveMouse }, - { "nativeMoveMouseIfLatest", "(IIIIIZ)V", + { "nativeMoveMouseIfLatest", "(IIII)V", (void*) MoveMouseIfLatest }, { "passToJs", "(ILjava/lang/String;IIZZZZ)V", (void*) PassToJs } , diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 7231941..4ba0074 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -195,14 +195,12 @@ namespace android { // Create a set of pictures to represent the drawn DOM, driven by // the invalidated region and the time required to draw (used to draw) void recordPictureSet(PictureSet* master); - bool moveMouse(WebCore::Frame* frame, WebCore::Node* node, - int x, int y); + void moveMouse(WebCore::Frame* frame, int x, int y); void moveMouseIfLatest(int moveGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - bool ignoreNullFocus); + WebCore::Frame* frame, int x, int y); // set the scroll amount that webview.java is currently showing - void setScrollOffset(int dx, int dy); + void setScrollOffset(int moveGeneration, int dx, int dy); void setGlobalBounds(int x, int y, int h, int v); @@ -327,10 +325,11 @@ namespace android { int m_touchGeneration; // copy of state in WebViewNative triggered by touch int m_lastGeneration; // last action using up to date cache bool m_updatedFrameCache; - bool m_useReplay; bool m_findIsUp; bool m_hasCursorBounds; WebCore::IntRect m_cursorBounds; + void* m_cursorFrame; + IntPoint m_cursorLocation; void* m_cursorNode; static Mutex gCursorBoundsMutex; // These two fields go together: we use the mutex to protect access to @@ -396,17 +395,11 @@ namespace android { this->drawPlugins(); } - WebCore::Frame* changedKitFocus(WebCore::Frame* frame, - WebCore::Node* node, int x, int y); void doMaxScroll(CacheBuilder::Direction dir); SkPicture* rebuildPicture(const SkIRect& inval); void rebuildPictureSet(PictureSet* ); - void sendMarkNodeInvalid(WebCore::Node* ); void sendNotifyProgressFinished(); - void sendRecomputeFocus(); bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); - bool prepareFrameCache(); - void releaseFrameCache(bool newCache); #if DEBUG_NAV_UI uint32_t m_now; #endif diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index da1d27b..116cfdd 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -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; @@ -682,6 +727,8 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) m_viewImpl->gCursorBoundsMutex.lock(); 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(); } @@ -1299,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; @@ -1689,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(); } @@ -1765,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", |