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
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 @@
     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 @@
     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 @@
                 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 @@
     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 @@
     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 @@
     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::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 @@
 }
 
 // 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 @@
         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 @@
             " 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 @@
         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 @@
     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 @@
     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 @@
 #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 @@
     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 @@
         (void*) SendListBoxChoice },
     { "nativeSetSize", "(IIIFII)V",
         (void*) SetSize },
-    { "nativeSetScrollOffset", "(II)V",
+    { "nativeSetScrollOffset", "(III)V",
         (void*) SetScrollOffset },
     { "nativeSetGlobalBounds", "(IIII)V",
         (void*) SetGlobalBounds },
@@ -2517,9 +2435,9 @@
         (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 @@
         // 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 @@
         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 @@
             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 @@
     *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 @@
     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 @@
         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 @@
     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 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 @@
         (void*) nativeCursorIsAnchor },
     { "nativeCursorIsTextInput", "()Z",
         (void*) nativeCursorIsTextInput },
+    { "nativeCursorPosition", "()Landroid/graphics/Point;",
+        (void*) nativeCursorPosition },
     { "nativeCursorText", "()Ljava/lang/String;",
         (void*) nativeCursorText },
     { "nativeCursorWantsKeyEvents", "()Z",