rebuild WebView nav cache on trackball move, other bugs

When the WebViewCore picture set is recomputed, check
to see if the trackball has moved since the last time.
If so, rebuild the nav cache even if dom version checking
is disabled.

If there's no focus node ready to receive a key event,
check to see if the cursor is hovering over a plugin, and
give it the event instead.

Update all cursor state in both places it could change.
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 73430ce..170e55d 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -284,6 +284,7 @@
 
     m_lastFocused = 0;
     m_lastFocusedBounds = WebCore::IntRect(0,0,0,0);
+    m_lastMoveGeneration = 0;
     clearContent();
     m_updatedFrameCache = true;
     m_frameCacheOutOfDate = true;
@@ -478,11 +479,6 @@
     m_frameCacheOutOfDate = true;
     WebCore::IntRect oldBounds = oldFocusNode ?
         oldFocusNode->getRect() : WebCore::IntRect(0,0,0,0);
-    DBG_NAV_LOGD("m_lastFocused=%p oldFocusNode=%p"
-        " m_lastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}",
-        m_lastFocused, oldFocusNode,
-        m_lastFocusedBounds.x(), m_lastFocusedBounds.y(), m_lastFocusedBounds.width(), m_lastFocusedBounds.height(),
-        oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height());
     unsigned latestVersion = 0;
     if (m_check_domtree_version) {
         // as domTreeVersion only increment, we can just check the sum to see
@@ -491,9 +487,19 @@
             latestVersion += frame->document()->domTreeVersion();
         }
     }
+    DBG_NAV_LOGD("m_lastFocused=%p oldFocusNode=%p"
+        " m_lastFocusedBounds={%d,%d,%d,%d} oldBounds={%d,%d,%d,%d}"
+        " m_check_domtree_version=%s latestVersion=%d m_domtree_version=%d",
+        m_lastFocused, oldFocusNode,
+        m_lastFocusedBounds.x(), m_lastFocusedBounds.y(),
+        m_lastFocusedBounds.width(), m_lastFocusedBounds.height(),
+        oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height(),
+        m_check_domtree_version ? "true" : "false",
+        latestVersion, m_domtree_version);
     bool update = m_lastFocused != oldFocusNode
         || m_lastFocusedBounds != oldBounds || m_findIsUp
-        || (m_check_domtree_version && latestVersion != m_domtree_version);
+        || (m_check_domtree_version && latestVersion != m_domtree_version)
+        || m_moveGeneration != m_lastMoveGeneration;
     if (!update) { // avoid mutex when possible
     // This block is specifically for the floating bar in gmail messages
     // it has been disabled because it adversely affects the performance
@@ -518,9 +524,9 @@
     }
     m_lastFocused = oldFocusNode;
     m_lastFocusedBounds = oldBounds;
-    DBG_NAV_LOGD("call updateFrameCache m_domtree_version=%d latest=%d",
-        m_domtree_version, latestVersion);
     m_domtree_version = latestVersion;
+    m_lastMoveGeneration = m_moveGeneration;
+    DBG_NAV_LOG("call updateFrameCache");
     updateFrameCache();
 }
 
@@ -1608,10 +1614,22 @@
 
 bool WebViewCore::key(int keyCode, UChar32 unichar, int repeatCount, bool isShift, bool isAlt, bool isDown)
 {
-    DBG_NAV_LOGD("key: keyCode=%d", keyCode);
-
     WebCore::EventHandler* eventHandler = m_mainFrame->eventHandler();
     WebCore::Node* focusNode = currentFocus();
+    if (!focusNode) {
+        gCursorBoundsMutex.lock();
+        bool hasCursorBounds = m_hasCursorBounds;
+        Frame* frame = (Frame*) m_cursorFrame;
+        Node* node = (Node*) m_cursorNode;
+        gCursorBoundsMutex.unlock();
+        if (hasCursorBounds
+                && CacheBuilder::validNode(m_mainFrame, frame, node)
+                && nodeIsPlugin(node)) {
+            // check if this plugin really wants the key (TODO)
+            DBG_NAV_LOGD("widget=%p is plugin", widget);
+            focusNode = node;
+        }
+    }
     if (focusNode) {
         eventHandler = focusNode->document()->frame()->eventHandler();
     }
@@ -1623,6 +1641,7 @@
     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));
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 4e737b6..e08bbb8 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -363,6 +363,7 @@
         WebCoreReply*          m_popupReply;
         WebCore::Node* m_lastFocused;
         WebCore::IntRect m_lastFocusedBounds;
+        int m_lastMoveGeneration;
         static Mutex m_contentMutex; // protects ui/core thread pictureset access
         PictureSet m_content; // the set of pictures to draw (accessed by UI too)
         SkRegion m_addInval; // the accumulated inval region (not yet drawn)
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 116cfdd..44f0f1f 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -404,14 +404,15 @@
 
 void drawCursorRing(SkCanvas* canvas)
 {
-    const CachedRoot* root = getFrameCache(AllowNewer);
+    CachedRoot* root = getFrameCache(AllowNewer);
     if (!root) {
         DBG_NAV_LOG("!root");
         m_followedLink = false;
         m_viewImpl->m_hasCursorBounds = false;
         return;
     }
-    const CachedNode* node = root->currentCursor();
+    const CachedFrame* frame;
+    const CachedNode* node = root->currentCursor(&frame);
     if (!node) {
         DBG_NAV_LOG("!node");
         m_followedLink = false;
@@ -453,6 +454,8 @@
         DBG_NAV_LOGD("new cursor bounds=(%d,%d,w=%d,h=%d)",
             bounds.x(), bounds.y(), bounds.width(), bounds.height());
     m_viewImpl->m_cursorBounds = bounds;
+    m_viewImpl->m_cursorFrame = frame->framePointer();
+    root->getSimulatedMousePosition(&m_viewImpl->m_cursorLocation);
     m_viewImpl->m_cursorNode = node->nodePointer();
     m_viewImpl->gCursorBoundsMutex.unlock();
     bounds.inflate(SkScalarCeil(CURSOR_RING_OUTER_DIAMETER));