diff options
author | Cary Clark <cary@android.com> | 2009-06-18 09:56:26 -0400 |
---|---|---|
committer | Cary Clark <cary@android.com> | 2009-06-18 10:54:35 -0400 |
commit | 36747fa778285f57f2f53c047028be83e9d8776d (patch) | |
tree | fae1627e7384bece4fd603930c7dc759c9b672d5 | |
parent | 56ce2fa12f7492cf355cfb37b80b679d7921f6d4 (diff) | |
download | external_webkit-36747fa778285f57f2f53c047028be83e9d8776d.zip external_webkit-36747fa778285f57f2f53c047028be83e9d8776d.tar.gz external_webkit-36747fa778285f57f2f53c047028be83e9d8776d.tar.bz2 |
clean up mouse move events in webview
Generate mouse move event after sending scroll event
Move cursor update in nav cache to UI thread
Remove updating nav cache on mouse move
Remove node parameter from mouse move
Remove plugin focus hack from mouse move
Add interface to get native cursor position
-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", |