diff options
author | Cary Clark <cary@android.com> | 2009-05-29 10:55:15 -0400 |
---|---|---|
committer | Cary Clark <cary@android.com> | 2009-06-01 16:11:38 -0400 |
commit | 46dfee13b2bec1b39f46c138df565b2207ccbc86 (patch) | |
tree | 567b54c6da71adcef3840717d082bfb908b71634 | |
parent | d0c887c5d9f5595e0c2075f65976def2282f9b42 (diff) | |
download | external_webkit-46dfee13b2bec1b39f46c138df565b2207ccbc86.zip external_webkit-46dfee13b2bec1b39f46c138df565b2207ccbc86.tar.gz external_webkit-46dfee13b2bec1b39f46c138df565b2207ccbc86.tar.bz2 |
in the browser, make the trackball more like a mouse
Older code treated the trackball as a four way dpad with
equivalents to moving up, down, left and right by generating
arrow key events. This change makes the trackball solely
generate mousemove events.
The old arrow keys in turn were mapped to be as close as
possible to tab-key events that moved the focus. The new
model leaves focus-changes to the DOM.
Clicking the dpad is distinguished from pressing the enter
key to be more compatible with desktop-authored web pages.
-rw-r--r-- | WebCore/page/Frame.cpp | 10 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/android_graphics.cpp | 52 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/android_graphics.h | 15 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 3 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 212 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 64 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 57 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.h | 4 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 432 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.h | 20 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.cpp | 79 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.h | 44 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 271 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.h | 21 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 1330 |
15 files changed, 1002 insertions, 1612 deletions
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index dcedaf5..1caae9a 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -228,16 +228,6 @@ FrameView* Frame::view() const void Frame::setView(FrameView* view) { -#if PLATFORM(ANDROID) - if (!view && m_view) { - // FIXME(for Cary): This is moved from FrameAndroid destructor. Do we - // need to call removeFrameGeneration per Frame or per FrameView? - android::WebViewCore* core = android::WebViewCore::getWebViewCore(m_view.get()); - if (core) - core->removeFrameGeneration(this); - } -#endif - // Detach the document now, so any onUnload handlers get run - if // we wait until the view is destroyed, then things won't be // hooked up enough for some JavaScript calls to work. diff --git a/WebCore/platform/graphics/android/android_graphics.cpp b/WebCore/platform/graphics/android/android_graphics.cpp index fc8a272..10dd5e7 100644 --- a/WebCore/platform/graphics/android/android_graphics.cpp +++ b/WebCore/platform/graphics/android/android_graphics.cpp @@ -33,32 +33,32 @@ /////////////////////////////////////////////////////////////////////////////// -const static SkColor focusOuterColors[] = { - SkColorSetARGB(0xff, 0xB3, 0x3F, 0x08), // normal focus ring select - SkColorSetARGB(0xff, 0x46, 0xb0, 0x00), // fake focus ring select, for phone, email, text - SkColorSetARGB(0xff, 0xb0, 0x16, 0x00), // invalid focus ring color - SkColorSetARGB(0xff, 0xAD, 0x5C, 0x0A), // normal focus ring pressed - SkColorSetARGB(0xff, 0x36, 0xc0, 0x00) // fake focus ring pressed +const static SkColor cursorOuterColors[] = { + SkColorSetARGB(0xff, 0xB3, 0x3F, 0x08), // normal ring select + SkColorSetARGB(0xff, 0x46, 0xb0, 0x00), // fake ring select, for phone, email, text + SkColorSetARGB(0xff, 0xb0, 0x16, 0x00), // invalid ring color + SkColorSetARGB(0xff, 0xAD, 0x5C, 0x0A), // normal ring pressed + SkColorSetARGB(0xff, 0x36, 0xc0, 0x00) // fake ring pressed }; -const static SkColor focusInnerColors[] = { - SkColorSetARGB(0xff, 0xFE, 0x92, 0x30), // normal focus ring select - SkColorSetARGB(0xff, 0x8c, 0xd9, 0x00), // fake focus ring select, for phone, email, text - SkColorSetARGB(0xff, 0xd9, 0x2c, 0x00), // invalid focus ring color - SkColorSetARGB(0xff, 0xFE, 0xBD, 0x3A), // normal focus ring pressed - SkColorSetARGB(0xff, 0x7c, 0xe9, 0x00) // fake focus ring pressed +const static SkColor cursorInnerColors[] = { + SkColorSetARGB(0xff, 0xFE, 0x92, 0x30), // normal ring select + SkColorSetARGB(0xff, 0x8c, 0xd9, 0x00), // fake ring select, for phone, email, text + SkColorSetARGB(0xff, 0xd9, 0x2c, 0x00), // invalid ring color + SkColorSetARGB(0xff, 0xFE, 0xBD, 0x3A), // normal ring pressed + SkColorSetARGB(0xff, 0x7c, 0xe9, 0x00) // fake ring pressed }; -const static SkColor focusPressedColors[] = { - SkColorSetARGB(0x80, 0xFF, 0xC6, 0x4B), // normal focus ring pressed - SkColorSetARGB(0x80, 0x7c, 0xe9, 0x00) // fake focus ring pressed +const static SkColor cursorPressedColors[] = { + SkColorSetARGB(0x80, 0xFF, 0xC6, 0x4B), // normal ring pressed + SkColorSetARGB(0x80, 0x7c, 0xe9, 0x00) // fake ring pressed }; -#define FOCUS_RING_ROUNDEDNESS SkIntToScalar(5) // used to draw corners -#define FOCUS_RING_INNER_DIAMETER SkFixedToScalar(SkIntToFixed(3)>>1) // 3/2 == 1.5 -#define FOCUS_RING_OUTER_OUTSET 2 // used to inflate rects added to region +#define CURSOR_RING_ROUNDEDNESS SkIntToScalar(5) // used to draw corners +#define CURSOR_RING_INNER_DIAMETER SkFixedToScalar(SkIntToFixed(3)>>1) // 3/2 == 1.5 +#define CURSOR_RING_OUTER_OUTSET 2 // used to inflate rects added to region -void FocusRing::DrawRing(SkCanvas* canvas, +void CursorRing::DrawRing(SkCanvas* canvas, const Vector<WebCore::IntRect>& rects, Flavor flavor) { unsigned rectCount = rects.size(); @@ -70,24 +70,24 @@ void FocusRing::DrawRing(SkCanvas* canvas, SkIRect ir; r.round(&ir); - ir.inset(-FOCUS_RING_OUTER_OUTSET, -FOCUS_RING_OUTER_OUTSET); + ir.inset(-CURSOR_RING_OUTER_OUTSET, -CURSOR_RING_OUTER_OUTSET); rgn.op(ir, SkRegion::kUnion_Op); } rgn.getBoundaryPath(&path); SkPaint paint; paint.setAntiAlias(true); - paint.setPathEffect(new SkCornerPathEffect(FOCUS_RING_ROUNDEDNESS))->unref(); + paint.setPathEffect(new SkCornerPathEffect(CURSOR_RING_ROUNDEDNESS))->unref(); if (flavor >= NORMAL_ANIMATING) { // pressed - paint.setColor(focusPressedColors[flavor - NORMAL_ANIMATING]); + paint.setColor(cursorPressedColors[flavor - NORMAL_ANIMATING]); canvas->drawPath(path, paint); } paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(FOCUS_RING_OUTER_DIAMETER); - paint.setColor(focusOuterColors[flavor]); + paint.setStrokeWidth(CURSOR_RING_OUTER_DIAMETER); + paint.setColor(cursorOuterColors[flavor]); canvas->drawPath(path, paint); - paint.setStrokeWidth(FOCUS_RING_INNER_DIAMETER); - paint.setColor(focusInnerColors[flavor]); + paint.setStrokeWidth(CURSOR_RING_INNER_DIAMETER); + paint.setColor(cursorInnerColors[flavor]); canvas->drawPath(path, paint); } diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h index 0853d85..d60c10b 100644 --- a/WebCore/platform/graphics/android/android_graphics.h +++ b/WebCore/platform/graphics/android/android_graphics.h @@ -39,15 +39,15 @@ namespace WebCore { SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc); -// Data and methods for focus rings +// Data and methods for cursor rings // used to inflate node cache entry -#define FOCUS_RING_HIT_TEST_RADIUS 5 +#define CURSOR_RING_HIT_TEST_RADIUS 5 -// used to inval rectangle enclosing pressed state of focus ring -#define FOCUS_RING_OUTER_DIAMETER SkFixedToScalar(SkIntToFixed(13)>>2) // 13/4 == 3.25 +// used to inval rectangle enclosing pressed state of ring +#define CURSOR_RING_OUTER_DIAMETER SkFixedToScalar(SkIntToFixed(13)>>2) // 13/4 == 3.25 -struct FocusRing { +struct CursorRing { public: enum Flavor { NORMAL_FLAVOR, @@ -57,10 +57,9 @@ public: FAKE_ANIMATING, ANIMATING_COUNT = 2 }; - - static void DrawRing(SkCanvas* , + + static void DrawRing(SkCanvas* , const Vector<WebCore::IntRect>& rects, Flavor ); }; #endif - diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp index 1f33f57..d312fb6 100644 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp @@ -257,8 +257,7 @@ void FrameLoaderClientAndroid::dispatchDidReceiveTitle(const String& title) { } void FrameLoaderClientAndroid::dispatchDidCommitLoad() { - ASSERT(m_frame); - WebViewCore::getWebViewCore(m_frame->view())->updateFrameGeneration(m_frame); + verifiedOk(); } static void loadDataIntoFrame(Frame* frame, KURL baseUrl, const String& url, diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index e40fd1d..6f65218 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -162,7 +162,6 @@ struct WebViewCore::JavaGlue { jmethodID m_jsInterrupt; jmethodID m_didFirstLayout; jmethodID m_sendMarkNodeInvalid; - jmethodID m_sendNotifyFocusSet; jmethodID m_sendNotifyProgressFinished; jmethodID m_sendRecomputeFocus; jmethodID m_sendViewInvalidate; @@ -187,10 +186,8 @@ static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const } Mutex WebViewCore::gFrameCacheMutex; -Mutex WebViewCore::gFrameGenerationMutex; -Mutex WebViewCore::gRecomputeFocusMutex; Mutex WebViewCore::gButtonMutex; -Mutex WebViewCore::gNotifyFocusMutex; +Mutex WebViewCore::gCursorBoundsMutex; Mutex WebViewCore::m_contentMutex; WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* mainframe) @@ -199,7 +196,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_mainFrame = mainframe; m_popupReply = 0; - m_buildGeneration = 0; m_moveGeneration = 0; m_generation = 0; m_lastGeneration = 0; @@ -230,7 +226,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_jsInterrupt = GetJMethod(env, clazz, "jsInterrupt", "()Z"); m_javaGlue->m_didFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Z)V"); m_javaGlue->m_sendMarkNodeInvalid = GetJMethod(env, clazz, "sendMarkNodeInvalid", "(I)V"); - m_javaGlue->m_sendNotifyFocusSet = GetJMethod(env, clazz, "sendNotifyFocusSet", "()V"); m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); m_javaGlue->m_sendRecomputeFocus = GetJMethod(env, clazz, "sendRecomputeFocus", "()V"); m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V"); @@ -302,7 +297,6 @@ void WebViewCore::reset(bool fromConstructor) m_domtree_version = 0; m_check_domtree_version = true; m_progressDone = false; - m_blockNotifyFocus = false; } static bool layoutIfNeededRecursive(WebCore::Frame* f) @@ -316,7 +310,7 @@ static bool layoutIfNeededRecursive(WebCore::Frame* f) if (v->needsLayout()) v->layout(f->tree()->parent()); - + WebCore::Frame* child = f->tree()->firstChild(); bool success = true; while (child) { @@ -480,13 +474,13 @@ void WebViewCore::recordPictureSet(PictureSet* content) 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 + // as domTreeVersion only increment, we can just check the sum to see // whether we need to update the frame cache for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) { latestVersion += frame->document()->domTreeVersion(); } } - if (m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds || m_findIsUp + if (m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds || m_findIsUp || (m_check_domtree_version && latestVersion != m_domtree_version)) { m_lastFocused = oldFocusNode; m_lastFocusedBounds = oldBounds; @@ -550,7 +544,7 @@ void WebViewCore::copyContentToPicture(SkPicture* picture) m_contentMutex.lock(); PictureSet copyContent = PictureSet(m_content); m_contentMutex.unlock(); - + int w = copyContent.width(); int h = copyContent.height(); copyContent.draw(picture->beginRecording(w, h, PICT_RECORD_FLAGS)); @@ -703,14 +697,6 @@ void WebViewCore::sendMarkNodeInvalid(WebCore::Node* node) checkException(env); } -void WebViewCore::sendNotifyFocusSet() -{ - LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendNotifyFocusSet); - checkException(env); -} - void WebViewCore::sendNotifyProgressFinished() { LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); @@ -728,7 +714,7 @@ void WebViewCore::sendRecomputeFocus() } void WebViewCore::viewInvalidate(const WebCore::IntRect& rect) -{ +{ LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); env->CallVoidMethod(m_javaGlue->object(env).get(), @@ -742,7 +728,7 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate) if (!(dx | dy)) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy, + env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy, dx, dy, animate); checkException(env); } @@ -831,11 +817,6 @@ void WebViewCore::needTouchEvents(bool need) #endif } -void WebViewCore::notifyFocusSet() -{ - sendNotifyFocusSet(); -} - void WebViewCore::notifyProgressFinished() { DBG_NAV_LOG("call updateFrameCache"); @@ -889,7 +870,7 @@ void WebViewCore::setGlobalBounds(int x, int y, int h, int v) m_mainFrame->view()->platformWidget()->setWindowBounds(x, y, h, v); } -void WebViewCore::setSizeScreenWidthAndScale(int width, int height, +void WebViewCore::setSizeScreenWidthAndScale(int width, int height, int screenWidth, int scale, int realScreenWidth, int screenHeight) { WebCoreViewBridge* window = m_mainFrame->view()->platformWidget(); @@ -905,7 +886,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, m_maxYScroll = (screenWidth * height / width) >> 2; if (ow != width || oh != height || osw != screenWidth) { WebCore::RenderObject *r = m_mainFrame->contentRenderer(); - DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r, + DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r, realScreenWidth, screenHeight); if (r) { // get current screen center position @@ -924,7 +905,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, offset = WebCore::IntPoint(screenCenter.x() - bounds.x(), screenCenter.y() - bounds.y()); if (offset.x() < 0 || offset.x() > realScreenWidth || - offset.y() < 0 || offset.y() > screenHeight) + offset.y() < 0 || offset.y() > screenHeight) { DBG_NAV_LOGD("offset out of bounds:(x=%d,y=%d)", offset.x(), offset.y()); @@ -938,7 +919,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, return; const WebCore::IntRect& newBounds = node->getRect(); DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d," - "h=%d,ns=%d)", newBounds.x(), newBounds.y(), + "h=%d,ns=%d)", newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(), false); @@ -1018,8 +999,6 @@ bool WebViewCore::prepareFrameCache() #endif m_temp = new CachedRoot(); m_temp->init(m_mainFrame, &m_history); - m_temp->setGeneration(++m_buildGeneration); - DBG_NAV_LOGD("m_buildGeneration=%d", m_buildGeneration); CacheBuilder& builder = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder(); WebCore::Settings* settings = m_mainFrame->page()->settings(); builder.allowAllTextDetection(); @@ -1038,20 +1017,26 @@ bool WebViewCore::prepareFrameCache() recordPicture(m_tempPict); m_temp->setPicture(m_tempPict); m_temp->setTextGeneration(m_textGeneration); - if (m_temp->currentFocus()) - return true; +// 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 IntRect& bounds = m_history.navBounds(); const CachedNode* node = m_temp->findAt(bounds, &frame, &x, &y); 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()); if (node) - m_temp->setCachedFocus(const_cast<CachedFrame*>(frame), + m_temp->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(node)); return true; } @@ -1069,14 +1054,15 @@ 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("cachedFocusNode=%d (nodePointer=%p)", + DBG_NAV_LOGD("cachedCursor=%d (%p) cachedFocusNode=%d (nodePointer=%p)", + cachedCursorNode ? cachedCursorNode->index() : 0, + cachedCursorNode ? cachedCursorNode->nodePointer() : 0, cachedFocusNode ? cachedFocusNode->index() : 0, cachedFocusNode ? cachedFocusNode->nodePointer() : 0); #endif gFrameCacheMutex.unlock(); - if (!m_blockNotifyFocus) - notifyFocusSet(); // 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 @@ -1089,59 +1075,6 @@ void WebViewCore::updateFrameCache() releaseFrameCache(prepareFrameCache()); } -void WebViewCore::removeFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p m_generation=%d", frame, m_generation); - gFrameGenerationMutex.lock(); - int last = m_frameGenerations.size() - 1; - for (int index = 0; index <= last; index++) { - if (m_frameGenerations[index].m_frame == frame) { - DBG_NAV_LOGD("index=%d last=%d", index, last); - if (index != last) - m_frameGenerations[index] = m_frameGenerations[last]; - m_frameGenerations.removeLast(); - break; - } - } - gFrameGenerationMutex.unlock(); -} - -void WebViewCore::updateFrameGeneration(WebCore::Frame* frame) -{ - DBG_NAV_LOGD("frame=%p m_generation=%d", frame, m_generation); - gFrameGenerationMutex.lock(); - ++m_buildGeneration; - for (size_t index = 0; index < m_frameGenerations.size(); index++) { - if (m_frameGenerations[index].m_frame == frame) { - DBG_NAV_LOG("replace"); - m_frameGenerations[index].m_generation = m_buildGeneration; - goto done; - } - } - { - FrameGen frameGen = {frame, m_buildGeneration}; - m_frameGenerations.append(frameGen); - DBG_NAV_LOG("append"); - } -done: - gFrameGenerationMutex.unlock(); -} - -int WebViewCore::retrieveFrameGeneration(WebCore::Frame* frame) -{ - int result = INT_MAX; - gFrameGenerationMutex.lock(); - for (size_t index = 0; index < m_frameGenerations.size(); index++) { - if (m_frameGenerations[index].m_frame == frame) { - result = m_frameGenerations[index].m_generation; - break; - } - } - gFrameGenerationMutex.unlock(); - DBG_NAV_LOGD("frame=%p m_generation=%d result=%d", frame, m_generation, result); - return result; -} - /////////////////////////////////////////////////////////////////////////////// void WebViewCore::addPlugin(PluginWidgetAndroid* w) @@ -1205,35 +1138,13 @@ void WebViewCore::sendPluginEvent(const ANPEvent& evt) } /////////////////////////////////////////////////////////////////////////////// - -void WebViewCore::setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block) -{ - DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d", frame, node, x, y); - bool result = finalKitFocus(frame, node, x, y); - bool callNotify = false; - gNotifyFocusMutex.lock(); - if (m_blockNotifyFocus) { - m_blockNotifyFocus = false; - callNotify = true; - } - gNotifyFocusMutex.unlock(); - if (callNotify) - notifyFocusSet(); - if (block) { - m_blockFocusChange = true; - if (!result && node) - touchUp(m_touchGeneration, 0, 0, 0, x, y, 0, true); - } -} - -void WebViewCore::setKitFocus(int moveGeneration, int buildGeneration, +void WebViewCore::moveMouseIfLatest(int moveGeneration, WebCore::Frame* frame, WebCore::Node* node, int x, int y, bool ignoreNullFocus) { DBG_NAV_LOGD("m_moveGeneration=%d moveGeneration=%d" - " buildGeneration=%d frame=%p node=%p x=%d y=%d", - m_moveGeneration, moveGeneration, buildGeneration, frame, node, x, y); + " frame=%p node=%p x=%d y=%d", + m_moveGeneration, moveGeneration, frame, node, x, y); if (m_blockFocusChange) { DBG_NAV_LOG("m_blockFocusChange"); return; @@ -1251,26 +1162,11 @@ void WebViewCore::setKitFocus(int moveGeneration, int buildGeneration, releaseFrameCache(newCache); return; // short-circuit if a newer move has already been generated } - // if the nav cache has been rebuilt since this focus request was generated, - // send a request back to the UI side to recompute the kit-side focus - if (m_buildGeneration > buildGeneration - || (node && !CacheBuilder::validNode(m_mainFrame, frame, node))) { - DBG_NAV_LOGD("m_buildGeneration=%d > buildGeneration=%d", - m_buildGeneration, buildGeneration); - gRecomputeFocusMutex.lock(); - bool first = !m_recomputeEvents.size(); - m_recomputeEvents.append(moveGeneration); - gRecomputeFocusMutex.unlock(); - releaseFrameCache(newCache); - if (first) - sendRecomputeFocus(); - return; - } releaseFrameCache(newCache); m_lastGeneration = moveGeneration; if (!node && ignoreNullFocus) return; - finalKitFocus(frame, node, x, y); + moveMouse(frame, node, x, y); } static bool nodeIsPlugin(Node* node) { @@ -1283,7 +1179,7 @@ static bool nodeIsPlugin(Node* node) { } // Update mouse position and may change focused node. -bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, +bool WebViewCore::moveMouse(WebCore::Frame* frame, WebCore::Node* node, int x, int y) { DBG_NAV_LOGD("frame=%p node=%p x=%d y=%d ", frame, node, x, y); @@ -1305,10 +1201,6 @@ bool WebViewCore::finalKitFocus(WebCore::Frame* frame, WebCore::Node* node, DBG_NAV_LOGD("exit: node=%p valid=%s", node, valid ? "true" : "false"); return false; } - DBG_NAV_LOGD("setFocusedNode node=%p", node); - builder.setLastFocus(node); - m_lastFocused = node; - m_lastFocusedBounds = node->getRect(); // hack to give the plugin focus (for keys). better fix on the way if (nodeIsPlugin(node)) @@ -1348,7 +1240,7 @@ WebCore::Frame* WebViewCore::changedKitFocus(WebCore::Frame* frame, WebCore::Node* current = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder().currentFocus(); if (current == node) return frame; - return finalKitFocus(frame, node, x, y) ? frame : m_mainFrame; + return moveMouse(frame, node, x, y) ? frame : m_mainFrame; } static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt) @@ -1590,6 +1482,8 @@ void WebViewCore::passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, in WebCore::Node* currentFocus = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder().currentFocus(); // Make sure we have the same focus and it is a text field. + DBG_NAV_LOGD("node=%p currentFocus=%p xy=(%d, %d) keyCode=%d keyValue=%d", + node, currentFocus, x, y, keyCode, keyValue); if (node == currentFocus && currentFocus) { WebCore::RenderObject* renderer = currentFocus->renderer(); if (renderer && (renderer->isTextField() || renderer->isTextArea())) { @@ -1813,7 +1707,7 @@ bool WebViewCore::click() { keyHandled = handleMouseClick(focusNode->document()->frame(), focusNode); WebFrame::getWebFrame(m_mainFrame)->setUserInitiatedClick(false); } - // match in setFinalFocus() + // match in moveMouse() m_blockFocusChange = false; return keyHandled; } @@ -1846,16 +1740,15 @@ bool WebViewCore::handleTouchEvent(int action, int x, int y) return preventDefault; } -void WebViewCore::touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size, - bool retry) +void WebViewCore::touchUp(int touchGeneration, + WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size) { if (m_touchGeneration > touchGeneration) { DBG_NAV_LOGD("m_touchGeneration=%d > touchGeneration=%d" " x=%d y=%d", m_touchGeneration, touchGeneration, x, y); return; // short circuit if a newer touch has been generated } - finalKitFocus(frame, node, x, y); + moveMouse(frame, node, x, y); m_lastGeneration = touchGeneration; if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); @@ -2349,16 +2242,15 @@ static jboolean HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, } static void TouchUp(JNIEnv *env, jobject obj, jint touchGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, jint size, - jboolean retry) + jint frame, jint node, jint x, jint y, jint size) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); #endif WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->touchUp(touchGeneration, buildGeneration, - (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, size, retry); + viewImpl->touchUp(touchGeneration, + (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, size); } static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame, @@ -2376,20 +2268,20 @@ static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame, return 0; } -static void SetFinalFocus(JNIEnv *env, jobject obj, jint frame, jint node, - jint x, jint y, jboolean block) +static void MoveMouse(JNIEnv *env, jobject obj, jint frame, jint node, + jint x, jint y) { #ifdef ANDROID_INSTRUMENT TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter); #endif WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setFinalFocus((WebCore::Frame*) frame, (WebCore::Node*) node, x, - y, block); + viewImpl->moveMouse((WebCore::Frame*) frame, (WebCore::Node*) node, x, + y); } -static void SetKitFocus(JNIEnv *env, jobject obj, jint moveGeneration, - jint buildGeneration, jint frame, jint node, jint x, jint y, +static void MoveMouseIfLatest(JNIEnv *env, jobject obj, jint moveGeneration, + jint frame, jint node, jint x, jint y, jboolean ignoreNullFocus) { #ifdef ANDROID_INSTRUMENT @@ -2397,7 +2289,7 @@ static void SetKitFocus(JNIEnv *env, jobject obj, jint moveGeneration, #endif WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__); - viewImpl->setKitFocus(moveGeneration, buildGeneration, + viewImpl->moveMouseIfLatest(moveGeneration, (WebCore::Frame*) frame, (WebCore::Node*) node, x, y, ignoreNullFocus); } @@ -2639,6 +2531,10 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) DeleteSelection } , { "nativeReplaceTextfieldText", "(IIIIIILjava/lang/String;II)V", (void*) ReplaceTextfieldText } , + { "nativeMoveMouse", "(IIII)V", + (void*) MoveMouse }, + { "nativeMoveMouseIfLatest", "(IIIIIZ)V", + (void*) MoveMouseIfLatest }, { "passToJs", "(IIIIILjava/lang/String;IIZZZZ)V", (void*) PassToJs } , { "nativeSetFocusControllerActive", "(Z)V", @@ -2649,14 +2545,10 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) FindAddress }, { "nativeHandleTouchEvent", "(III)Z", (void*) HandleTouchEvent }, - { "nativeTouchUp", "(IIIIIIIZ)V", + { "nativeTouchUp", "(IIIIII)V", (void*) TouchUp }, { "nativeRetrieveHref", "(II)Ljava/lang/String;", (void*) RetrieveHref }, - { "nativeSetFinalFocus", "(IIIIZ)V", - (void*) SetFinalFocus }, - { "nativeSetKitFocus", "(IIIIIIZ)V", - (void*) SetKitFocus }, { "nativeUnblockFocus", "()V", (void*) UnblockFocus }, { "nativeUpdateFrameCache", "()V", diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index cd9de55..b8eeeff 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -58,7 +58,7 @@ class SkIRect; struct ANPEvent; namespace android { - + class CachedRoot; class ListBoxReply; @@ -133,12 +133,6 @@ namespace android { void offInvalidate(const WebCore::IntRect &rect); /** - * Called by webcore when the focus was set after returning to prior page - * used to rebuild and display any changes in focus - */ - void notifyFocusSet(); - - /** * Called by webcore when the progress indicator is done * used to rebuild and display any changes in focus */ @@ -150,7 +144,7 @@ namespace android { void didFirstLayout(); /** - * Notify the view to restore the screen width, which in turn restores + * Notify the view to restore the screen width, which in turn restores * the scale. */ void restoreScale(int); @@ -192,16 +186,16 @@ namespace android { WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node); WebCore::String getSelection(SkRegion* ); - + // Create a single picture to represent the drawn DOM (used by navcache) void recordPicture(SkPicture* picture); - + // 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); - void setFinalFocus(WebCore::Frame* frame, WebCore::Node* node, - int x, int y, bool block); - void setKitFocus(int moveGeneration, int buildGeneration, + bool moveMouse(WebCore::Frame* frame, WebCore::Node* node, + int x, int y); + void moveMouseIfLatest(int moveGeneration, WebCore::Frame* frame, WebCore::Node* node, int x, int y, bool ignoreNullFocus); @@ -210,7 +204,7 @@ namespace android { void setGlobalBounds(int x, int y, int h, int v); - void setSizeScreenWidthAndScale(int width, int height, int screenWidth, + void setSizeScreenWidthAndScale(int width, int height, int screenWidth, int scale, int realScreenWidth, int screenHeight); /** @@ -233,10 +227,9 @@ namespace android { * Handle motionUp event from the UI thread (called touchUp in the * WebCore thread). */ - void touchUp(int touchGeneration, int buildGeneration, - WebCore::Frame* frame, WebCore::Node* node, int x, int y, - int size, bool retry); - + void touchUp(int touchGeneration, + WebCore::Frame* frame, WebCore::Node* node, int x, int y, int size); + /** * Sets the index of the label from a popup */ @@ -245,7 +238,7 @@ namespace android { /** * Delete text from start to end in the focused textfield. If there is no - * focus, or if start == end, silently fail, but set selection to that value. + * focus, or if start == end, silently fail, but set selection to that value. * If start and end are out of order, swap them. * Use the frame, node, x, and y to ensure that the correct node is focused. * Return a frame. Convenience so replaceTextfieldText can use this function. @@ -267,7 +260,7 @@ namespace android { * (if oldStart == oldEnd, this will be an insert at that position) with replace, * and set the selection to (start, end). */ - void replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, + void replaceTextfieldText(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int oldStart, int oldEnd, jstring replace, int start, int end); void passToJs(WebCore::Frame* frame, WebCore::Node* node, int x, int y, int generation, jstring currentText, int jKeyCode, int keyVal, bool down, bool cap, bool fn, bool sym); @@ -309,30 +302,27 @@ namespace android { // other public functions public: - void removeFrameGeneration(WebCore::Frame* ); - void updateFrameGeneration(WebCore::Frame* ); // reset the picture set to empty void clearContent(); - + // flatten the picture set to a picture void copyContentToPicture(SkPicture* ); - + // draw the picture set with the specified background color bool drawContent(SkCanvas* , SkColor ); bool pictureReady(); - + // record the inval area, and the picture size bool recordContent(SkRegion* , SkIPoint* ); int screenWidth() const { return m_screenWidth; } int scale() const { return m_scale; } WebCore::Frame* mainFrame() const { return m_mainFrame; } - + // utility to split slow parts of the picture set void splitContent(); - + // these members are shared with webview.cpp - int retrieveFrameGeneration(WebCore::Frame* ); static Mutex gFrameCacheMutex; CachedRoot* m_frameCacheKit; // nav data being built by webcore SkPicture* m_navPictureKit; @@ -343,10 +333,9 @@ namespace android { bool m_updatedFrameCache; bool m_useReplay; bool m_findIsUp; - bool m_blockNotifyFocus; - static Mutex gRecomputeFocusMutex; - static Mutex gNotifyFocusMutex; - WTF::Vector<int> m_recomputeEvents; + bool m_hasCursorBounds; + WebCore::IntRect m_cursorBounds; + static Mutex gCursorBoundsMutex; // These two fields go together: we use the mutex to protect access to // m_buttons, so that we, and webview.cpp can look/modify the m_buttons // field safely from our respective threads @@ -367,12 +356,6 @@ namespace android { bool multiple, const int selected[], size_t selectedCountOrSelection); friend class ListBoxReply; - struct FrameGen { - const WebCore::Frame* m_frame; - int m_generation; - }; - WTF::Vector<FrameGen> m_frameGenerations; - static Mutex gFrameGenerationMutex; struct JavaGlue; struct JavaGlue* m_javaGlue; WebCore::Frame* m_mainFrame; @@ -392,7 +375,6 @@ namespace android { int m_textGeneration; CachedRoot* m_temp; SkPicture* m_tempPict; - int m_buildGeneration; int m_maxXScroll; int m_maxYScroll; int m_scrollOffsetX; // webview.java's current scroll in X @@ -409,7 +391,7 @@ namespace android { int m_scale; unsigned m_domtree_version; bool m_check_domtree_version; - + SkTDArray<PluginWidgetAndroid*> m_plugins; WebCore::Timer<WebViewCore> m_pluginInvalTimer; void pluginInvalTimerFired(WebCore::Timer<WebViewCore>*) { @@ -418,12 +400,10 @@ namespace android { WebCore::Frame* changedKitFocus(WebCore::Frame* frame, WebCore::Node* node, int x, int y); - bool finalKitFocus(WebCore::Frame* , WebCore::Node* , int x, int y); void doMaxScroll(CacheBuilder::Direction dir); SkPicture* rebuildPicture(const SkIRect& inval); void rebuildPictureSet(PictureSet* ); void sendMarkNodeInvalid(WebCore::Node* ); - void sendNotifyFocusSet(); void sendNotifyProgressFinished(); void sendRecomputeFocus(); bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index 02f4605..1d6ac5e 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -721,7 +721,6 @@ void CacheBuilder::Debug::wideString(const String& str) { CacheBuilder::CacheBuilder() { - mLastKnownFocus = NULL; mAllowableTypes = ALL_CACHEDNODETYPES; #ifdef DUMP_NAV_CACHE_USING_PRINTF gNavCacheLogFile = NULL; @@ -821,7 +820,6 @@ bool CacheBuilder::AnyIsClick(Node* node) void CacheBuilder::buildCache(CachedRoot* root) { Frame* frame = FrameAnd(this); - mLastKnownFocus = NULL; BuildFrame(frame, frame, root, (CachedFrame*) root); root->finishInit(); // set up frame parent pointers, child pointers setData((CachedFrame*) root); @@ -903,10 +901,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, Node* node = parent; int cacheIndex = 1; Node* focused = doc->focusedNode(); - if (focused) { - setLastFocus(focused); - cachedRoot->setFocusBounds(mLastKnownFocusBounds); - } + if (focused) + cachedRoot->setFocusBounds(focused->getRect()); int globalOffsetX, globalOffsetY; GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); while (walk.mMore || (node = node->traverseNextNode()) != NULL) { @@ -974,20 +970,20 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, } RenderObject* nodeRenderer = node->renderer(); bool isTransparent = false; - bool hasFocusRing = true; + bool hasCursorRing = true; if (nodeRenderer != NULL) { RenderStyle* style = nodeRenderer->style(); if (style->visibility() == HIDDEN) continue; isTransparent = style->hasBackground() == false; #ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR - hasFocusRing = style->tapHighlightColor().alpha() > 0; + hasCursorRing = style->tapHighlightColor().alpha() > 0; #endif } bool more = walk.mMore; walk.reset(); // GetGlobalBounds(node, &bounds, false); - bool computeFocusRings = false; + bool computeCursorRings = false; bool hasClip = false; bool hasMouseOver = false; bool isAnchor = false; @@ -1087,7 +1083,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, IntRect(0, 0, INT_MAX, INT_MAX); if (ConstructTextRects((WebCore::Text*) node, walk.mStart, (WebCore::Text*) walk.mFinalNode, walk.mEnd, globalOffsetX, - globalOffsetY, &bounds, clip, &cachedNode.focusRings()) == false) + globalOffsetY, &bounds, clip, &cachedNode.cursorRings()) == false) continue; absBounds = bounds; cachedNode.setBounds(bounds); @@ -1095,7 +1091,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, continue; if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT) continue; - computeFocusRings = true; + computeCursorRings = true; isUnclipped = true; // FIXME: to hide or partially occlude synthesized links, each // focus ring will also need the offset and length of characters // used to produce it @@ -1179,14 +1175,14 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, continue; bounds.move(globalOffsetX, globalOffsetY); } - computeFocusRings = true; + computeCursorRings = true; keepNode: cachedNode.init(node); - if (computeFocusRings == false) { + if (computeCursorRings == false) { cachedNode.setBounds(bounds); - cachedNode.focusRings().append(bounds); + cachedNode.cursorRings().append(bounds); } else if (ConstructPartRects(node, bounds, cachedNode.boundsPtr(), - globalOffsetX, globalOffsetY, &cachedNode.focusRings()) == false) + globalOffsetX, globalOffsetY, &cachedNode.cursorRings()) == false) continue; keepTextNode: IntRect clip = hasClip ? bounds : absBounds; @@ -1208,13 +1204,13 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, } if (hasClip && cachedNode.clip(clip) == false) { cachedNode.setBounds(clip); - cachedNode.focusRings().append(clip); + cachedNode.cursorRings().append(clip); isUnclipped = true; } cachedNode.setNavableRects(); cachedNode.setChildFrameIndex(-1); cachedNode.setExport(exported); - cachedNode.setHasFocusRing(hasFocusRing); + cachedNode.setHasCursorRing(hasCursorRing); cachedNode.setHasMouseOver(hasMouseOver); cachedNode.setHitBounds(absBounds); cachedNode.setIndex(cacheIndex); @@ -1287,7 +1283,7 @@ bool CacheBuilder::CleanUpContainedNodes(CachedFrame* cachedFrame, lastNode->hasTagName(HTMLNames::bodyTag) || lastNode->hasTagName(HTMLNames::formTag)) { lastCached->setBounds(IntRect(0, 0, 0, 0)); - lastCached->focusRings().clear(); + lastCached->cursorRings().clear(); lastCached->setNavableRects(); return false; } @@ -1299,8 +1295,6 @@ bool CacheBuilder::CleanUpContainedNodes(CachedFrame* cachedFrame, lastNode->isFocusable() == false && HasOverOrOut(lastNode) == true && HasTriggerEvent(lastNode) == false; - if (cachedFrame->focusIndex() == lastChildIndex) - cachedFrame->setFocusIndex(last->mCachedNodeIndex); if (onlyChildCached->parent() == lastCached) onlyChildCached->setParentIndex(lastCached->parentIndex()); if (outerIsMouseMoveOnly || onlyChild->isKeyboardFocusable(NULL)) @@ -2649,29 +2643,6 @@ bool CacheBuilder::IsMailboxChar(UChar ch) return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0; } -bool CacheBuilder::outOfDate() -{ - Node* kitFocusNode = currentFocus(); - if (mLastKnownFocus != kitFocusNode) { - DBG_NAV_LOGD("%s\n", "mLastKnownFocus != kitFocusNode"); - return true; - } - if (kitFocusNode == NULL) - return false; - IntRect kitBounds = kitFocusNode->getRect(); - bool result = kitBounds != mLastKnownFocusBounds; - if (result == true) - DBG_NAV_LOGD("%s\n", "kitBounds != mLastKnownFocusBounds"); - return result; -} - -void CacheBuilder::setLastFocus(Node* node) -{ - ASSERT(node); - mLastKnownFocus = node; - mLastKnownFocusBounds = node->getRect(); -} - bool CacheBuilder::setData(CachedFrame* cachedFrame) { Frame* frame = FrameAnd(this); diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h index 667f149..3990cab 100644 --- a/WebKit/android/nav/CacheBuilder.h +++ b/WebKit/android/nav/CacheBuilder.h @@ -91,8 +91,6 @@ public: static FoundState FindAddress(const UChar* , unsigned length, int* start, int* end); static void GetGlobalOffset(Frame* , int* x, int * y); static void GetGlobalOffset(Node* , int* x, int * y); - bool outOfDate(); - void setLastFocus(Node* ); static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr); private: enum AddressProgress { @@ -225,8 +223,6 @@ private: bool setData(CachedFrame* ); Node* tryFocus(Direction direction); Node* trySegment(Direction direction, int mainStart, int mainEnd); - Node* mLastKnownFocus; - IntRect mLastKnownFocusBounds; CachedNodeType mAllowableTypes; #if DUMP_NAV_CACHE public: diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index f68c2f2..ffd0f1b 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -36,7 +36,7 @@ namespace android { -bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, +bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, const WebCore::IntRect& prior, WebCore::IntRect* result) { int left, top, width, height; @@ -86,7 +86,7 @@ bool CachedFrame::checkBetween(BestData* best, Direction direction) do { WebCore::IntRect edges; Direction check = (Direction) (index & DIRECTION_MASK); - if (CheckBetween(check, bestRect, + if (CheckBetween(check, bestRect, history()->priorBounds(), &edges) == false) continue; WebCore::IntRect clip = mRoot->scrolledBounds(); @@ -96,7 +96,7 @@ bool CachedFrame::checkBetween(BestData* best, Direction direction) findClosest(&test, direction, check, &clip); if (test.mNode == NULL) continue; - if (direction == check) + if (direction == check) break; } while (++index < limit); if (test.mNode == NULL) @@ -105,47 +105,45 @@ bool CachedFrame::checkBetween(BestData* best, Direction direction) return true; } -bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const -{ - return history()->checkVisited(node, direction); +bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const +{ + return history()->checkVisited(node, direction); } -void CachedFrame::clearFocus() +void CachedFrame::clearCursor() { - if (mFocus < 0) + if (mCursorIndex < 0) return; - CachedNode& focus = mCachedNodes[mFocus]; - focus.clearFocus(this); - mFocus = -1; + CachedNode& cursor = mCachedNodes[mCursorIndex]; + cursor.clearCursor(this); + mCursorIndex = -1; } -// the thing that sucks is that when you're on a link, you want to navigate next door to a link just like this one, but can't make it -// so with all my other sucky compares, maybe there needs to be one that prefers links that are aligned with the current focus... - // returns 0 if test is preferable to best, 1 if not preferable, or -1 if unknown -int CachedFrame::compare(BestData& testData, const BestData& bestData, const CachedNode* focus) const +int CachedFrame::compare(BestData& testData, const BestData& bestData, + const CachedNode* cursor) const { if (testData.mNode->tabIndex() != bestData.mNode->tabIndex()) { if (testData.mNode->tabIndex() < bestData.mNode->tabIndex() - || (focus && focus->tabIndex() < bestData.mNode->tabIndex())) { + || (cursor && cursor->tabIndex() < bestData.mNode->tabIndex())) { testData.mNode->setCondition(CachedNode::HIGHER_TAB_INDEX); return REJECT_TEST; } return TEST_IS_BEST; } -// start here; - // if the test minor axis line intersects the line segment between focus center and best center, choose it + // if the test minor axis line intersects the line segment between cursor + // center and best center, choose it // give more weight to exact major axis alignment (rows, columns) if (testData.mInNav != bestData.mInNav) { if (bestData.mInNav) { - testData.mNode->setCondition(CachedNode::IN_FOCUS); + testData.mNode->setCondition(CachedNode::IN_CURSOR); return REJECT_TEST; } return TEST_IS_BEST; } if (testData.mInNav) { if (bestData.mMajorDelta < testData.mMajorDelta) { - testData.mNode->setCondition(CachedNode::CLOSER_IN_FOCUS); + testData.mNode->setCondition(CachedNode::CLOSER_IN_CURSOR); return REJECT_TEST; } if (testData.mMajorDelta < bestData.mMajorDelta) @@ -157,13 +155,6 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac } if ((testData.mMajorDelta ^ bestData.mMajorDelta) < 0) // one above, one below (or one left, one right) return TEST_IS_BEST; -// SkFixed focusMultiplier = SK_Fixed1; -// if (focus != NULL) { -// if (testData.mMajorDelta < bestData.mMajorDelta) { -// // use bestData.mMajorDelta, -// } else if (bestData.mMajorDelta < testData.mMajorDelta) { -// -// } bool bestInWorking = bestData.inOrSubsumesWorking(); bool testInWorking = testData.inOrSubsumesWorking(); if (bestInWorking && testData.mWorkingOutside && testData.mNavOutside) { @@ -183,9 +174,9 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac return TEST_IS_BEST; } #if 01 // hopefully butt test will remove need for this - if (testData.mFocusChild != bestData.mFocusChild) { - if (bestData.mFocusChild) { - testData.mNode->setCondition(CachedNode::IN_FOCUS_CHILDREN); + if (testData.mCursorChild != bestData.mCursorChild) { + if (bestData.mCursorChild) { + testData.mNode->setCondition(CachedNode::IN_CURSOR_CHILDREN); return REJECT_TEST; } return TEST_IS_BEST; @@ -210,7 +201,7 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac } if (testOverlap && testData.mMajorDelta < bestData.mMajorDelta) return TEST_IS_BEST; - if (bestOverlap && bestData.mMajorDelta2 < testData.mMajorDelta2) { + if (bestOverlap && bestData.mMajorDelta2 < testData.mMajorDelta2) { testData.mNode->setCondition(CachedNode::CLOSER_TOP); return REJECT_TEST; } @@ -218,7 +209,7 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac return TEST_IS_BEST; #if 01 if (bestOverlap && ((bestData.mSideDistance <= 0 && testData.mSideDistance > 0) || - abs(bestData.mSideDistance) < abs(testData.mSideDistance))) { + abs(bestData.mSideDistance) < abs(testData.mSideDistance))) { testData.mNode->setCondition(CachedNode::LEFTMOST); return REJECT_TEST; } @@ -240,7 +231,7 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac // and off by a lot causes sideDistance to have little or no effect // try elliptical distance -- lengthen side contribution // these ASSERTs should not fire, but do fire on mail.google.com - // can't debug yet, won't reproduce + // can't debug yet, won't reproduce ASSERT(testDistance >= 0); ASSERT(bestDistance >= 0); testDistance += testDistance; // multiply by 2 @@ -295,23 +286,36 @@ int CachedFrame::compare(BestData& testData, const BestData& bestData, const Cac return UNDECIDED; } -const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const +const CachedNode* CachedFrame::currentCursor(const CachedFrame** framePtr) const { if (framePtr) *framePtr = this; - if (mFocus < 0) + if (mCursorIndex < 0) return NULL; - const CachedNode* result = &mCachedNodes[mFocus]; + const CachedNode* result = &mCachedNodes[mCursorIndex]; + const CachedFrame* frame = hasFrame(result); + if (frame != NULL) + return frame->currentCursor(framePtr); + (const_cast<CachedNode*>(result))->fixUpCursorRects(mRoot); + return result; +} + +const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const +{ + if (framePtr) + *framePtr = this; + if (mFocusIndex < 0) + return NULL; + const CachedNode* result = &mCachedNodes[mFocusIndex]; const CachedFrame* frame = hasFrame(result); if (frame != NULL) return frame->currentFocus(framePtr); - (const_cast<CachedNode*>(result))->fixUpFocusRects(mRoot); return result; } -bool CachedFrame::directionChange() const -{ - return history()->directionChange(); +bool CachedFrame::directionChange() const +{ + return history()->directionChange(); } #ifdef BROWSER_DEBUG @@ -320,13 +324,13 @@ CachedNode* CachedFrame::find(WebCore::Node* node) // !!! probably debugging onl for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) if (node == test->webCoreNode()) return test; - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); + for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); frame++) { CachedNode* result = frame->find(node); if (result != NULL) return result; } - return NULL; + return NULL; } #endif @@ -347,11 +351,11 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, int* bes testData.mMouseBounds = testData.mNodeBounds = test->getBounds(); bool checkForHidden = true; for (size_t part = 0; part < parts; part++) { - if (test->focusRings().at(part).intersects(rect)) { + if (test->cursorRings().at(part).intersects(rect)) { if (checkForHidden && mRoot->maskIfHidden(&testData) == true) break; checkForHidden = false; - WebCore::IntRect testRect = test->focusRings().at(part); + WebCore::IntRect testRect = test->cursorRings().at(part); testRect.intersect(testData.mMouseBounds); if (testRect.contains(center)) { // We have a direct hit. @@ -372,12 +376,12 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, int* bes } } if (NULL != *directHit) { - // If we have a direct hit already, there is no need to - // calculate the distances, or check the other focusring parts + // If we have a direct hit already, there is no need to + // calculate the distances, or check the other parts break; } WebCore::IntRect both = rect; - int smaller = testRect.width() < testRect.height() ? + int smaller = testRect.width() < testRect.height() ? testRect.width() : testRect.height(); smaller -= rectWidth; int inset = smaller < rectWidth ? smaller : rectWidth; @@ -390,7 +394,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, int* bes bool testInside = testRect.contains(center); if (*inside && !testInside) continue; - WebCore::IntPoint testCenter = WebCore::IntPoint(testRect.x() + + WebCore::IntPoint testCenter = WebCore::IntPoint(testRect.x() + (testRect.width() >> 1), testRect.y() + (testRect.height() >> 1)); int dx = testCenter.x() - center.x(); int dy = testCenter.y() - center.y(); @@ -406,7 +410,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, int* bes } } } - for (const CachedFrame* frame = mCachedFrames.begin(); + for (const CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); frame++) { const CachedNode* frameResult = frame->findBestAt(rect, best, inside, directHit, framePtr, x, y); @@ -424,7 +428,7 @@ const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const if (mLocalViewBounds.contains(x, y) == false) return NULL; const CachedFrame* result = this; - for (const CachedFrame* frame = mCachedFrames.begin(); + for (const CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); frame++) { const CachedFrame* frameResult = frame->findBestFrameAt(x, y); if (NULL != frameResult) @@ -433,7 +437,7 @@ const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const return result; } -const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, +const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, int* best, const CachedFrame** framePtr, int* x, int* y) const { const CachedNode* result = NULL; @@ -453,21 +457,21 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, if (mRoot->maskIfHidden(&testData) == true) continue; const WebCore::IntRect& bounds = testData.mMouseBounds; - WebCore::IntPoint testCenter = WebCore::IntPoint(bounds.x() + + WebCore::IntPoint testCenter = WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), bounds.y() + (bounds.height() >> 1)); int dx = testCenter.x() - center.x(); int dy = testCenter.y() - center.y(); int distance = dx * dx + dy * dy; - if (*best <= distance) + if (*best <= distance) continue; *best = distance; result = test; *framePtr = this; - const WebCore::IntRect& focusRect = test->focusRings().at(0); - *x = focusRect.x() + (focusRect.width() >> 1); - *y = focusRect.y() + (focusRect.height() >> 1); + const WebCore::IntRect& cursorRect = test->cursorRings().at(0); + *x = cursorRect.x() + (cursorRect.width() >> 1); + *y = cursorRect.y() + (cursorRect.height() >> 1); } - for (const CachedFrame* frame = mCachedFrames.begin(); + for (const CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); frame++) { const CachedNode* frameResult = frame->findBestHitAt(rect, best, framePtr, x, y); @@ -478,7 +482,7 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, } void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, - Direction direction, WebCore::IntRect* clip) const + Direction direction, WebCore::IntRect* clip) const { const CachedNode* test = mCachedNodes.begin(); while ((test = test->traverseNextNode()) != NULL) { @@ -491,13 +495,13 @@ void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, } if (test->noSecondChance()) continue; - if (test->isFocusable(*clip) == false) + if (test->isNavable(*clip) == false) continue; if (checkVisited(test, originalDirection) == false) continue; size_t partMax = test->navableRects(); for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->focusRings().at(part); + WebCore::IntRect testBounds = test->cursorRings().at(part); if (clip->intersects(testBounds) == false) continue; if (clip->contains(testBounds) == false) { @@ -516,7 +520,7 @@ void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, continue; } int distance; - // seems like distance for UP for instance needs to be 'test top closest to + // seems like distance for UP for instance needs to be 'test top closest to // clip bottom' -- keep the old code but try this instead switch (direction) { #if 0 @@ -530,74 +534,72 @@ void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, case UP: distance = clip->bottom() - testBounds.y(); break; case DOWN: distance = testBounds.bottom() - clip->y(); break; #endif - default: + default: distance = 0; ASSERT(0); } if (distance < bestData->mDistance) { bestData->mNode = test; bestData->mFrame = this; bestData->mDistance = distance; - bestData->mMouseBounds = bestData->mNodeBounds = - test->focusRings().at(part); + bestData->mMouseBounds = bestData->mNodeBounds = + test->cursorRings().at(part); CachedHistory* cachedHistory = history(); switch (direction) { - case LEFT: - bestData->setLeftDirection(cachedHistory); + case LEFT: + bestData->setLeftDirection(cachedHistory); break; - case RIGHT: - bestData->setRightDirection(cachedHistory); + case RIGHT: + bestData->setRightDirection(cachedHistory); break; - case UP: - bestData->setUpDirection(cachedHistory); + case UP: + bestData->setUpDirection(cachedHistory); break; - case DOWN: - bestData->setDownDirection(cachedHistory); + case DOWN: + bestData->setDownDirection(cachedHistory); break; - default: - ASSERT(0); + default: + ASSERT(0); } } } } } -bool CachedFrame::finishInit() +void CachedFrame::finishInit() { CachedNode* lastCached = lastNode(); lastCached->setLast(); CachedFrame* child = mCachedFrames.begin(); while (child != mCachedFrames.end()) { child->mParent = this; - if (child->finishInit()) - setFocusIndex(child->indexInParent()); + child->finishInit(); child++; } - return focusIndex() > 0; } -const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const +const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNode* limit, BestData* bestData, + const CachedNode* cursor) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameDown, test, bestData, focus)) + if (moveInFrame(&CachedFrame::frameDown, test, bestData, cursor)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) continue; if (checkVisited(test, DOWN) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); + testData.mNodeBounds = test->cursorRings().at(part); if (testData.setDownDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, focus); + int result = framePartCommon(testData, test, bestData, cursor); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameDown(document(), test, &innerData, focus); + frameDown(document(), test, &innerData, cursor); if (checkVisited(innerData.mNode, DOWN)) { *bestData = innerData; continue; @@ -607,37 +609,37 @@ const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNod *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); - ASSERT(focus == NULL || bestData->mNode != focus); - // does the best contain something (or, is it contained by an area which is not the focus?) + ASSERT(cursor == NULL || bestData->mNode != cursor); + // does the best contain something (or, is it contained by an area which is not the cursor?) // if so, is the conainer/containee should have been chosen, but wasn't -- so there's a better choice // in the doc list prior to this choice - // + // return bestData->mNode; } -const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const +const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNode* limit, BestData* bestData, + const CachedNode* cursor) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameLeft, test, bestData, focus)) + if (moveInFrame(&CachedFrame::frameLeft, test, bestData, cursor)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) continue; if (checkVisited(test, LEFT) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); + testData.mNodeBounds = test->cursorRings().at(part); if (testData.setLeftDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, focus); + int result = framePartCommon(testData, test, bestData, cursor); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameLeft(document(), test, &innerData, focus); + frameLeft(document(), test, &innerData, cursor); if (checkVisited(innerData.mNode, LEFT)) { *bestData = innerData; continue; @@ -647,12 +649,12 @@ const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNod *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(focus == NULL || bestData->mNode != focus); + ASSERT(cursor == NULL || bestData->mNode != cursor); return bestData->mNode; } int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, BestData* bestData, BestData* originalData, - const CachedNode* focus) const + const CachedNode* cursor) const { testData.mFrame = this; testData.mNode = test; @@ -662,34 +664,34 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes return REJECT_TEST; } if (mRoot->scrolledBounds().intersects(test->bounds()) == false) { - testData.mNode->setCondition(CachedNode::FOCUSABLE); + testData.mNode->setCondition(CachedNode::NAVABLE); return REJECT_TEST; } -// if (isFocusable(test, &testData.mNodeBounds, walk) == false) { -// testData.mNode->setCondition(CachedNode::FOCUSABLE); +// if (isNavable(test, &testData.mNodeBounds, walk) == false) { +// testData.mNode->setCondition(CachedNode::NAVABLE); // return REJECT_TEST; // } // - if (test == focus) { - testData.mNode->setCondition(CachedNode::NOT_FOCUS_NODE); + if (test == cursor) { + testData.mNode->setCondition(CachedNode::NOT_CURSOR_NODE); return REJECT_TEST; } -// if (test->bounds().contains(mRoot->focusBounds())) { -// testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); +// if (test->bounds().contains(mRoot->cursorBounds())) { +// testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); // return REJECT_TEST; // } - void* par = focus ? focus->parentGroup() : NULL; - testData.mFocusChild = test->parentGroup() == par; + void* par = cursor ? cursor->parentGroup() : NULL; + testData.mCursorChild = test->parentGroup() == par; #if 0 // not debugged - if (focus && focus->hasMouseOver() && test->hasMouseOver() == false && - focus->bounds().contains(test->bounds())) + if (cursor && cursor->hasMouseOver() && test->hasMouseOver() == false && + cursor->bounds().contains(test->bounds())) return REJECT_TEST; #endif - if (bestData->mNode == NULL) + if (bestData->mNode == NULL) return TEST_IS_BEST; #if 0 // not debugged - if (focus && focus->hasMouseOver() && test->hasMouseOver() == false && - focus->bounds().contains(test->bounds())) + if (cursor && cursor->hasMouseOver() && test->hasMouseOver() == false && + cursor->bounds().contains(test->bounds())) return REJECT_TEST; if (test->hasMouseOver() != bestData->mNode->hasMouseOver()) { if (test->hasMouseOver()) { @@ -703,15 +705,15 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes test->setCondition(CachedNode::ANCHOR_IN_ANCHOR); return REJECT_TEST; } - } - } + } + } #endif - if (focus && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { - int focusParentIndex = focus->parentIndex(); - if (focusParentIndex >= 0) { - if (bestData->mNode->parentIndex() == focusParentIndex) + if (cursor && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { + int cursorParentIndex = cursor->parentIndex(); + if (cursorParentIndex >= 0) { + if (bestData->mNode->parentIndex() == cursorParentIndex) return REJECT_TEST; - if (testData.mNode->parentIndex() == focusParentIndex) + if (testData.mNode->parentIndex() == cursorParentIndex) return TEST_IS_BEST; } } @@ -743,15 +745,15 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes } int CachedFrame::framePartCommon(BestData& testData, - const CachedNode* test, BestData* bestData, const CachedNode* focus) const + const CachedNode* test, BestData* bestData, const CachedNode* cursor) const { - if (testData.mNodeBounds.contains(mRoot->focusBounds())) { - testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); + if (testData.mNodeBounds.contains(mRoot->cursorBounds())) { + testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } testData.setDistances(); if (bestData->mNode != NULL) { - int compared = compare(testData, *bestData, focus); + int compared = compare(testData, *bestData, cursor); if (compared == 0 && test->isArea() == false && bestData->mNode->isArea() == false) goto pickTest; if (compared >= 0) @@ -761,29 +763,29 @@ pickTest: return -1; // pick test } -const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const +const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNode* limit, BestData* bestData, + const CachedNode* cursor) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameRight, test, bestData, focus)) + if (moveInFrame(&CachedFrame::frameRight, test, bestData, cursor)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) continue; if (checkVisited(test, RIGHT) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); + testData.mNodeBounds = test->cursorRings().at(part); if (testData.setRightDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, focus); + int result = framePartCommon(testData, test, bestData, cursor); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameRight(document(), test, &innerData, focus); + frameRight(document(), test, &innerData, cursor); if (checkVisited(innerData.mNode, RIGHT)) { *bestData = innerData; continue; @@ -793,33 +795,33 @@ const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNo *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); - ASSERT(focus == NULL || bestData->mNode != focus); + ASSERT(cursor == NULL || bestData->mNode != cursor); return bestData->mNode; } -const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* focus) const +const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* limit, BestData* bestData, + const CachedNode* cursor) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameUp, test, bestData, focus)) + if (moveInFrame(&CachedFrame::frameUp, test, bestData, cursor)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, focus) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) continue; if (checkVisited(test, UP) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->focusRings().at(part); + testData.mNodeBounds = test->cursorRings().at(part); if (testData.setUpDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, focus); + int result = framePartCommon(testData, test, bestData, cursor); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameUp(document(), test, &innerData, focus); + frameUp(document(), test, &innerData, cursor); if (checkVisited(innerData.mNode, UP)) { *bestData = innerData; continue; @@ -829,56 +831,57 @@ const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(focus == NULL || bestData->mNode != focus); + ASSERT(cursor == NULL || bestData->mNode != cursor); return bestData->mNode; } const CachedFrame* CachedFrame::hasFrame(const CachedNode* node) const -{ - return node->isFrame() ? &mCachedFrames[node->childFrameIndex()] : NULL; +{ + return node->isFrame() ? &mCachedFrames[node->childFrameIndex()] : NULL; } -CachedHistory* CachedFrame::history() const -{ - return mRoot->rootHistory(); +CachedHistory* CachedFrame::history() const +{ + return mRoot->rootHistory(); } -void CachedFrame::init(const CachedRoot* root, int childFrameIndex, +void CachedFrame::init(const CachedRoot* root, int childFrameIndex, WebCore::Frame* frame) { mContents = WebCore::IntRect(0, 0, 0, 0); // fixed up for real in setData() mLocalViewBounds = WebCore::IntRect(0, 0, 0, 0); mViewBounds = WebCore::IntRect(0, 0, 0, 0); mRoot = root; - mFocus = -1; + mCursorIndex = -1; + mFocusIndex = -1; mFrame = frame; mParent = NULL; // set up parents after stretchy arrays are set up - mIndex = childFrameIndex; + mIndexInParent = childFrameIndex; } -int CachedFrame::minWorkingHorizontal() const -{ - return history()->minWorkingHorizontal(); +int CachedFrame::minWorkingHorizontal() const +{ + return history()->minWorkingHorizontal(); } -int CachedFrame::minWorkingVertical() const -{ +int CachedFrame::minWorkingVertical() const +{ return history()->minWorkingVertical(); } - -int CachedFrame::maxWorkingHorizontal() const -{ - return history()->maxWorkingHorizontal(); + +int CachedFrame::maxWorkingHorizontal() const +{ + return history()->maxWorkingHorizontal(); } - -int CachedFrame::maxWorkingVertical() const -{ - return history()->maxWorkingVertical(); + +int CachedFrame::maxWorkingVertical() const +{ + return history()->maxWorkingVertical(); } -bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, +bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, const CachedNode* test, BestData* bestData, - const CachedNode* focus) const + const CachedNode* cursor) const { const CachedFrame* frame = hasFrame(test); if (frame == NULL) @@ -886,25 +889,25 @@ bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, const CachedNode* childDoc = frame->validDocument(); if (childDoc == NULL) return true; - (frame->*moveInDirection)(childDoc, NULL, bestData, focus); + (frame->*moveInDirection)(childDoc, NULL, bestData, cursor); return true; } const WebCore::IntRect& CachedFrame::_navBounds() const -{ - return history()->navBounds(); +{ + return history()->navBounds(); } void CachedFrame::resetClippedOut() { - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) + for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { if (test->clippedOut()) { test->setDisabled(false); test->setClippedOut(false); } } - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); + for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); frame++) { frame->resetClippedOut(); } @@ -913,14 +916,14 @@ void CachedFrame::resetClippedOut() bool CachedFrame::sameFrame(const CachedFrame* test) const { ASSERT(test); - if (mIndex != test->mIndex) + if (mIndexInParent != test->mIndexInParent) return false; - if (mIndex == -1) // index within parent's array of children, or -1 if root + if (mIndexInParent == -1) // index within parent's array of children, or -1 if root return true; return mParent->sameFrame(test->mParent); } -void CachedFrame::setData() +void CachedFrame::setData() { if (this != mRoot) { mViewBounds = mLocalViewBounds; @@ -942,17 +945,17 @@ void CachedFrame::setData() } } -bool CachedFrame::setFocus(WebCore::Frame* frame, WebCore::Node* node, +bool CachedFrame::setCursor(WebCore::Frame* frame, WebCore::Node* node, int x, int y) { if (NULL == node) { - const_cast<CachedRoot*>(mRoot)->setCachedFocus(NULL, NULL); + const_cast<CachedRoot*>(mRoot)->setCursor(NULL, NULL); return true; } if (mFrame != frame) { - for (CachedFrame* testF = mCachedFrames.begin(); testF != mCachedFrames.end(); + for (CachedFrame* testF = mCachedFrames.begin(); testF != mCachedFrames.end(); testF++) { - if (testF->setFocus(frame, node, x, y)) + if (testF->setCursor(frame, node, x, y)) return true; } DBG_NAV_LOGD("no frame frame=%p node=%p", frame, node); @@ -965,17 +968,17 @@ bool CachedFrame::setFocus(WebCore::Frame* frame, WebCore::Node* node, if (test->nodePointer() != node && first) continue; size_t partMax = test->navableRects(); - WTF::Vector<WebCore::IntRect>& focusRings = test->focusRings(); + WTF::Vector<WebCore::IntRect>& cursorRings = test->cursorRings(); for (size_t part = 0; part < partMax; part++) { - const WebCore::IntRect& testBounds = focusRings.at(part); + const WebCore::IntRect& testBounds = cursorRings.at(part); if (testBounds.contains(x, y) == false) continue; - if (test->isFocus()) { - DBG_NAV_LOGD("already set? test=%d frame=%p node=%p x=%d y=%d", + if (test->isCursor()) { + DBG_NAV_LOGD("already set? test=%d frame=%p node=%p x=%d y=%d", test->index(), frame, node, x, y); return false; } - const_cast<CachedRoot*>(mRoot)->setCachedFocus(this, test); + const_cast<CachedRoot*>(mRoot)->setCursor(this, test); return true; } } @@ -1034,11 +1037,11 @@ int CachedFrame::BestData::isContainer(CachedFrame::BestData* other) // mMouseOver = other->mNode; return other->mNode->isArea() ? -1 : 1; } - return 0; + return 0; } // distance scale factor factor as a 16.16 scalar -SkFixed CachedFrame::BestData::Overlap(int span, int left, int right) +SkFixed CachedFrame::BestData::Overlap(int span, int left, int right) { unsigned result; if (left > 0 && left < span && right > span) @@ -1077,11 +1080,11 @@ void CachedFrame::BestData::setDistances() bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) { - const WebCore::IntRect& navBounds = history->navBounds(); + const WebCore::IntRect& navBounds = history->navBounds(); mMajorButt = mNodeBounds.y() - navBounds.bottom(); int testX = mNodeBounds.x(); int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, + setNavOverlap(navBounds.width(), navBounds.right() - testX, testRight - navBounds.x()); if (canBeReachedByAnotherDirection()) { mNode->setCondition(CachedNode::BEST_DIRECTION); @@ -1089,7 +1092,7 @@ bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) } int inNavTop = mNodeBounds.y() - navBounds.y(); mMajorDelta2 = inNavTop; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.height() - + mMajorDelta = mMajorDelta2 + ((mNodeBounds.height() - navBounds.height()) >> 1); if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { mNode->setCondition(CachedNode::CENTER_FURTHER); // never move up or sideways @@ -1099,7 +1102,7 @@ bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) setNavInclusion(testRight - navBounds.right(), navBounds.x() - testX); bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); + mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } int maxV = history->maxWorkingVertical(); @@ -1110,18 +1113,18 @@ bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); return REJECT_TEST; } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; + mInNav = history->directionChange() && inNavTop >= 0 && + inNavBottom > 0 && subsumes; return false; } bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) { - const WebCore::IntRect& navBounds = history->navBounds(); + const WebCore::IntRect& navBounds = history->navBounds(); mMajorButt = navBounds.x() - mNodeBounds.right(); int testY = mNodeBounds.y(); int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, + setNavOverlap(navBounds.height(), navBounds.bottom() - testY, testBottom - navBounds.y()); if (canBeReachedByAnotherDirection()) { mNode->setCondition(CachedNode::BEST_DIRECTION); @@ -1129,7 +1132,7 @@ bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) } int inNavRight = navBounds.right() - mNodeBounds.right(); mMajorDelta2 = inNavRight; - mMajorDelta = mMajorDelta2 - ((navBounds.width() - + mMajorDelta = mMajorDelta2 - ((navBounds.width() - mNodeBounds.width()) >> 1); if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { mNode->setCondition(CachedNode::CENTER_FURTHER); // never move right or sideways @@ -1139,7 +1142,7 @@ bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) setNavInclusion(navBounds.y() - testY, testBottom - navBounds.bottom()); bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); + mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } int maxH = history->maxWorkingHorizontal(); @@ -1150,18 +1153,18 @@ bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); return REJECT_TEST; } - mInNav = history->directionChange() && inNavLeft >= 0 && + mInNav = history->directionChange() && inNavLeft >= 0 && inNavRight > 0 && subsumes; /* both L/R in or out */ return false; } bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) { - const WebCore::IntRect& navBounds = history->navBounds(); + const WebCore::IntRect& navBounds = history->navBounds(); mMajorButt = mNodeBounds.x() - navBounds.right(); int testY = mNodeBounds.y(); int testBottom = mNodeBounds.bottom(); - setNavOverlap(navBounds.height(), navBounds.bottom() - testY, + setNavOverlap(navBounds.height(), navBounds.bottom() - testY, testBottom - navBounds.y()); if (canBeReachedByAnotherDirection()) { mNode->setCondition(CachedNode::BEST_DIRECTION); @@ -1169,7 +1172,7 @@ bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) } int inNavLeft = mNodeBounds.x() - navBounds.x(); mMajorDelta2 = inNavLeft; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.width() - + mMajorDelta = mMajorDelta2 + ((mNodeBounds.width() - navBounds.width()) >> 1); if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { mNode->setCondition(CachedNode::CENTER_FURTHER); // never move left or sideways @@ -1179,7 +1182,7 @@ bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) setNavInclusion(testBottom - navBounds.bottom(), navBounds.y() - testY); bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); + mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } int maxH = history->maxWorkingHorizontal(); @@ -1190,18 +1193,18 @@ bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); return REJECT_TEST; } - mInNav = history->directionChange() && inNavLeft >= 0 && + mInNav = history->directionChange() && inNavLeft >= 0 && inNavRight > 0 && subsumes; /* both L/R in or out */ return false; } bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) { - const WebCore::IntRect& navBounds = history->navBounds(); + const WebCore::IntRect& navBounds = history->navBounds(); mMajorButt = navBounds.y() - mNodeBounds.bottom(); int testX = mNodeBounds.x(); int testRight = mNodeBounds.right(); - setNavOverlap(navBounds.width(), navBounds.right() - testX, + setNavOverlap(navBounds.width(), navBounds.right() - testX, testRight - navBounds.x()); if (canBeReachedByAnotherDirection()) { mNode->setCondition(CachedNode::BEST_DIRECTION); @@ -1209,7 +1212,7 @@ bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) } int inNavBottom = navBounds.bottom() - mNodeBounds.bottom(); mMajorDelta2 = inNavBottom; - mMajorDelta = mMajorDelta2 - ((navBounds.height() - + mMajorDelta = mMajorDelta2 - ((navBounds.height() - mNodeBounds.height()) >> 1); if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { mNode->setCondition(CachedNode::CENTER_FURTHER); // never move down or sideways @@ -1219,7 +1222,7 @@ bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) setNavInclusion(navBounds.x() - testX, testRight - navBounds.right()); bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_FOCUS); + mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } int maxV = history->maxWorkingVertical(); @@ -1230,36 +1233,38 @@ bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); return REJECT_TEST; } - mInNav = history->directionChange() && inNavTop >= 0 && + mInNav = history->directionChange() && inNavTop >= 0 && inNavBottom > 0 && subsumes; /* both L/R in or out */ return false; } void CachedFrame::BestData::setNavInclusion(int left, int right) { - // if left and right <= 0, test node is completely in umbra of focus + // if left and right <= 0, test node is completely in umbra of cursor // prefer leftmost center - // if left and right > 0, test node subsumes focus + // if left and right > 0, test node subsumes cursor mNavDelta = left; mNavDelta2 = right; } void CachedFrame::BestData::setNavOverlap(int span, int left, int right) { - mNavOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; // if left or right < 0, test node is not in umbra of focus + // if left or right < 0, test node is not in umbra of cursor + mNavOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; mNavOverlap = Overlap(span, left, right); // prefer smallest negative left } -void CachedFrame::BestData::setWorkingInclusion(int left, int right) +void CachedFrame::BestData::setWorkingInclusion(int left, int right) { mWorkingDelta = left; mWorkingDelta2 = right; } // distance scale factor factor as a 16.16 scalar -void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) +void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) { - mWorkingOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; // if left or right < 0, test node is not in umbra of focus + // if left or right < 0, test node is not in umbra of cursor + mWorkingOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; mWorkingOverlap = Overlap(span, left, right); mPreferred = left <= 0 ? 0 : left; } @@ -1273,7 +1278,7 @@ void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) CachedFrame* CachedFrame::Debug::base() const { CachedFrame* nav = (CachedFrame*) ((char*) this - OFFSETOF(CachedFrame, mDebug)); - return nav; + return nav; } void CachedFrame::Debug::print() const @@ -1283,12 +1288,12 @@ void CachedFrame::Debug::print() const DEBUG_PRINT_RECT("", BOUNDS, mLocalViewBounds); DEBUG_PRINT_RECT("//", VIEW, mViewBounds); DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size()); - for (CachedNode* node = b->mCachedNodes.begin(); + for (CachedNode* node = b->mCachedNodes.begin(); node != b->mCachedNodes.end(); node++) node->mDebug.print(); DUMP_NAV_LOGD("// }; // end of nodes\n"); DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size()); - for (CachedFrame* child = b->mCachedFrames.begin(); + for (CachedFrame* child = b->mCachedFrames.begin(); child != b->mCachedFrames.end(); child++) { child->mDebug.print(); @@ -1296,9 +1301,10 @@ void CachedFrame::Debug::print() const DUMP_NAV_LOGD("// }; // end of child frames\n"); DUMP_NAV_LOGD("// void* mFrame=(void*) %p;\n", b->mFrame); DUMP_NAV_LOGD("// CachedFrame* mParent=%p;\n", b->mParent); - DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); + DUMP_NAV_LOGD("// int mIndexInParent=%d;\n", b->mIndexInParent); DUMP_NAV_LOGD("// const CachedRoot* mRoot=%p;\n", b->mRoot); - DUMP_NAV_LOGD("// int mFocus=%d;\n", b->mFocus); + DUMP_NAV_LOGD("// int mCursorIndex=%d;\n", b->mCursorIndex); + DUMP_NAV_LOGD("// int mFocusIndex=%d;\n", b->mFocusIndex); } bool CachedFrame::Debug::validate(const CachedNode* node) const @@ -1308,7 +1314,7 @@ bool CachedFrame::Debug::validate(const CachedNode* node) const return false; if (node >= b->mCachedNodes.begin() && node < b->mCachedNodes.end()) return true; - for (const CachedFrame* child = b->mCachedFrames.begin(); + for (const CachedFrame* child = b->mCachedFrames.begin(); child != b->mCachedFrames.end(); child++) if (child->mDebug.validate(node)) return true; diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h index dc20e15..30d9f88 100644 --- a/WebKit/android/nav/CachedFrame.h +++ b/WebKit/android/nav/CachedFrame.h @@ -65,7 +65,9 @@ public: void addFrame(CachedFrame& child) { mCachedFrames.append(child); } bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; size_t childCount() { return mCachedFrames.size(); } - void clearFocus(); + void clearCursor(); + const CachedNode* currentCursor() const { return currentCursor(NULL); } + const CachedNode* currentCursor(const CachedFrame** ) const; const CachedNode* currentFocus() const { return currentFocus(NULL); } const CachedNode* currentFocus(const CachedFrame** ) const; bool directionChange() const; @@ -76,15 +78,14 @@ public: const CachedFrame* findBestFrameAt(int x, int y) const; const CachedNode* findBestHitAt(const WebCore::IntRect& , int* best, const CachedFrame** , int* x, int* y) const; - bool finishInit(); + void finishInit(); CachedFrame* firstChild() { return mCachedFrames.begin(); } const CachedFrame* firstChild() const { return mCachedFrames.begin(); } - int focusIndex() const { return mFocus; } void* framePointer() const { return mFrame; } CachedNode* getIndex(int index) { return index >= 0 ? &mCachedNodes[index] : NULL; } const CachedFrame* hasFrame(const CachedNode* node) const; - int indexInParent() const { return mIndex; } + int indexInParent() const { return mIndexInParent; } void init(const CachedRoot* root, int index, WebCore::Frame* frame); const CachedFrame* lastChild() const { return &mCachedFrames.last(); } CachedNode* lastNode() { return &mCachedNodes.last(); } @@ -96,9 +97,11 @@ public: void resetClippedOut(); void setContentsSize(int width, int height) { mContents.setWidth(width); mContents.setHeight(height); } + bool setCursor(WebCore::Frame* , WebCore::Node* , int x, int y); + void setCursorIndex(int index) { mCursorIndex = index; } void setData(); bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y); - void setFocusIndex(int focusIndex) const { mFocus = focusIndex; } + void setFocusIndex(int index) { mFocusIndex = index; } void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; } int size() { return mCachedNodes.size(); } const CachedNode* validDocument() const; @@ -121,7 +124,7 @@ protected: SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools SkFixed mNavOverlap; SkFixed mPreferred; - bool mFocusChild; + bool mCursorChild; bool mInNav; bool mNavOutside; bool mWorkingOutside; @@ -186,9 +189,10 @@ protected: WTF::Vector<CachedFrame> mCachedFrames; void* mFrame; // WebCore::Frame*, used only to compare pointers CachedFrame* mParent; - int mIndex; // index within parent's array of children, or -1 if root + int mCursorIndex; + int mFocusIndex; + int mIndexInParent; // index within parent's array of children, or -1 if root const CachedRoot* mRoot; - mutable int mFocus; private: CachedHistory* history() const; #ifdef BROWSER_DEBUG diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp index 07d3491..4408cb6 100644 --- a/WebKit/android/nav/CachedNode.cpp +++ b/WebKit/android/nav/CachedNode.cpp @@ -34,13 +34,13 @@ namespace android { -void CachedNode::clearFocus(CachedFrame* parent) +void CachedNode::clearCursor(CachedFrame* parent) { if (isFrame()) { CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->clearFocus(); + child->clearCursor(); } - mIsFocus = false; + mIsCursor = false; } bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, @@ -73,19 +73,19 @@ bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, bool CachedNode::clip(const WebCore::IntRect& bounds) { - return Clip(bounds, &mBounds, &mFocusRing); + return Clip(bounds, &mBounds, &mCursorRing); } #define OVERLAP 3 -void CachedNode::fixUpFocusRects(const CachedRoot* root) +void CachedNode::fixUpCursorRects(const CachedRoot* root) { - if (mFixedUpFocusRects) + if (mFixedUpCursorRects) return; - mFixedUpFocusRects = true; + mFixedUpCursorRects = true; // if the hit-test rect doesn't intersect any other rect, use it if (mHitBounds != mBounds && mHitBounds.contains(mBounds) && - root->checkRings(mFocusRing, mHitBounds)) { + root->checkRings(mCursorRing, mHitBounds)) { DBG_NAV_LOGD("use mHitBounds (%d,%d,%d,%d)", mHitBounds.x(), mHitBounds.y(), mHitBounds.width(), mHitBounds.height()); mUseHitBounds = true; @@ -94,8 +94,8 @@ void CachedNode::fixUpFocusRects(const CachedRoot* root) if (mNavableRects <= 1) return; // if there is more than 1 rect, and the bounds doesn't intersect - // any other focus ring bounds, use it - if (root->checkRings(mFocusRing, mBounds)) { + // any other cursor ring bounds, use it + if (root->checkRings(mCursorRing, mBounds)) { DBG_NAV_LOGD("use mBounds (%d,%d,%d,%d)", mBounds.x(), mBounds.y(), mBounds.width(), mBounds.height()); mUseBounds = true; @@ -103,10 +103,10 @@ void CachedNode::fixUpFocusRects(const CachedRoot* root) } #if DEBUG_NAV_UI { - WebCore::IntRect* boundsPtr = mFocusRing.begin() - 1; - const WebCore::IntRect* const boundsEnd = mFocusRing.begin() + mFocusRing.size(); + WebCore::IntRect* boundsPtr = mCursorRing.begin() - 1; + const WebCore::IntRect* const boundsEnd = mCursorRing.begin() + mCursorRing.size(); while (++boundsPtr < boundsEnd) - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mFocusRing.begin(), + LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mCursorRing.begin(), boundsPtr->x(), boundsPtr->y(), boundsPtr->width(), boundsPtr->height()); } #endif @@ -114,16 +114,16 @@ void CachedNode::fixUpFocusRects(const CachedRoot* root) bool again; do { again = false; - size_t size = mFocusRing.size(); - WebCore::IntRect* unitBoundsPtr = mFocusRing.begin() - 1; - const WebCore::IntRect* const unitBoundsEnd = mFocusRing.begin() + size; + size_t size = mCursorRing.size(); + WebCore::IntRect* unitBoundsPtr = mCursorRing.begin() - 1; + const WebCore::IntRect* const unitBoundsEnd = mCursorRing.begin() + size; while (++unitBoundsPtr < unitBoundsEnd) { // any other unitBounds to the left or right of this one? int unitTop = unitBoundsPtr->y(); int unitBottom = unitBoundsPtr->bottom(); int unitLeft = unitBoundsPtr->x(); int unitRight = unitBoundsPtr->right(); - WebCore::IntRect* testBoundsPtr = mFocusRing.begin() - 1; + WebCore::IntRect* testBoundsPtr = mCursorRing.begin() - 1; while (++testBoundsPtr < unitBoundsEnd) { if (unitBoundsPtr == testBoundsPtr) continue; @@ -151,7 +151,7 @@ void CachedNode::fixUpFocusRects(const CachedRoot* root) WebCore::IntRect candidate = WebCore::IntRect(candidateLeft, candidateTop, candidateRight - candidateLeft, candidateBottom - candidateTop); // does a different unit bounds intersect the candidate? if so, don't add - WebCore::IntRect* checkBoundsPtr = mFocusRing.begin() - 1; + WebCore::IntRect* checkBoundsPtr = mCursorRing.begin() - 1; while (++checkBoundsPtr < unitBoundsEnd) { if (checkBoundsPtr->intersects(candidate) == false) continue; @@ -179,10 +179,10 @@ void CachedNode::fixUpFocusRects(const CachedRoot* root) candidateRight - candidateLeft, candidateBottom - candidateTop); ASSERT(candidate.isEmpty() == false); #if DEBUG_NAV_UI - LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mFocusRing.size(), + LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mCursorRing.size(), candidate.x(), candidate.y(), candidate.width(), candidate.height()); #endif - mFocusRing.append(candidate); + mCursorRing.append(candidate); again = true; goto tryAgain; nextCheck: @@ -195,14 +195,14 @@ tryAgain: } -void CachedNode::focusRingBounds(WebCore::IntRect* bounds) const +void CachedNode::cursorRingBounds(WebCore::IntRect* bounds) const { int partMax = mNavableRects; ASSERT(partMax > 0); - *bounds = mFocusRing[0]; + *bounds = mCursorRing[0]; for (int partIndex = 1; partIndex < partMax; partIndex++) - bounds->unite(mFocusRing[partIndex]); - bounds->inflate(FOCUS_RING_HIT_TEST_RADIUS); + bounds->unite(mCursorRing[partIndex]); + bounds->inflate(CURSOR_RING_HIT_TEST_RADIUS); } void CachedNode::init(WebCore::Node* node) @@ -219,8 +219,8 @@ void CachedNode::move(int x, int y) { mBounds.move(x, y); // mHitTestBounds will be moved by caller - WebCore::IntRect* first = mFocusRing.begin(); - WebCore::IntRect* last = first + mFocusRing.size(); + WebCore::IntRect* first = mCursorRing.begin(); + WebCore::IntRect* last = first + mCursorRing.size(); --first; while (++first != last) first->move(x, y); @@ -232,10 +232,10 @@ bool CachedNode::partRectsContains(const CachedNode* other) const int outerMax = mNavableRects; int innerMax = other->mNavableRects; do { - const WebCore::IntRect& outerBounds = mFocusRing[outerIndex]; + const WebCore::IntRect& outerBounds = mCursorRing[outerIndex]; int innerIndex = 0; do { - const WebCore::IntRect& innerBounds = other->mFocusRing[innerIndex]; + const WebCore::IntRect& innerBounds = other->mCursorRing[innerIndex]; if (innerBounds.contains(outerBounds)) return true; } while (++innerIndex < innerMax); @@ -265,10 +265,10 @@ const char* CachedNode::Debug::condition(Condition t) const case BUTTED_UP: return "BUTTED_UP"; break; case CENTER_FURTHER: return "CENTER_FURTHER"; break; case CLOSER: return "CLOSER"; break; - case CLOSER_IN_FOCUS: return "CLOSER_IN_FOCUS"; break; + case CLOSER_IN_CURSOR: return "CLOSER_IN_CURSOR"; break; case CLOSER_OVERLAP: return "CLOSER_OVERLAP"; break; case CLOSER_TOP: return "CLOSER_TOP"; break; - case FOCUSABLE: return "FOCUSABLE"; break; + case NAVABLE: return "NAVABLE"; break; case FURTHER: return "FURTHER"; break; case IN_UMBRA: return "IN_UMBRA"; break; case IN_WORKING: return "IN_WORKING"; break; @@ -280,11 +280,10 @@ const char* CachedNode::Debug::condition(Condition t) const case CHILD: return "CHILD"; break; case DISABLED: return "DISABLED"; break; case HIGHER_TAB_INDEX: return "HIGHER_TAB_INDEX"; break; - case IN_FOCUS: return "IN_FOCUS"; break; - case IN_FOCUS_CHILDREN: return "IN_FOCUS_CHILDREN"; break; - case NOT_ENCLOSING_FOCUS: return "NOT_ENCLOSING_FOCUS"; break; - // case NOT_FOCUS_CHILD: return "NOT_FOCUS_CHILD"; break; - case NOT_FOCUS_NODE: return "NOT_FOCUS_NODE"; break; + case IN_CURSOR: return "IN_CURSOR"; break; + case IN_CURSOR_CHILDREN: return "IN_CURSOR_CHILDREN"; break; + case NOT_ENCLOSING_CURSOR: return "NOT_ENCLOSING_CURSOR"; break; + case NOT_CURSOR_NODE: return "NOT_CURSOR_NODE"; break; case OUTSIDE_OF_BEST: return "OUTSIDE_OF_BEST"; break; case OUTSIDE_OF_ORIGINAL: return "OUTSIDE_OF_ORIGINAL"; break; default: return "???"; @@ -318,9 +317,9 @@ void CachedNode::Debug::print() const DUMP_NAV_LOGD("%.*s\"\n", index, scratch); DEBUG_PRINT_RECT(mBounds); DEBUG_PRINT_RECT(mHitBounds); - const WTF::Vector<WebCore::IntRect>& rects = b->focusRings(); + const WTF::Vector<WebCore::IntRect>& rects = b->cursorRings(); size_t size = rects.size(); - DUMP_NAV_LOGD("// IntRect focusRings={ // size=%d\n", size); + DUMP_NAV_LOGD("// IntRect cursorRings={ // size=%d\n", size); for (size_t i = 0; i < size; i++) DUMP_NAV_LOGD(" // {%d, %d, %d, %d}, // %d\n", rects[i].x(), rects[i].y(), rects[i].width(), rects[i].height(), i); @@ -338,12 +337,12 @@ void CachedNode::Debug::print() const DUMP_NAV_LOGD("// Type mType=%s;\n", type(b->mType)); DEBUG_PRINT_BOOL(mClippedOut); DEBUG_PRINT_BOOL(mDisabled); - DEBUG_PRINT_BOOL(mFixedUpFocusRects); - DEBUG_PRINT_BOOL(mHasFocusRing); + DEBUG_PRINT_BOOL(mFixedUpCursorRects); + DEBUG_PRINT_BOOL(mHasCursorRing); DEBUG_PRINT_BOOL(mHasMouseOver); DEBUG_PRINT_BOOL(mIsAnchor); DEBUG_PRINT_BOOL(mIsArea); - DEBUG_PRINT_BOOL(mIsFocus); + DEBUG_PRINT_BOOL(mIsCursor); DEBUG_PRINT_BOOL(mIsInput); DEBUG_PRINT_BOOL(mIsParentAnchor); DEBUG_PRINT_BOOL(mIsPassword); diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h index bdde9e0..88757d0 100644 --- a/WebKit/android/nav/CachedNode.h +++ b/WebKit/android/nav/CachedNode.h @@ -54,10 +54,10 @@ public: BUTTED_UP, CENTER_FURTHER, CLOSER, - CLOSER_IN_FOCUS, + CLOSER_IN_CURSOR, CLOSER_OVERLAP, CLOSER_TOP, - FOCUSABLE, + NAVABLE, FURTHER, IN_UMBRA, IN_WORKING, @@ -71,11 +71,10 @@ public: CHILD, DISABLED, HIGHER_TAB_INDEX, - IN_FOCUS, - IN_FOCUS_CHILDREN, - NOT_ENCLOSING_FOCUS, - // NOT_FOCUS_CHILD, - NOT_FOCUS_NODE, + IN_CURSOR, + IN_CURSOR_CHILDREN, + NOT_ENCLOSING_CURSOR, + NOT_CURSOR_NODE, OUTSIDE_OF_BEST, // containership OUTSIDE_OF_ORIGINAL, // containership CONDITION_SIZE // FIXME: test that CONDITION_SIZE fits in mCondition @@ -89,33 +88,34 @@ public: WebCore::IntRect* boundsPtr() { return &mBounds; } int childFrameIndex() const { return mChildFrameIndex; } void clearCondition() const { mCondition = NOT_REJECTED; } - void clearFocus(CachedFrame* ); + void clearCursor(CachedFrame* ); static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, WTF::Vector<WebCore::IntRect>* rings); bool clip(const WebCore::IntRect& ); bool clippedOut() { return mClippedOut; } + void cursorRingBounds(WebCore::IntRect* ) const; bool disabled() const { return mDisabled; } const CachedNode* document() const { return &this[-mIndex]; } - void fixUpFocusRects(const CachedRoot* root); - void focusRingBounds(WebCore::IntRect* ) const; - WTF::Vector<WebCore::IntRect>& focusRings() { return mFocusRing; } - const WTF::Vector<WebCore::IntRect>& focusRings() const { return mFocusRing; } + void fixUpCursorRects(const CachedRoot* root); + WTF::Vector<WebCore::IntRect>& cursorRings() { return mCursorRing; } + const WTF::Vector<WebCore::IntRect>& cursorRings() const { return mCursorRing; } const WebCore::IntRect& getBounds() const { return mBounds; } void getBounds(WebCore::IntRect* bounds) const { *bounds = mBounds; } const WebCore::String& getExport() const { return mExport; } - bool hasFocusRing() const { return mHasFocusRing; } + bool hasCursorRing() const { return mHasCursorRing; } bool hasMouseOver() const { return mHasMouseOver; } const WebCore::IntRect& hitBounds() const { return mHitBounds; } int index() const { return mIndex; } void init(WebCore::Node* node); bool isAnchor() const { return mIsAnchor; } + bool isCursor() const { return mIsCursor; } bool isArea() const { return mIsArea; } bool isFocus() const { return mIsFocus; } - bool isFocusable(const WebCore::IntRect& clip) const { - return clip.intersects(mBounds); - } bool isFrame() const { return mChildFrameIndex >= 0 ; } bool isInput() const { return mIsInput; } + bool isNavable(const WebCore::IntRect& clip) const { + return clip.intersects(mBounds); + } bool isPassword() const { return mIsPassword; } bool isRtlText() const { return mIsRtlText; } bool isTextArea() const { return mIsTextArea; } @@ -141,12 +141,13 @@ public: void setCondition(Condition condition) const { mCondition = condition; } void setDisabled(bool disabled) { mDisabled = disabled; } void setExport(const WebCore::String& exported) { mExport = exported; } - void setHasFocusRing(bool hasFocusRing) { mHasFocusRing = hasFocusRing; } + void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; } void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; } void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; } void setIndex(int index) { mIndex = index; } void setIsAnchor(bool isAnchor) { mIsAnchor = isAnchor; } void setIsArea(bool isArea) { mIsArea = isArea; } + void setIsCursor(bool isCursor) { mIsCursor = isCursor; } void setIsFocus(bool isFocus) { mIsFocus = isFocus; } void setIsInput(bool isInput) { mIsInput = isInput; } void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; } @@ -159,7 +160,7 @@ public: void setLast() { mLast = true; } void setMaxLength(int maxLength) { mMaxLength = maxLength; } void setName(const WebCore::String& name) { mName = name; } - void setNavableRects() { mNavableRects = mFocusRing.size(); } + void setNavableRects() { mNavableRects = mCursorRing.size(); } void setParentGroup(void* group) { mParentGroup = group; } void setParentIndex(int parent) { mParentIndex = parent; } void setTabIndex(int index) { mTabIndex = index; } @@ -177,7 +178,7 @@ private: WebCore::String mName; WebCore::IntRect mBounds; WebCore::IntRect mHitBounds; - WTF::Vector<WebCore::IntRect> mFocusRing; + WTF::Vector<WebCore::IntRect> mCursorRing; void* mNode; // WebCore::Node*, only used to match pointers void* mParentGroup; // WebCore::Node*, only used to match pointers int mChildFrameIndex; // set to -1 if node is not a frame @@ -191,11 +192,12 @@ private: CachedNodeType mType : 3; bool mClippedOut : 1; bool mDisabled : 1; - bool mFixedUpFocusRects : 1; - bool mHasFocusRing : 1; + bool mFixedUpCursorRects : 1; + bool mHasCursorRing : 1; bool mHasMouseOver : 1; bool mIsAnchor : 1; bool mIsArea : 1; + bool mIsCursor : 1; bool mIsFocus : 1; bool mIsInput : 1; bool mIsParentAnchor : 1; diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index cf8578f..98750b8 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -58,18 +58,18 @@ public: kDrawText_Type, kDrawTextOnPath_Type }; - + static bool isTextType(Type t) { return t == kDrawPosTextH_Type || t == kDrawText_Type; } - + CommonCheck() : mType(kNo_Type), mAllOpaque(true), mIsOpaque(true) { setEmpty(); } - bool doRect(Type type) { + bool doRect(Type type) { mType = type; - return doIRect(mUnion); + return doIRect(mUnion); } bool joinGlyphs(const SkIRect& rect) { @@ -78,7 +78,7 @@ public: mUnion.join(rect); return isGlyph; } - + void setAllOpaque(bool opaque) { mAllOpaque = opaque; } void setEmpty() { mUnion.setEmpty(); } void setIsOpaque(bool opaque) { mIsOpaque = opaque; } @@ -113,16 +113,16 @@ public: class BoundsCheck : public CommonCheck { public: - BoundsCheck() { + BoundsCheck() { mAllDrawnIn.setEmpty(); mLastAll.setEmpty(); mLastOver.setEmpty(); } - + static int Area(SkIRect test) { return test.width() * test.height(); } - + void checkLast() { if (mAllDrawnIn.isEmpty()) return; @@ -132,16 +132,16 @@ public: } mAllDrawnIn.setEmpty(); } - + bool hidden() { return (mLastAll.isEmpty() && mLastOver.isEmpty()) || mDrawnOver.contains(mBounds); } - + virtual bool onIRect(const SkIRect& rect) { if (joinGlyphs(rect)) return false; - bool interestingType = mType == kDrawBitmap_Type || + bool interestingType = mType == kDrawBitmap_Type || mType == kDrawRect_Type || isTextType(mType); if (SkIRect::Intersects(mBounds, rect) == false) { #if DEBUG_NAV_UI && !defined BROWSER_DEBUG @@ -155,7 +155,7 @@ public: } if (interestingType == false) return false; - if (mBoundsSlop.contains(rect) || + if (mBoundsSlop.contains(rect) || (mBounds.fLeft == rect.fLeft && mBounds.fRight == rect.fRight && mBounds.fTop >= rect.fTop && mBounds.fBottom <= rect.fBottom) || (mBounds.fTop == rect.fTop && mBounds.fBottom == rect.fBottom && @@ -177,15 +177,15 @@ public: // should the opaqueness of the bitmap disallow its ability to draw over? // not sure that this test is needed (mType != kDrawBitmap_Type || - (mIsOpaque && mAllOpaque)) && -#endif + (mIsOpaque && mAllOpaque)) && +#endif mLastAll.isEmpty() == false) mDrawnOver.op(rect, SkRegion::kUnion_Op); } else { // FIXME -// sometimes the text is not drawn entirely inside the focus area, even though +// sometimes the text is not drawn entirely inside the cursor area, even though // it is the correct text. Until I figure out why, I allow text drawn at the -// end that is not covered up by something else to represent the focusable link +// end that is not covered up by something else to represent the link // example that triggers this that should be figured out: // http://cdn.labpixies.com/campaigns/blackjack/blackjack.html?lang=en&country=US&libs=assets/feature/core // ( http://tinyurl.com/ywsyzb ) @@ -202,7 +202,7 @@ public: } return false; } - + SkIRect mBounds; SkIRect mBoundsSlop; SkRegion mDrawnOver; @@ -258,7 +258,7 @@ public: SkCanvas::drawSprite(bitmap, left, top, paint); } - virtual void drawText(const void* text, size_t byteLength, SkScalar x, + virtual void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { mBounder.setEmpty(); mBounder.setType(CommonCheck::kDrawGlyph_Type); @@ -266,7 +266,7 @@ public: mBounder.doRect(CommonCheck::kDrawText_Type); } - virtual void drawPosText(const void* text, size_t byteLength, + virtual void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { mBounder.setEmpty(); mBounder.setType(CommonCheck::kDrawGlyph_Type); @@ -295,8 +295,8 @@ public: mBounder.doRect(CommonCheck::kDrawPosTextH_Type); } - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, + virtual void drawTextOnPath(const void* text, size_t byteLength, + const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { mBounder.setEmpty(); mBounder.setType(CommonCheck::kDrawGlyph_Type); @@ -308,7 +308,7 @@ public: mBounder.setType(CommonCheck::kDrawPicture_Type); SkCanvas::drawPicture(picture); } - + virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { int depth = SkCanvas::saveLayer(bounds, paint, flags); @@ -327,7 +327,7 @@ public: } SkCanvas::restore(); } - + int mTransparentLayer; CommonCheck& mBounder; }; @@ -338,20 +338,20 @@ and returns via center() the optimal amount to scroll in x to display the paragraph of text. The caller of CenterCheck has configured (but not allocated) a bitmap -the height and three times the width of the view. The picture is drawn centered -in the bitmap, so text that would be revealed, if the view was scrolled up to +the height and three times the width of the view. The picture is drawn centered +in the bitmap, so text that would be revealed, if the view was scrolled up to a view-width to the left or right, is considered. */ class CenterCheck : public CommonCheck { public: - CenterCheck(int x, int y, int width) : mX(x), mY(y), + CenterCheck(int x, int y, int width) : mX(x), mY(y), mHitLeft(x), mHitRight(x), mMostLeft(INT_MAX), mMostRight(-INT_MAX), mViewLeft(width), mViewRight(width << 1) { - mHit.set(x - CENTER_SLOP, y - CENTER_SLOP, + mHit.set(x - CENTER_SLOP, y - CENTER_SLOP, x + CENTER_SLOP, y + CENTER_SLOP); mPartial.setEmpty(); } - + int center() { doRect(); // process the final line of text /* If the touch coordinates aren't near any text, return 0 */ @@ -382,12 +382,12 @@ public: center = 0; // paragraph is already fully visible #endif } - DBG_NAV_LOGD("scroll: leftOver=%d rightOver=%d center=%d", + DBG_NAV_LOGD("scroll: leftOver=%d rightOver=%d center=%d", leftOver, rightOver, center); return center; } - -protected: + +protected: virtual bool onIRect(const SkIRect& rect) { if (joinGlyphs(rect)) // assembles glyphs into a text string return false; @@ -395,9 +395,9 @@ protected: return false; /* Text on one line may be broken into several parts. Reassemble the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom && rect.fBottom > + if (rect.fTop < mPartial.fBottom && rect.fBottom > mPartial.fTop && mPartial.fRight + CENTER_SLOP >= rect.fLeft) { - DBG_NAV_LOGD("join mPartial=(%d, %d, %d, %d) rect=(%d, %d, %d, %d)", + DBG_NAV_LOGD("join mPartial=(%d, %d, %d, %d) rect=(%d, %d, %d, %d)", mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); mPartial.join(rect); @@ -407,11 +407,11 @@ protected: doRect(); // process the previous line of text mPartial = rect; return false; - } - + } + void doRect() { - /* Record the outer bounds of the lines of text that was 'hit' by the + /* Record the outer bounds of the lines of text that was 'hit' by the touch coordinates, given some slop */ if (SkIRect::Intersects(mPartial, mHit)) { if (mHitLeft > mPartial.fLeft) @@ -440,10 +440,10 @@ protected: mMostLeft = leftOver; if (mMostRight < rightOver) mMostRight = rightOver; - DBG_NAV_LOGD("leftOver=%d rightOver=%d mMostLeft=%d mMostRight=%d", + DBG_NAV_LOGD("leftOver=%d rightOver=%d mMostLeft=%d mMostRight=%d", leftOver, rightOver, mMostLeft, mMostRight); } - + static const int CENTER_SLOP = 10; // space between text parts and lines /* const */ SkIRect mHit; // sloppy hit rectangle SkIRect mPartial; // accumulated text bounds, per line @@ -464,7 +464,7 @@ public: } // Currently webkit's bitmap draws always seem to be cull'd before this entry -// point is called, so we assume that any bitmap that gets here is inside our +// point is called, so we assume that any bitmap that gets here is inside our // tiny clip (may not be true in the future) virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkMatrix& , const SkPaint& ) { @@ -491,14 +491,14 @@ public: mMinX = mMinJiggle = abs(delta); mMaxWidth = width + mMinX; } - + int jiggle() { if (mMinJiggle > mMaxJiggle) return mDelta; int avg = (mMinJiggle + mMaxJiggle + 1) >> 1; return mDelta < 0 ? -avg : avg; } - + virtual bool onIRect(const SkIRect& rect) { if (joinGlyphs(rect)) return false; @@ -538,7 +538,7 @@ public: const WebCore::IntRect* r; for (r = rings.begin(); r != rings.end(); r++) { SkIRect fatter = {r->x(), r->y(), r->right(), r->bottom()}; - fatter.inset(-FOCUS_RING_HIT_TEST_RADIUS, -FOCUS_RING_HIT_TEST_RADIUS); + fatter.inset(-CURSOR_RING_HIT_TEST_RADIUS, -CURSOR_RING_HIT_TEST_RADIUS); DBG_NAV_LOGD("fat=(%d,%d,r=%d,b=%d)", fatter.fLeft, fatter.fTop, fatter.fRight, fatter.fBottom); mRings.op(fatter, SkRegion::kUnion_Op); @@ -562,14 +562,14 @@ public: bool mSuccess; }; -bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, +bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, WebCore::IntPoint* scrollPtr, bool findClosest) -{ +{ WebCore::IntRect newOutset; const CachedNode* newNode = best->mNode; // see if there's a middle node - // if the middle node is in the visited list, - // or if none was computed and the newNode is in the visited list, + // if the middle node is in the visited list, + // or if none was computed and the newNode is in the visited list, // treat result as NULL if (newNode != NULL && findClosest) { if (best->bounds().intersects(mHistory->mPriorBounds) == false && @@ -579,13 +579,13 @@ bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction directio innerMove(document(), best, direction, scrollPtr, false); return true; } - newNode->focusRingBounds(&newOutset); + newNode->cursorRingBounds(&newOutset); } int delta; bool newNodeInView = scrollDelta(newOutset, direction, &delta); - if (delta && scrollPtr && (newNode == NULL || newNodeInView == false || + if (delta && scrollPtr && (newNode == NULL || newNodeInView == false || (best->mNavOutside && best->mWorkingOutside))) - *scrollPtr = WebCore::IntPoint(direction & UP_DOWN ? 0 : delta, + *scrollPtr = WebCore::IntPoint(direction & UP_DOWN ? 0 : delta, direction & UP_DOWN ? delta : 0); return false; } @@ -594,14 +594,14 @@ bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction directio int CachedRoot::checkForCenter(int x, int y) const { int width = mViewBounds.width(); - CenterCheck centerCheck(x + width - mViewBounds.x(), y - mViewBounds.y(), + CenterCheck centerCheck(x + width - mViewBounds.x(), y - mViewBounds.y(), width); BoundsCanvas checker(¢erCheck); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, width * 3, mViewBounds.height()); checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(width - mViewBounds.x()), + checker.translate(SkIntToScalar(width - mViewBounds.x()), SkIntToScalar(-mViewBounds.y())); checker.drawPicture(*mPicture); return centerCheck.center(); @@ -617,7 +617,7 @@ void CachedRoot::checkForJiggle(int* xDeltaPtr) const bitmap.setConfig(SkBitmap::kARGB_8888_Config, mViewBounds.width() + absDelta, mViewBounds.height()); checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-mViewBounds.x() - + checker.translate(SkIntToScalar(-mViewBounds.x() - (xDelta < 0 ? xDelta : 0)), SkIntToScalar(-mViewBounds.y())); checker.drawPicture(*mPicture); *xDeltaPtr = jiggleCheck.jiggle(); @@ -650,11 +650,11 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, (const_cast<CachedRoot*>(this))->resetClippedOut(); const CachedNode* directHit = NULL; const CachedNode* node = findBestAt(rect, &best, &inside, &directHit, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), + DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), node == NULL ? NULL : node->nodePointer()); if (node == NULL) { node = findBestHitAt(rect, &best, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), + DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), node == NULL ? NULL : node->nodePointer()); } if (node == NULL) { @@ -664,13 +664,19 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, return node; } -WebCore::IntPoint CachedRoot::focusLocation() const +WebCore::IntPoint CachedRoot::cursorLocation() const { const WebCore::IntRect& bounds = mHistory->mNavBounds; - return WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), + return WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), bounds.y() + (bounds.height() >> 1)); } +WebCore::IntPoint CachedRoot::focusLocation() const +{ + return WebCore::IntPoint(mFocusBounds.x() + (mFocusBounds.width() >> 1), + mFocusBounds.y() + (mFocusBounds.height() >> 1)); +} + // These reset the values because we only want to get the selection the first time. // After that, the selection is no longer accurate. int CachedRoot::getAndResetSelectionEnd() @@ -705,7 +711,7 @@ void CachedRoot::getSimulatedMousePosition(WebCore::IntPoint* point) #endif } -void CachedRoot::init(WebCore::Frame* frame, CachedHistory* history) +void CachedRoot::init(WebCore::Frame* frame, CachedHistory* history) { CachedFrame::init(this, -1, frame); reset(); @@ -722,8 +728,8 @@ bool CachedRoot::innerDown(const CachedNode* test, BestData* bestData) const mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); int testTop = mScrolledBounds.y(); int viewBottom = mViewBounds.bottom(); - if (mFocusBounds.isEmpty() == false && - mFocusBounds.bottom() > viewBottom && viewBottom < mContents.height()) + if (mCursorBounds.isEmpty() == false && + mCursorBounds.bottom() > viewBottom && viewBottom < mContents.height()) return false; if (mHistory->mNavBounds.isEmpty() == false) { int navTop = mHistory->mNavBounds.y(); @@ -733,7 +739,7 @@ bool CachedRoot::innerDown(const CachedNode* test, BestData* bestData) const mScrolledBounds.setY(navTop); } } - frameDown(test, NULL, bestData, currentFocus()); + frameDown(test, NULL, bestData, currentCursor()); return true; } @@ -746,8 +752,8 @@ bool CachedRoot::innerLeft(const CachedNode* test, BestData* bestData) const mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); int testRight = mScrolledBounds.right(); int viewLeft = mViewBounds.x(); - if (mFocusBounds.isEmpty() == false && - mFocusBounds.x() < viewLeft && viewLeft > mContents.x()) + if (mCursorBounds.isEmpty() == false && + mCursorBounds.x() < viewLeft && viewLeft > mContents.x()) return false; if (mHistory->mNavBounds.isEmpty() == false) { int navRight = mHistory->mNavBounds.right(); @@ -755,53 +761,53 @@ bool CachedRoot::innerLeft(const CachedNode* test, BestData* bestData) const if (testRight > navRight && navRight > (scrollLeft = mScrolledBounds.x())) mScrolledBounds.setWidth(navRight - scrollLeft); } - frameLeft(test, NULL, bestData, currentFocus()); + frameLeft(test, NULL, bestData, currentCursor()); return true; } -void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, +void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, Direction direction, WebCore::IntPoint* scroll, bool firstCall) { bestData->reset(); - mFocusChild = false; - bool outOfFocus = mFocus < 0; - bool firstTime = mHistory->didFirstLayout() && outOfFocus; + mCursorChild = false; + bool outOfCursor = mCursorIndex < 0; + bool firstTime = mHistory->didFirstLayout() && outOfCursor; #if DEBUG_NAV_UI && !defined BROWSER_DEBUG - LOGD("%s mHistory->didFirstLayout()=%s && mFocus=%d\n", __FUNCTION__, - mHistory->didFirstLayout() ? "true" : "false", mFocus); + LOGD("%s mHistory->didFirstLayout()=%s && mCursorIndex=%d\n", __FUNCTION__, + mHistory->didFirstLayout() ? "true" : "false", mCursorIndex); #endif if (firstTime) mHistory->reset(); - const CachedNode* focus = currentFocus(); - mHistory->setWorking(direction, focus, mViewBounds); - mFocusBounds = WebCore::IntRect(0, 0, 0, 0); - if (focus != NULL) - focus->getBounds(&mFocusBounds); + const CachedNode* cursor = currentCursor(); + mHistory->setWorking(direction, cursor, mViewBounds); + mCursorBounds = WebCore::IntRect(0, 0, 0, 0); + if (cursor != NULL) + cursor->getBounds(&mCursorBounds); bool findClosest = false; if (mScrollOnly == false) { switch (direction) { case LEFT: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.right(), + if (outOfCursor) + mHistory->mNavBounds = WebCore::IntRect(mViewBounds.right(), mViewBounds.y(), 1, mViewBounds.height()); findClosest = innerLeft(node, bestData); break; - case RIGHT: - if (outOfFocus) + case RIGHT: + if (outOfCursor) mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x() - 1, mViewBounds.y(), 1, mViewBounds.height()); findClosest = innerRight(node, bestData); break; case UP: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), + if (outOfCursor) + mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), mViewBounds.bottom(), mViewBounds.width(), 1); findClosest = innerUp(node, bestData); break; case DOWN: - if (outOfFocus) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), + if (outOfCursor) + mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), mViewBounds.y() - 1, mViewBounds.width(), 1); findClosest = innerDown(node, bestData); break; @@ -817,7 +823,7 @@ void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, return; if (bestData->mNode != NULL) { mHistory->addToVisited(bestData->mNode, direction); - mHistory->mNavBounds = mFocusBounds = bestData->mNodeBounds; + mHistory->mNavBounds = mCursorBounds = bestData->mNodeBounds; mHistory->mMouseBounds = bestData->mMouseBounds; } else if (scroll->x() != 0 || scroll->y() != 0) { WebCore::IntRect newBounds = mHistory->mNavBounds; @@ -846,8 +852,8 @@ bool CachedRoot::innerRight(const CachedNode* test, BestData* bestData) const mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); int testLeft = mScrolledBounds.x(); int viewRight = mViewBounds.right(); - if (mFocusBounds.isEmpty() == false && - mFocusBounds.right() > viewRight && viewRight < mContents.width()) + if (mCursorBounds.isEmpty() == false && + mCursorBounds.right() > viewRight && viewRight < mContents.width()) return false; if (mHistory->mNavBounds.isEmpty() == false) { int navLeft = mHistory->mNavBounds.x(); @@ -857,7 +863,7 @@ bool CachedRoot::innerRight(const CachedNode* test, BestData* bestData) const mScrolledBounds.setX(navLeft); } } - frameRight(test, NULL, bestData, currentFocus()); + frameRight(test, NULL, bestData, currentCursor()); return true; } @@ -870,8 +876,8 @@ bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); int testBottom = mScrolledBounds.bottom(); int viewTop = mViewBounds.y(); - if (mFocusBounds.isEmpty() == false && - mFocusBounds.y() < viewTop && viewTop > mContents.y()) + if (mCursorBounds.isEmpty() == false && + mCursorBounds.y() < viewTop && viewTop > mContents.y()) return false; if (mHistory->mNavBounds.isEmpty() == false) { int navBottom = mHistory->mNavBounds.bottom(); @@ -879,7 +885,7 @@ bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const if (testBottom > navBottom && navBottom > (scrollTop = mScrolledBounds.y())) mScrolledBounds.setHeight(navBottom - scrollTop); } - frameUp(test, NULL, bestData, currentFocus()); + frameUp(test, NULL, bestData, currentCursor()); return true; } @@ -907,7 +913,7 @@ bool CachedRoot::maskIfHidden(BestData* best) const if (bestNode->isUnclipped()) return false; // given the picture matching this nav cache - // create an SkBitmap with dimensions of the focus intersected w/ extended view + // create an SkBitmap with dimensions of the cursor intersected w/ extended view const WebCore::IntRect& nodeBounds = bestNode->getBounds(); WebCore::IntRect bounds = nodeBounds; bounds.intersect(mScrolledBounds); @@ -921,7 +927,7 @@ bool CachedRoot::maskIfHidden(BestData* best) const marginBounds.intersect(mScrolledBounds); BoundsCheck boundsCheck; BoundsCanvas checker(&boundsCheck); - boundsCheck.mBounds.set(leftMargin, topMargin, + boundsCheck.mBounds.set(leftMargin, topMargin, leftMargin + bounds.width(), topMargin + bounds.height()); boundsCheck.mBoundsSlop = boundsCheck.mBounds; boundsCheck.mBoundsSlop.inset(-kSlop, -kSlop); @@ -929,8 +935,8 @@ bool CachedRoot::maskIfHidden(BestData* best) const bitmap.setConfig(SkBitmap::kARGB_8888_Config, marginBounds.width(), marginBounds.height()); checker.setBitmapDevice(bitmap); - // insert probes to be called when the data corresponding to this focus ring is drawn - // need to know if focus ring was generated by text, image, or parent (like div) + // insert probes to be called when the data corresponding to this ring is drawn + // need to know if ring was generated by text, image, or parent (like div) // ? need to know (like imdb menu bar) to give up sometimes (when?) checker.translate(SkIntToScalar(leftMargin - bounds.x()), SkIntToScalar(topMargin - bounds.y())); @@ -989,17 +995,17 @@ bool CachedRoot::maskIfHidden(BestData* best) const #if DEBUG_NAV_UI && !defined BROWSER_DEBUG const SkIRect& modded = boundsCheck.mBounds; LOGD("%s partially occluded node:%p (%d) old:{%d,%d,%d,%d} new:{%d,%d,%d,%d}\n", - __FUNCTION__, best->mNode, best->mNode->index(), + __FUNCTION__, best->mNode, best->mNode->index(), orig.fLeft, orig.fTop, orig.fRight, orig.fBottom, base.fLeft, base.fTop, base.fRight, base.fBottom); #endif - best->mMouseBounds = WebCore::IntRect(bounds.x() + base.fLeft - kMargin, + best->mMouseBounds = WebCore::IntRect(bounds.x() + base.fLeft - kMargin, bounds.y() + base.fTop - kMargin, base.width(), base.height()); } return false; } -const CachedNode* CachedRoot::moveFocus(Direction direction, const CachedFrame** framePtr, +const CachedNode* CachedRoot::moveCursor(Direction direction, const CachedFrame** framePtr, WebCore::IntPoint* scroll) { #ifndef NDEBUG @@ -1028,7 +1034,7 @@ void CachedRoot::reset() mMaxXScroll = mMaxYScroll = 0; mSelectionStart = mSelectionEnd = -1; mScrollOnly = false; - mFocusBounds = WebCore::IntRect(0, 0, 0, 0); + mCursorBounds = WebCore::IntRect(0, 0, 0, 0); } bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, int* delta) @@ -1037,13 +1043,13 @@ bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, i case LEFT: *delta = -mMaxXScroll; return newOutset.x() >= mViewBounds.x(); - case RIGHT: + case RIGHT: *delta = mMaxXScroll; return newOutset.right() <= mViewBounds.right(); case UP: *delta = -mMaxYScroll; return newOutset.y() >= mViewBounds.y(); - case DOWN: + case DOWN: *delta = mMaxYScroll; return newOutset.bottom() <= mViewBounds.bottom(); default: @@ -1055,46 +1061,63 @@ bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, i void CachedRoot::setCachedFocus(CachedFrame* frame, CachedNode* node) { -#if !defined NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif -#if DEBUG_NAV_UI && !defined BROWSER_DEBUG - const CachedNode* focus = currentFocus(); - WebCore::IntRect bounds; - if (focus) - bounds = focus->bounds(); - LOGD("%s old focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif - clearFocus(); + mFocusBounds = WebCore::IntRect(0, 0, 0, 0); if (node == NULL) return; node->setIsFocus(true); - ASSERT(node->isFrame() == false); + mFocusBounds = node->bounds(); frame->setFocusIndex(node - frame->document()); - ASSERT(frame->focusIndex() > 0 && frame->focusIndex() < (int) frame->size()); CachedFrame* parent; while ((parent = frame->parent()) != NULL) { parent->setFocusIndex(frame->indexInParent()); frame = parent; } #if DEBUG_NAV_UI && !defined BROWSER_DEBUG - focus = currentFocus(); - bounds = WebCore::IntRect(0, 0, 0, 0); + const CachedNode* focus = currentFocus(); + WebCore::IntRect bounds = WebCore::IntRect(0, 0, 0, 0); if (focus) bounds = focus->bounds(); LOGD("%s new focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), + focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), bounds.width(), bounds.height()); #endif } -void CachedRoot::setupScrolledBounds() const +void CachedRoot::setCursor(CachedFrame* frame, CachedNode* node) { - mScrolledBounds = mViewBounds; +#if DEBUG_NAV_UI && !defined BROWSER_DEBUG + const CachedNode* cursor = currentCursor(); + WebCore::IntRect bounds; + if (cursor) + bounds = cursor->bounds(); + LOGD("%s old cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, + cursor ? cursor->index() : 0, + cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), + bounds.width(), bounds.height()); +#endif + clearCursor(); + mCursorBounds = WebCore::IntRect(0, 0, 0, 0); + if (node == NULL) + return; + node->setIsCursor(true); + mCursorBounds = node->bounds(); + frame->setCursorIndex(node - frame->document()); + CachedFrame* parent; + while ((parent = frame->parent()) != NULL) { + parent->setCursorIndex(frame->indexInParent()); + frame = parent; + } +#if DEBUG_NAV_UI && !defined BROWSER_DEBUG + cursor = currentCursor(); + bounds = WebCore::IntRect(0, 0, 0, 0); + if (cursor) + bounds = cursor->bounds(); + LOGD("%s new cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}\n", __FUNCTION__, + cursor ? cursor->index() : 0, + cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), + bounds.width(), bounds.height()); +#endif } #if DUMP_NAV_CACHE @@ -1109,7 +1132,7 @@ void CachedRoot::setupScrolledBounds() const CachedRoot* CachedRoot::Debug::base() const { CachedRoot* nav = (CachedRoot*) ((char*) this - OFFSETOF(CachedRoot, mDebug)); - return nav; + return nav; } void CachedRoot::Debug::print() const @@ -1122,10 +1145,10 @@ void CachedRoot::Debug::print() const CachedRoot* b = base(); b->CachedFrame::mDebug.print(); b->mHistory->mDebug.print(b); - DEBUG_PRINT_RECT(mFocusBounds); - DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n", + DEBUG_PRINT_RECT(mCursorBounds); + DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n", b->mMaxXScroll, b->mMaxYScroll); - DEBUG_PRINT_BOOL(mFocusChild); + DEBUG_PRINT_BOOL(mCursorChild); #ifdef DUMP_NAV_CACHE_USING_PRINTF if (gNavCacheLogFile) fclose(gNavCacheLogFile); diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h index d06e46c..52b6e34 100644 --- a/WebKit/android/nav/CachedRoot.h +++ b/WebKit/android/nav/CachedRoot.h @@ -46,14 +46,14 @@ public: void checkForJiggle(int* ) const; bool checkRings(const WTF::Vector<WebCore::IntRect>& rings, const WebCore::IntRect& bounds) const; + const WebCore::IntRect& cursorBounds() const { return mCursorBounds; } + WebCore::IntPoint cursorLocation() const; int documentHeight() { return mContents.height(); } int documentWidth() { return mContents.width(); } const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , int* x, int* y) const; const WebCore::IntRect& focusBounds() const { return mFocusBounds; } - bool focusChild() const { return mFocusChild; } WebCore::IntPoint focusLocation() const; - int generation() const { return mGeneration; } SkPicture* getPicture() { return mPicture; } int getAndResetSelectionEnd(); int getAndResetSelectionStart(); @@ -69,39 +69,40 @@ public: bool innerUp(const CachedNode* , BestData* ) const; WebCore::String imageURI(int x, int y) const; bool maskIfHidden(BestData* ) const; - const CachedNode* moveFocus(Direction , const CachedFrame** , WebCore::IntPoint* scroll); + const CachedNode* moveCursor(Direction , const CachedFrame** , WebCore::IntPoint* scroll); void reset(); // void resetNavClipBounds() { mClippedBounds = WebCore::IntRect(-1, -1, 0, 0); } CachedHistory* rootHistory() const { return mHistory; } - bool scrollDelta(WebCore::IntRect& focusRingBounds, Direction , int* delta); + bool scrollDelta(WebCore::IntRect& cursorRingBounds, Direction , int* delta); const WebCore::IntRect& scrolledBounds() const { return mScrolledBounds; } + void setCursor(CachedFrame* , CachedNode* ); void setCachedFocus(CachedFrame* , CachedNode* ); + void setCursorBounds(const WebCore::IntRect& r) { mCursorBounds = r; } void setFocusBounds(const WebCore::IntRect& r) { mFocusBounds = r; } - void setGeneration(int generation) { mGeneration = generation; } void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; } - void setFocusChild(bool state) const { mFocusChild = state; } + void setCursorChild(bool state) const { mCursorChild = state; } void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; } // void setNavClipBounds(const WebCore::IntRect& r) { mClippedBounds = r; } void setPicture(SkPicture* picture) { mPicture = picture; } void setScrollOnly(bool state) { mScrollOnly = state; } void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; } - void setupScrolledBounds() const; + void setupScrolledBounds() const { mScrolledBounds = mViewBounds; } void setVisibleRect(const WebCore::IntRect& r) { mViewBounds = r; } int textGeneration() const { return mTextGeneration; } int width() const { return mPicture ? mPicture->width() : 0; } private: CachedHistory* mHistory; SkPicture* mPicture; - WebCore::IntRect mFocusBounds; // chosen focus ring + WebCore::IntRect mCursorBounds; // chosen cursor ring + WebCore::IntRect mFocusBounds; // dom text input focus node bounds mutable WebCore::IntRect mScrolledBounds; // view bounds + amount visible as result of scroll - int mGeneration; int mTextGeneration; int mMaxXScroll; int mMaxYScroll; // These two are ONLY used when the tree is rebuilt and the focus is a textfield/area int mSelectionStart; int mSelectionEnd; - mutable bool mFocusChild; // temporary state set if walked nodes are children of focus + mutable bool mCursorChild; // temporary state set if walked nodes are children of focus bool mScrollOnly; #if DUMP_NAV_CACHE public: diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 8b7b6b9..954f8a1 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -69,264 +69,8 @@ #include <JNIHelp.h> #include <jni.h> -#define REPLAY_BUFFER_SIZE 4096 - namespace android { -struct CommonParams { - enum Trigger { - NoData, - ClearFocusParams, - FirstMoveFocusParams, - MoveFocusParams, - MotionUpParams - } m_trigger; - int m_generation; -}; - -struct CacheParams { - void setFocus(const CachedNode* node, - const CachedFrame* frame, const CachedRoot* root, - const WebCore::IntPoint& focusLocation) - { - m_node = (WebCore::Node*) (node ? node->nodePointer() : 0); - m_frame = (WebCore::Frame*) (node ? frame->framePointer() : 0); - m_x = focusLocation.x(); - m_y = focusLocation.y(); - } - - WebCore::Node* m_node; - WebCore::Frame* m_frame; - int m_x; - int m_y; -}; - -struct ClearFocusParams { - CommonParams d; - CacheParams c; - int m_x; - int m_y; -}; - -struct MotionUpParams { - CommonParams d; - int m_x; - int m_y; - int m_slop; -}; - -struct FirstMoveFocusParams { - CommonParams d; - int m_keyCode; - int m_count; - bool m_ignoreScroll; -}; - -struct MoveFocusParams { - FirstMoveFocusParams d; - CacheParams c; - void* m_sentFocus; - WebCore::IntRect m_sentBounds; - WebCore::IntRect m_visibleRect; - CachedHistory m_history; // FIXME: make this a subset - int m_xMax; - int m_yMax; -}; - -typedef MoveFocusParams LargestParams; - -#if DEBUG_NAV_UI -static const char* TriggerNames[] = { - "*** no data ! ***", - "clearFocus", - "firstMoveFocus", - "moveFocus", - "motionUp" -}; -#endif - -class FocusReplay { -public: -FocusReplay() : m_start(m_buffer), m_end(m_buffer), m_lastGeneration(0) -{ -} - -// find the most recent common data -void add(const CommonParams& data, size_t len) -{ - DBG_NAV_LOGD("m_start=%d m_end=%d trigger=%s moveGeneration=%d", m_start - m_buffer, - m_end - m_buffer, TriggerNames[data.m_trigger], data.m_generation); - m_lastGeneration = data.m_generation; - char* limit = m_buffer + sizeof(m_buffer); - int used = m_end - m_start; - if (used < 0) - used += sizeof(m_buffer); - int needed = (int) len - ((int) sizeof(m_buffer) - used); - if (needed >= 0) - reclaim(++needed); - if (m_end + len <= limit) { - memcpy(m_end, (void*) &data, len); - m_end += len; - DBG_NAV_LOGD("m_start=%d m_end=%d", m_start - m_buffer, m_end - m_buffer); - return; - } - size_t partial = limit - m_end; - memcpy(m_end, (void*) &data, partial); - const void* remainder = (const void*) ((const char*) &data + partial); - partial = len - partial; - memcpy(m_buffer, remainder, partial); - m_end = m_buffer + partial; - DBG_NAV_LOGD("wrap m_start=%d m_end=%d", - m_start - m_buffer, m_end - m_buffer); -} - -int count() -{ - DBG_NAV_LOGD("m_start=%d m_end=%d", - m_start - m_buffer, m_end - m_buffer); - if (m_start == m_end) - return 0; - char* limit = m_buffer + sizeof(m_buffer); - char* saveStart = m_start; - int result = 0; - while (true) { - ++result; - m_start += triggerSize(); - if (m_start == m_end) - break; - if (m_start < limit) - continue; - m_start -= sizeof(m_buffer); - if (m_start == m_end) - break; - } - m_start = saveStart; - DBG_NAV_LOGD("count=%d", result); - return result; -} - -void discard(int generation) -{ - DBG_NAV_LOGD("generation=%d", generation); - LargestParams storage; - const CommonParams& params = storage.d.d; - char* pos = position(); - retrieve(&storage.d.d); - if (params.m_generation > generation) { - DBG_NAV_LOGD("params.m_generation=%d > generation=%d", - params.m_generation, generation); - rewind(pos); - DBG_NAV_LOGD("m_start=%d m_end=%d", m_start - m_buffer, m_end - m_buffer); - return; - } - LOG_ASSERT(params.m_generation == generation, "params.m_generation != generation"); - DBG_NAV_LOGD("m_start=%d m_end=%d", m_start - m_buffer, m_end - m_buffer); -} - -int lastAdd() -{ - return m_lastGeneration; -} - -char* position() -{ - return m_start; -} - -int retrieve(CommonParams* data) -{ - if (m_end == m_start) { - // changed from LOGD to LOGV, as it always fires when I click to center - // text (mrr) - LOGV("%s *** no data to retrieve (error condition) ***", __FUNCTION__); - data->m_trigger = CommonParams::NoData; - return data->m_generation = INT_MAX; - } - DBG_NAV_LOGD("m_start=%d m_end=%d", - m_start - m_buffer, m_end - m_buffer); - char* limit = m_buffer + sizeof(m_buffer); - size_t size = triggerSize(); - if (m_start < m_end) { - LOG_ASSERT((size_t) (m_end - m_start) >= size, "m_end - m_start < size"); - memcpy(data, m_start, size); - m_start += size; - } else { - int partial = limit - m_start; - if (partial > (int) size) - partial = size; - memcpy(data, m_start, partial); - m_start += partial; - void* remainder = (void*) ((char*) data + partial); - partial = size - partial; - if (partial > 0) { - memcpy(remainder, m_buffer, partial); - m_start = m_buffer + partial; - LOG_ASSERT(m_start <= m_end, "m_start > m_end"); - } - } - if (m_start == limit) { - m_start = m_buffer; - if (m_end == limit) - m_end = m_buffer; - } - DBG_NAV_LOGD("m_start=%d m_end=%d trigger=%s moveGeneration=%d", - m_start - m_buffer, m_end - m_buffer, TriggerNames[data->m_trigger], - data->m_generation); - return data->m_generation; -} - -void rewind(char* pos) -{ - m_start = pos; -} - -private: -void reclaim(int needed) -{ - DBG_NAV_LOGD("needed=%d", needed); - char* limit = m_buffer + sizeof(m_buffer); - do { - size_t size = triggerSize(); - m_start += size; - needed -= size; - if (m_start >= limit) { - m_start = m_buffer + (m_start - limit); - if (m_end == limit) - m_end = m_buffer; - } - } while (needed > 0 && m_start != m_end); - DBG_NAV_LOGD("m_start=%d m_end=%d", - m_start - m_buffer, m_end - m_buffer); -} - -size_t triggerSize() -{ - LOG_ASSERT(m_start != m_end, "m_start == m_end"); - char* limit = m_buffer + sizeof(m_buffer); - LOG_ASSERT(m_start + sizeof(CommonParams::Trigger) <= limit, "trigger not in limit"); - CommonParams::Trigger trigger; - memcpy(&trigger, m_start, sizeof(trigger)); - switch (trigger) { - case CommonParams::ClearFocusParams: - return sizeof(ClearFocusParams); - case CommonParams::FirstMoveFocusParams: - return sizeof(FirstMoveFocusParams); - case CommonParams::MoveFocusParams: - return sizeof(MoveFocusParams); - case CommonParams::MotionUpParams: - return sizeof(MotionUpParams); - default: - LOG_ASSERT(0, "trigger undefined"); - } - return 0; -} - -char m_buffer[REPLAY_BUFFER_SIZE]; -char* m_start; -char* m_end; -int m_lastGeneration; -}; // end of helper class ReplayFocus - static jfieldID gWebViewField; //------------------------------------- @@ -350,21 +94,14 @@ enum FrameCachePermission { AllowNewest }; -enum OutOfFocusFix { - DoNothing, - ClearTextEntry, - UpdateTextEntry -}; - struct JavaGlue { jobject m_obj; jmethodID m_clearTextEntry; jmethodID m_overrideLoading; jmethodID m_scrollBy; - jmethodID m_sendFinalFocus; - jmethodID m_sendKitFocus; + jmethodID m_sendMoveMouse; + jmethodID m_sendMoveMouseIfLatest; jmethodID m_sendMotionUp; - jmethodID m_setFocusData; jmethodID m_getScaledMaxXScroll; jmethodID m_getScaledMaxYScroll; jmethodID m_getVisibleRect; @@ -377,8 +114,6 @@ struct JavaGlue { jfieldID m_rectTop; jmethodID m_rectWidth; jmethodID m_rectHeight; - jfieldID m_focusNode; - jmethodID m_setAll; AutoJObject object(JNIEnv* env) { return getRealObject(env, m_obj); } @@ -392,10 +127,9 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)V"); m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); - m_javaGlue.m_sendFinalFocus = GetJMethod(env, clazz, "sendFinalFocus", "(IIII)V"); - m_javaGlue.m_sendKitFocus = GetJMethod(env, clazz, "sendKitFocus", "()V"); - m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIIIIIZ)V"); - m_javaGlue.m_setFocusData = GetJMethod(env, clazz, "setFocusData", "(IIIIIIZ)V"); + m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); + m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "()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"); m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); @@ -412,13 +146,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I"); m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); - // Set up class for updateFocusNode - jclass focusnodeClass = env->FindClass("android/webkit/WebView$FocusNode"); - LOG_ASSERT(focusnodeClass, "Could not find FocusNode class!"); - m_javaGlue.m_focusNode = env->GetFieldID(clazz, "mFocusNode", "Landroid/webkit/WebView$FocusNode;"); - m_javaGlue.m_setAll = GetJMethod(env, focusnodeClass, "setAll", "(ZZZZZIIIIIIIILjava/lang/String;Ljava/lang/String;I)V"); - env->DeleteLocalRef(focusnodeClass); - env->SetIntField(javaWebView, gWebViewField, (jint)this); m_viewImpl = (WebViewCore*) viewImpl; m_frameCacheUI = 0; @@ -451,33 +178,16 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) delete m_matches; } -void clearFocus(int x, int y, bool inval) +void clearCursor(int x, int y, bool inval) { - DBG_NAV_LOGD("x=%d y=%d inval=%s", x, y, - inval ? "true" : "false"); - clearTextEntry(); + DBG_NAV_LOGD("x=%d y=%d inval=%s", x, y, inval ? "true" : "false"); CachedRoot* root = getFrameCache(AllowNewer); - if (!root) + if (!root || !root->currentCursor()) return; - const CachedFrame* oldFrame = 0; - const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - WebCore::IntPoint focusLocation = WebCore::IntPoint(0, 0); - setFocusData(root->generation(), 0, 0, x, y, !oldFocusNode); - sendKitFocus(); - if (oldFocusNode) { - DBG_NAV_LOG("oldFocusNode"); - focusLocation = root->focusLocation(); - root->setCachedFocus(0, 0); - if (inval) - viewInvalidate(); - } - ClearFocusParams params; - params.d.m_trigger = CommonParams::ClearFocusParams; - params.d.m_generation = m_generation; - params.c.setFocus(oldFocusNode, oldFrame, root, focusLocation); - params.m_x = x; - params.m_y = y; - m_replay.add(params.d, sizeof(params)); + DBG_NAV_LOG("root->setCursor(0, 0)"); + root->setCursor(0, 0); + if (inval) + viewInvalidate(); } void clearTextEntry() @@ -498,40 +208,38 @@ void debugDump() #endif // Traverse our stored array of buttons that are in our picture, and update -// their subpictures according to their current focus state. +// their subpictures according to their current state. // Called from the UI thread. This is the one place in the UI thread where we // access the buttons stored in the WebCore thread. // hasFocus keeps track of whether the WebView has focus && windowFocus. -// If not, we do not want to draw the button in a focused or pressed state +// If not, we do not want to draw the button in a selected or pressed state void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) { - bool focusIsButton = false; - const CachedNode* cachedFocus = 0; + bool cursorIsOnButton = false; + const CachedNode* cachedCursor = 0; // Lock the mutex, since we now share with the WebCore thread. m_viewImpl->gButtonMutex.lock(); if (m_viewImpl->m_buttons.size()) { - // Find the focused node so we can determine which node has focus, and - // therefore which state to paint them in. - // FIXME: In a future change, we should keep track of whether the focus + // FIXME: In a future change, we should keep track of whether the selection // has changed to short circuit (note that we would still need to update // if we received new buttons from the WebCore thread). - WebCore::Node* focus = 0; + WebCore::Node* cursor = 0; CachedRoot* root = getFrameCache(DontAllowNewer); if (root) { - cachedFocus = root->currentFocus(); - if (cachedFocus) - focus = (WebCore::Node*) cachedFocus->nodePointer(); + cachedCursor = root->currentCursor(); + if (cachedCursor) + cursor = (WebCore::Node*) cachedCursor->nodePointer(); } // Traverse the array, and update each button, depending on whether it - // is focused. + // is selected. Container* end = m_viewImpl->m_buttons.end(); for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) { WebCore::RenderSkinAndroid::State state; - if (ptr->matches(focus)) { - focusIsButton = true; + if (ptr->matches(cursor)) { + cursorIsOnButton = true; // If the WebView is out of focus/window focus, set the state to - // normal, but still keep track of the fact that the focus is a + // normal, but still keep track of the fact that the selected is a // button if (!hasFocus) { state = WebCore::RenderSkinAndroid::kNormal; @@ -547,8 +255,8 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) } } m_viewImpl->gButtonMutex.unlock(); - if (invalidate && cachedFocus && focusIsButton) { - const WebCore::IntRect& b = cachedFocus->getBounds(); + if (invalidate && cachedCursor && cursorIsOnButton) { + const WebCore::IntRect& b = cachedCursor->getBounds(); viewInvalidateRect(b.x(), b.y(), b.right(), b.bottom()); } } @@ -576,7 +284,7 @@ void setUpFindPaint() m_isFindPaintSetUp = true; } -// Draw the match specified by region to the canvas. +// Draw the match specified by region to the canvas. void drawMatch(const SkRegion& region, SkCanvas* canvas, bool focused) { // For the match which has focus, use a filled paint. For the others, use @@ -681,40 +389,44 @@ void drawMatches(SkCanvas* canvas) } } -void drawFocusRing(SkCanvas* canvas) +void drawCursorRing(SkCanvas* canvas) { const CachedRoot* root = getFrameCache(AllowNewer); if (!root) { DBG_NAV_LOG("!root"); m_followedLink = false; + m_viewImpl->m_hasCursorBounds = false; return; } - const CachedNode* node = root->currentFocus(); + const CachedNode* node = root->currentCursor(); if (!node) { DBG_NAV_LOG("!node"); m_followedLink = false; + m_viewImpl->m_hasCursorBounds = false; return; } - if (!node->hasFocusRing()) { - DBG_NAV_LOG("!node->hasFocusRing()"); + if (!node->hasCursorRing()) { + DBG_NAV_LOG("!node->hasCursorRing()"); + m_viewImpl->m_hasCursorBounds = false; return; } - const WTF::Vector<WebCore::IntRect>* rings = &node->focusRings(); + const WTF::Vector<WebCore::IntRect>* rings = &node->cursorRings(); if (!rings->size()) { DBG_NAV_LOG("!rings->size()"); + m_viewImpl->m_hasCursorBounds = false; return; } bool isButton = false; m_viewImpl->gButtonMutex.lock(); // If this is a button drawn by us (rather than webkit) do not draw the - // focus ring, since its focus will be shown by a change in what we draw. + // cursor ring, since its cursor will be shown by a change in what we draw. // Should be in sync with recordButtons, since that will be called // before this. if (m_viewImpl->m_buttons.size() > 0) { - WebCore::Node* focusPointer = (WebCore::Node*) node->nodePointer(); + WebCore::Node* cursorPointer = (WebCore::Node*) node->nodePointer(); Container* end = m_viewImpl->m_buttons.end(); for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) { - if (ptr->matches(focusPointer)) { + if (ptr->matches(cursorPointer)) { isButton = true; break; } @@ -722,20 +434,29 @@ void drawFocusRing(SkCanvas* canvas) } m_viewImpl->gButtonMutex.unlock(); WebCore::IntRect bounds = node->bounds(); - bounds.inflate(SkScalarCeil(FOCUS_RING_OUTER_DIAMETER)); + m_viewImpl->gCursorBoundsMutex.lock(); + m_viewImpl->m_hasCursorBounds = true; + if (m_viewImpl->m_cursorBounds != bounds) + 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->gCursorBoundsMutex.unlock(); + bounds.inflate(SkScalarCeil(CURSOR_RING_OUTER_DIAMETER)); if (canvas->quickReject(bounds, SkCanvas::kAA_EdgeType)) { - DBG_NAV_LOG("canvas->quickReject"); + DBG_NAV_LOGD("canvas->quickReject cursorNode=%d (nodePointer=%p)" + " bounds=(%d,%d,w=%d,h=%d)", node->index(), node->nodePointer(), + bounds.x(), bounds.y(), bounds.width(), bounds.height()); m_followedLink = false; return; } - FocusRing::Flavor flavor = FocusRing::NORMAL_FLAVOR; + CursorRing::Flavor flavor = CursorRing::NORMAL_FLAVOR; WTF::Vector<WebCore::IntRect> oneRing; if (!isButton) { flavor = node->type() != NORMAL_CACHEDNODETYPE ? - FocusRing::FAKE_FLAVOR : node->nodePointer() == m_invalidNode ? - FocusRing::INVALID_FLAVOR : FocusRing::NORMAL_FLAVOR; - if (flavor != FocusRing::INVALID_FLAVOR && m_followedLink) { - flavor = (FocusRing::Flavor) (flavor + FocusRing::NORMAL_ANIMATING); + CursorRing::FAKE_FLAVOR : node->nodePointer() == m_invalidNode ? + CursorRing::INVALID_FLAVOR : CursorRing::NORMAL_FLAVOR; + if (flavor != CursorRing::INVALID_FLAVOR && m_followedLink) { + flavor = (CursorRing::Flavor) (flavor + CursorRing::NORMAL_ANIMATING); } bool useHitBounds = node->useHitBounds(); if (useHitBounds || node->useBounds()) { @@ -744,16 +465,16 @@ void drawFocusRing(SkCanvas* canvas) } #if DEBUG_NAV_UI const WebCore::IntRect& ring = (*rings)[0]; - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p) flavor=%s rings=%d" + DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) flavor=%s rings=%d" " (%d, %d, %d, %d)", node->index(), node->nodePointer(), - flavor == FocusRing::FAKE_FLAVOR ? "FAKE_FLAVOR" : - flavor == FocusRing::INVALID_FLAVOR ? "INVALID_FLAVOR" : - flavor == FocusRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" : - flavor == FocusRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR", + flavor == CursorRing::FAKE_FLAVOR ? "FAKE_FLAVOR" : + flavor == CursorRing::INVALID_FLAVOR ? "INVALID_FLAVOR" : + flavor == CursorRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" : + flavor == CursorRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR", rings->size(), ring.x(), ring.y(), ring.width(), ring.height()); #endif } - if (isButton || flavor >= FocusRing::NORMAL_ANIMATING) { + if (isButton || flavor >= CursorRing::NORMAL_ANIMATING) { SkMSec time = SkTime::GetMSecs(); if (time < m_ringAnimationEnd) { // views assume that inval bounds coordinates are non-negative @@ -761,114 +482,34 @@ void drawFocusRing(SkCanvas* canvas) postInvalidateDelayed(m_ringAnimationEnd - time, bounds); } else { m_followedLink = false; - flavor = (FocusRing::Flavor) (flavor - FocusRing::NORMAL_ANIMATING); + flavor = (CursorRing::Flavor) (flavor - CursorRing::NORMAL_ANIMATING); } } if (!isButton) - FocusRing::DrawRing(canvas, *rings, flavor); -} - -OutOfFocusFix fixOutOfDateFocus(bool useReplay) -{ - if (!m_frameCacheUI) { - DBG_NAV_LOG("!m_frameCacheUI"); - return DoNothing; - } - const CachedFrame* cachedFrame = 0; - const CachedNode* cachedFocusNode = m_frameCacheUI->currentFocus(&cachedFrame); - if (!cachedFocusNode) { - DBG_NAV_LOG("!cachedFocusNode"); - return DoNothing; - } - CachedRoot* webRoot = m_viewImpl->m_frameCacheKit; - if (!webRoot) { - DBG_NAV_LOG("!webRoot"); - return DoNothing; - } - int uiWidth = m_frameCacheUI->width(); - int webWidth = webRoot->width(); - if (uiWidth != webWidth) { - DBG_NAV_LOGD("uiWidth=%d webWidth=%d", uiWidth, webWidth); - return DoNothing; // allow text inputs to preserve their state - } else { - const WebCore::IntRect& cachedBounds = m_frameCacheUI->focusBounds(); - const CachedFrame* webFrame = 0; - const CachedNode* webFocusNode = webRoot->currentFocus(&webFrame); - DBG_NAV_LOGD("cachedBounds=(%d,%d,w=%d,h=%d) cachedFrame=%p (%d)" - " webFocusNode=%p (%d) webFrame=%p (%d)", - cachedBounds.x(), cachedBounds.y(), - cachedBounds.width(), cachedBounds.height(), - cachedFrame, cachedFrame ? cachedFrame->indexInParent() : -1, - webFocusNode, webFocusNode ? webFocusNode->index() : -1, - webFrame, webFrame ? webFrame->indexInParent() : -1); - if (webFocusNode && webFrame && webFrame->sameFrame(cachedFrame)) { - if (useReplay && !m_replay.count()) { - DBG_NAV_LOG("!m_replay.count()"); - return DoNothing; - } - const WebCore::IntRect& webBounds = webRoot->focusBounds(); - DBG_NAV_LOGD("webBounds=(%d,%d,w=%d,h=%d)", - webBounds.x(), webBounds.y(), - webBounds.width(), webBounds.height()); - if (cachedBounds.contains(webBounds)) { - DBG_NAV_LOG("contains"); - return DoNothing; - } - if (webBounds.contains(cachedBounds)) { - DBG_NAV_LOG("webBounds contains"); - return DoNothing; - } - } - const CachedFrame* foundFrame = 0; - int x, y; - const CachedNode* found = findAt(webRoot, cachedBounds, &foundFrame, &x, &y); -#if DEBUG_NAV_UI - DBG_NAV_LOGD("found=%p (%d) frame=%p (%d)", - found, found ? found->index() : -1, - foundFrame, foundFrame ? foundFrame->indexInParent() : -1); - if (found) { - WebCore::IntRect newBounds = found->bounds(); - DBG_NAV_LOGD("found=(%d,%d,w=%d,h=%d) x=%d y=%d", - newBounds.x(), newBounds.y(), newBounds.width(), - newBounds.height(), x, y); - } -#endif - webRoot->setCachedFocus(const_cast<CachedFrame*>(foundFrame), - const_cast<CachedNode*>(found)); - if (found) - webRoot->rootHistory()->setNavBounds(found->bounds()); - WebCore::Frame* framePointer = foundFrame ? (WebCore::Frame*) foundFrame->framePointer() : 0; - WebCore::Node* nodePointer = found ? (WebCore::Node*) found->nodePointer() : 0; - setFocusData(webRoot->generation(), framePointer, nodePointer, x, y, !found); - sendFinalFocus(framePointer, nodePointer, x, y); - if (found && (found->isTextArea() || found->isTextField())) - return UpdateTextEntry; - } -checkOldFocus: - return cachedFocusNode->isTextArea() || cachedFocusNode->isTextField() ? ClearTextEntry : DoNothing; + CursorRing::DrawRing(canvas, *rings, flavor); } -bool focusIsTextArea(FrameCachePermission allowNewer) +bool cursorIsTextInput(FrameCachePermission allowNewer) { - CachedRoot* root = getFrameCache(allowNewer, false); + CachedRoot* root = getFrameCache(allowNewer); if (!root) { DBG_NAV_LOG("!root"); return false; } - const CachedNode* focus = root->currentFocus(); - if (!focus) + const CachedNode* cursor = root->currentCursor(); + if (!cursor) return false; - return focus->isTextArea() || focus->isTextField(); + return cursor->isTextArea() || cursor->isTextField(); } -void focusRingBounds(WebCore::IntRect* bounds) +void cursorRingBounds(WebCore::IntRect* bounds) { DBG_NAV_LOGD("%s", ""); CachedRoot* root = getFrameCache(DontAllowNewer); if (root) { - const CachedNode* cachedNode = root->currentFocus(); + const CachedNode* cachedNode = root->currentCursor(); if (cachedNode) { - cachedNode->focusRingBounds(bounds); + cachedNode->cursorRingBounds(bounds); DBG_NAV_LOGD("bounds={%d,%d,%d,%d}", bounds->x(), bounds->y(), bounds->width(), bounds->height()); return; @@ -879,26 +520,18 @@ void focusRingBounds(WebCore::IntRect* bounds) CachedRoot* getFrameCache(FrameCachePermission allowNewer) { - return getFrameCache(allowNewer, allowNewer != DontAllowNewer); -} - -CachedRoot* getFrameCache(FrameCachePermission allowNewer, bool fixFocus) -{ - if (!m_viewImpl->m_updatedFrameCache) + if (!m_viewImpl->m_updatedFrameCache) { + DBG_NAV_LOG("!m_viewImpl->m_updatedFrameCache"); return m_frameCacheUI; - m_viewImpl->gRecomputeFocusMutex.lock(); - bool recomputeInProgress = m_viewImpl->m_recomputeEvents.size() > 0; - m_viewImpl->gRecomputeFocusMutex.unlock(); - if (allowNewer != AllowNewest && recomputeInProgress) - return m_frameCacheUI; - if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) + } + if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) { + DBG_NAV_LOGD("allowNewer==DontAllowNewer m_viewImpl->m_lastGeneration=%d" + " < m_generation=%d", m_viewImpl->m_lastGeneration, m_generation); return m_frameCacheUI; + } DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true"); - bool hadFocus = m_frameCacheUI && m_frameCacheUI->currentFocus(); + bool hadCursor = m_frameCacheUI && m_frameCacheUI->currentCursor(); m_viewImpl->gFrameCacheMutex.lock(); - OutOfFocusFix fix = DoNothing; - if (fixFocus) - fix = fixOutOfDateFocus(m_viewImpl->m_useReplay); delete m_frameCacheUI; delete m_navPictureUI; m_viewImpl->m_updatedFrameCache = false; @@ -907,12 +540,8 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer, bool fixFocus) m_viewImpl->m_frameCacheKit = 0; m_viewImpl->m_navPictureKit = 0; m_viewImpl->gFrameCacheMutex.unlock(); - if (hadFocus && (!m_frameCacheUI || !m_frameCacheUI->currentFocus())) - viewInvalidate(); // redraw in case focus ring is still visible - if (fix == UpdateTextEntry) - updateTextEntry(); - else if (fix == ClearTextEntry) - clearTextEntry(); + if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) + viewInvalidate(); // redraw in case cursor ring is still visible return m_frameCacheUI; } @@ -972,20 +601,11 @@ static CachedFrame::Direction KeyToDirection(KeyCode keyCode) DBG_NAV_LOGD("keyCode=%s", "up"); return CachedFrame::UP; default: - LOGD("------- bad key sent to WebView::moveFocus"); + LOGD("------- bad key sent to WebView::moveCursor"); return CachedFrame::UNINITIALIZED; } } -bool invalidFrame(WebCore::Frame* frame, const CachedRoot* root) -{ - if (!frame) - return false; - int frameBuild = m_viewImpl->retrieveFrameGeneration(frame); - int rootBuild = root->generation(); - return frameBuild > rootBuild; -} - WebCore::String imageURI(int x, int y) { const CachedRoot* root = getFrameCache(DontAllowNewer); @@ -997,39 +617,30 @@ bool focusNodeWantsKeyEvents() const CachedRoot* root = getFrameCache(DontAllowNewer); if (root) { const CachedNode* focus = root->currentFocus(); - if (focus) { + if (focus) return focus->isWantsKeyEvents(); - } } return false; } -/* returns true if the key had no effect (neither scrolled nor changed focus) */ -bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval, - void* lastSentFocus, const WebCore::IntRect* lastSentBounds) +/* returns true if the key had no effect (neither scrolled nor changed cursor) */ +bool moveCursor(int keyCode, int count, bool ignoreScroll, bool inval, + void* lastSentCursor, const WebCore::IntRect* lastSentBounds) { CachedRoot* root = getFrameCache(AllowNewer); if (!root) { DBG_NAV_LOG("!root"); - setFocusData(0, 0, 0, 0, 0, true); - sendKitFocus(); // will build cache and retry - FirstMoveFocusParams params; - params.d.m_trigger = CommonParams::FirstMoveFocusParams; - params.d.m_generation = m_generation; - params.m_keyCode = keyCode; - params.m_count = count; - params.m_ignoreScroll = ignoreScroll; - m_replay.add(params.d, sizeof(params)); return true; } + m_viewImpl->m_moveGeneration++; CachedFrame::Direction direction = KeyToDirection((KeyCode) keyCode); const CachedFrame* cachedFrame, * oldFrame = 0; - const CachedNode* focus = root->currentFocus(&oldFrame); - WebCore::IntPoint focusLocation = root->focusLocation(); - DBG_NAV_LOGD("old focus %d (nativeNode=%p) focusLocation={%d, %d}", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : 0, focusLocation.x(), focusLocation.y()); + const CachedNode* cursor = root->currentCursor(&oldFrame); + WebCore::IntPoint cursorLocation = root->cursorLocation(); + DBG_NAV_LOGD("old cursor %d (nativeNode=%p) cursorLocation={%d, %d}", + cursor ? cursor->index() : 0, + cursor ? cursor->nodePointer() : 0, cursorLocation.x(), cursorLocation.y()); WebCore::IntRect visibleRect; getVisibleRect(&visibleRect); DBG_NAV_LOGD("getVisibleRect %d,%d,%d,%d", @@ -1039,28 +650,37 @@ bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval, int yMax = getScaledMaxYScroll(); root->setMaxScroll(xMax, yMax); CachedHistory savedHistory = *root->rootHistory(); - bool oldNodeIsTextArea = focusIsTextArea(DontAllowNewer); const CachedNode* cachedNode = 0; int dx = 0; int dy = 0; int counter = count; - if (!focus || !focus->isInput() || !m_followedLink) + if (!cursor || !cursor->isInput() || !m_followedLink) root->setScrollOnly(m_followedLink); while (--counter >= 0) { WebCore::IntPoint scroll = WebCore::IntPoint(0, 0); - cachedNode = root->moveFocus(direction, &cachedFrame, &scroll); + cachedNode = root->moveCursor(direction, &cachedFrame, &scroll); dx += scroll.x(); dy += scroll.y(); } - DBG_NAV_LOGD("new focus %d (nativeNode=%p) focusLocation={%d, %d}", - cachedNode ? cachedNode->index() : 0, - cachedNode ? cachedNode->nodePointer() : 0, root->focusLocation().x(), - root->focusLocation().y()); + if (cachedNode) { + m_viewImpl->gCursorBoundsMutex.lock(); + m_viewImpl->m_hasCursorBounds = true; + m_viewImpl->m_cursorBounds = cachedNode->bounds(); + m_viewImpl->gCursorBoundsMutex.unlock(); + } + DBG_NAV_LOGD("new cursor %d (nativeNode=%p) cursorLocation={%d, %d}" + "bounds={%d,%d,w=%d,h=%d}", cachedNode ? cachedNode->index() : 0, + cachedNode ? cachedNode->nodePointer() : 0, + root->cursorLocation().x(), root->cursorLocation().y(), + cachedNode ? cachedNode->bounds().x() : 0, + cachedNode ? cachedNode->bounds().y() : 0, + cachedNode ? cachedNode->bounds().width() : 0, + cachedNode ? cachedNode->bounds().height() : 0); // If !m_heightCanMeasure (such as in the browser), we want to scroll no // matter what if (!ignoreScroll && (!m_heightCanMeasure || !cachedNode || - (focus && focus->nodePointer() == cachedNode->nodePointer()))) + (cursor && cursor->nodePointer() == cachedNode->nodePointer()))) { if (count == 1 && dx != 0 && dy == 0 && -m_lastDx == dx && SkTime::GetMSecs() - m_lastDxTime < 1000) @@ -1075,50 +695,21 @@ bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval, bool result = false; if (cachedNode) { WebCore::IntPoint pos; - root->setCachedFocus((CachedFrame*) cachedFrame, (CachedNode*) cachedNode); + root->setCursor((CachedFrame*) cachedFrame, (CachedNode*) cachedNode); root->getSimulatedMousePosition(&pos); - if (lastSentFocus == cachedNode->nodePointer() && lastSentBounds && + if (lastSentCursor == cachedNode->nodePointer() && lastSentBounds && *lastSentBounds == cachedNode->bounds()) { - sendFinalFocus((WebCore::Frame*) cachedFrame->framePointer(), + sendMoveMouse((WebCore::Frame*) cachedFrame->framePointer(), (WebCore::Node*) cachedNode->nodePointer(), pos.x(), pos.y()); } else { - setFocusData(root->generation(), - (WebCore::Frame*) cachedFrame->framePointer(), - (WebCore::Node*) cachedNode->nodePointer(), pos.x(), pos.y(), - true); - sendKitFocus(); + sendMoveMouseIfLatest(); if (inval) viewInvalidate(); - MoveFocusParams params; - params.d.d.m_trigger = CommonParams::MoveFocusParams; - params.d.d.m_generation = m_generation; - params.c.setFocus(focus, oldFrame, root, focusLocation); - params.m_sentFocus = cachedNode->nodePointer(); - params.m_sentBounds = cachedNode->bounds(); - params.m_visibleRect = visibleRect; - params.m_history = savedHistory; DBG_NAV_LOGD("history.mDidFirstLayout=%s", - params.m_history.didFirstLayout() ? "true" : "false"); - params.m_xMax = xMax; - params.m_yMax = yMax; - params.d.m_keyCode = keyCode; - params.d.m_count = count; - params.d.m_ignoreScroll = ignoreScroll; - m_replay.add(params.d.d, sizeof(params)); + savedHistory.didFirstLayout() ? "true" : "false"); } } else { - if (visibleRect.intersects(root->focusBounds()) == false) { - setFocusData(root->generation(), 0, 0, 0, 0, true); - sendKitFocus(); // will build cache and retry - } - FirstMoveFocusParams params; - params.d.m_trigger = CommonParams::FirstMoveFocusParams; - params.d.m_generation = m_generation; - params.m_keyCode = keyCode; - params.m_count = count; - params.m_ignoreScroll = ignoreScroll; - m_replay.add(params.d, sizeof(params)); int docHeight = root->documentHeight(); int docWidth = root->documentWidth(); if (visibleRect.bottom() + dy > docHeight) @@ -1133,45 +724,12 @@ bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval, direction == CachedFrame::RIGHT ? dx <= 0 : direction == CachedFrame::UP ? dy >= 0 : dy <= 0; } - if (focusIsTextArea(DontAllowNewer)) - updateTextEntry(); - else if (oldNodeIsTextArea) - clearTextEntry(); return result; } -void notifyFocusSet(FrameCachePermission inEditingMode) -{ - DBG_NAV_LOGD("inEditingMode=%s", inEditingMode ? "true" : "false"); - if (focusIsTextArea(inEditingMode)) - updateTextEntry(); - else if (inEditingMode) - clearTextEntry(); - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - // make sure the mFocusData in WebView.java is in sync with WebView.cpp - const CachedFrame* frame = 0; - const CachedNode* node = root->currentFocus(&frame); - const WebCore::IntPoint& focusLocation = root->focusLocation(); - setFocusData(root->generation(), - frame ? (WebCore::Frame*) frame->framePointer() : 0, - node ? (WebCore::Node*) node->nodePointer() : 0, - focusLocation.x(), focusLocation.y(), false); - } - -#if DEBUG_NAV_UI - if (m_frameCacheUI) { - const CachedNode* focus = m_frameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : 0); - } -#endif -} - void notifyProgressFinished() { - DBG_NAV_LOGD("focusIsTextArea=%d", focusIsTextArea(DontAllowNewer)); + DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); updateTextEntry(); #if DEBUG_NAV_UI if (m_frameCacheUI) { @@ -1183,121 +741,6 @@ void notifyProgressFinished() #endif } -void recomputeFocus() -{ - int generation; - do { - m_viewImpl->gRecomputeFocusMutex.lock(); - if (!m_viewImpl->m_recomputeEvents.size()) { - m_viewImpl->gRecomputeFocusMutex.unlock(); - return; - } - generation = m_viewImpl->m_recomputeEvents.first(); - m_viewImpl->m_recomputeEvents.remove(0); - m_viewImpl->gRecomputeFocusMutex.unlock(); - DBG_NAV_LOGD("generation=%d", generation); - CachedRoot* root = getFrameCache(AllowNewest); - if (!root) { - DBG_NAV_LOG("!root"); - return; - } - LargestParams storage; - const CommonParams& params = storage.d.d; - char* pos = m_replay.position(); - while (m_replay.retrieve(&storage.d.d) < generation) - DBG_NAV_LOGD("dropped ", params.m_generation); - if (params.m_generation > generation) { - DBG_NAV_LOGD("params.m_generation=%d > generation=%d", - params.m_generation, generation); - m_replay.rewind(pos); - return; - } - int lastAdd = m_replay.lastAdd(); - do { - LOG_ASSERT(params.m_trigger != CommonParams::NoData, "expected data"); - bool inval = generation == m_generation; - switch (params.m_trigger) { - case CommonParams::ClearFocusParams: { - const ClearFocusParams& sParams = *(ClearFocusParams*) &storage; - const CacheParams& cParams = sParams.c; - if (invalidFrame(cParams.m_frame, root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.m_trigger], generation); - return; - } - root->setFocus(cParams.m_frame, cParams.m_node, cParams.m_x, cParams.m_y); - clearFocus(sParams.m_x, sParams.m_y, inval); - DBG_NAV_LOGD("clearFocus(x,y)={%d,%d}", sParams.m_x, sParams.m_y); - } break; - case CommonParams::MotionUpParams: { - const MotionUpParams& mParams = *(MotionUpParams*) &storage; - // const CacheParams& cParams = mParams.c; - // if (invalidFrame(cParams.m_frame, root) == false) - // root->setFocus(cParams.m_frame, cParams.m_node, - // cParams.m_x, cParams.m_y); - motionUp(mParams.m_x, mParams.m_y, mParams.m_slop, inval, true); - DBG_NAV_LOGD("motionUp m_x=%d m_y=%d", mParams.m_x, mParams.m_y); - } break; - case CommonParams::FirstMoveFocusParams: { - if (invalidFrame((WebCore::Frame*) root->framePointer(), root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.m_trigger], generation); - return; - } - const FirstMoveFocusParams& fParams = *(FirstMoveFocusParams*) &storage; - DBG_NAV_LOGD("first moveFocus keyCode=%d count=%d" - " ignoreScroll=%s", fParams.m_keyCode, fParams.m_count, - fParams.m_ignoreScroll ? "true" : "false"); - moveFocus(fParams.m_keyCode, fParams.m_count, - fParams.m_ignoreScroll, inval, 0, 0); - } break; - case CommonParams::MoveFocusParams: { - const MoveFocusParams& mParams = *(MoveFocusParams*) &storage; - const CacheParams& cParams = mParams.c; - if (invalidFrame(cParams.m_frame, root)) { - DBG_NAV_LOGD("dropped %s generation=%d", - TriggerNames[params.m_trigger], generation); - return; - } - DBG_NAV_LOGD("moveFocus keyCode=%d count=%d ignoreScroll=%s " - "history.mDidFirstLayout=%s", mParams.d.m_keyCode, - mParams.d.m_count, mParams.d.m_ignoreScroll ? "true" : "false", - mParams.m_history.didFirstLayout() ? "true" : "false"); - if (!root->setFocus(cParams.m_frame, cParams.m_node, - cParams.m_x, cParams.m_y)) { - DBG_NAV_LOGD("can't restore focus frame=%p node=%p", - "x=%d y=%d %s", cParams.m_frame, cParams.m_node, - cParams.m_x, cParams.m_y, TriggerNames[params.m_trigger]); - return; - } - root->setVisibleRect(mParams.m_visibleRect); - root->setMaxScroll(mParams.m_xMax, mParams.m_yMax); - *root->rootHistory() = mParams.m_history; - moveFocus(mParams.d.m_keyCode, mParams.d.m_count, - mParams.d.m_ignoreScroll, inval, - mParams.m_sentFocus, &mParams.m_sentBounds); - } break; - default: - LOG_ASSERT(0, "unknown trigger"); - } - if (params.m_generation >= lastAdd) - break; - root = getFrameCache(DontAllowNewer); // re-execution may have retrieved newer cache - m_replay.retrieve(&storage.d.d); - DBG_NAV_LOGD("continuation m_generation %d", params.m_generation); - } while (true); - } while (true); -} - -void resetFocus() -{ - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - root->setCachedFocus(0, 0); -} - const CachedNode* findAt(CachedRoot* root, const WebCore::IntRect& rect, const CachedFrame** framePtr, int* rxPtr, int* ryPtr) { @@ -1318,40 +761,24 @@ void selectBestAt(const WebCore::IntRect& rect) int rx, ry; CachedRoot* root = getFrameCache(DontAllowNewer); const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); - int rootGeneration = root ? root->generation() : 0; - setFocusData(rootGeneration, - frame ? (WebCore::Frame*) frame->framePointer() : 0, - node ? (WebCore::Node*) node->nodePointer() : 0, rx, ry, false); if (!node) { DBG_NAV_LOGD("no nodes found root=%p", root); - if (root) { - root->clearFocus(); - root->setCachedFocus(0, 0); - } - sendKitFocus(); - viewInvalidate(); - clearTextEntry(); - return; + 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)); } - DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - const CachedFrame* oldFrame = 0; - const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - bool oldNodeIsTextArea = focusIsTextArea(DontAllowNewer); - root->setCachedFocus(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); + sendMoveMouseIfLatest(); viewInvalidate(); - if (focusIsTextArea(DontAllowNewer)) - updateTextEntry(); - else if (oldNodeIsTextArea) - clearTextEntry(); } WebCore::IntRect getNavBounds() { CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) - return WebCore::IntRect(0, 0, 0, 0); - return root->rootHistory()->navBounds(); + return root ? root->rootHistory()->navBounds() : + WebCore::IntRect(0, 0, 0, 0); } void setNavBounds(const WebCore::IntRect& rect) @@ -1369,7 +796,7 @@ void markNodeInvalid(WebCore::Node* node) viewInvalidate(); } -bool motionUp(int x, int y, int slop, bool inval, bool retry) +bool motionUp(int x, int y, int slop) { bool pageScrolled = false; m_followedLink = false; @@ -1382,75 +809,42 @@ bool motionUp(int x, int y, int slop, bool inval, bool retry) const CachedNode* result = findAt(root, rect, &frame, &rx, &ry); if (!result) { DBG_NAV_LOGD("no nodes found root=%p", root); - int rootGeneration = 0; + setNavBounds(rect); if (root) { - root->clearFocus(); - rootGeneration = root->generation(); - if (!retry) { // scroll first time only - int dx = root->checkForCenter(x, y); - if (dx) { - scrollBy(dx, 0); - retry = true; // don't recompute later since we scrolled - pageScrolled = true; - } + root->clearCursor(); + int dx = root->checkForCenter(x, y); + if (dx) { + scrollBy(dx, 0); + pageScrolled = true; } } - sendMotionUp(rootGeneration, frame ? - (WebCore::Frame*) frame->framePointer() : 0, - 0, x, y, slop, retry); - if (inval) - viewInvalidate(); - if (!retry) { - MotionUpParams params; - params.d.m_trigger = CommonParams::MotionUpParams; - params.d.m_generation = m_generation; - params.m_x = x; - params.m_y = y; - params.m_slop = slop; - m_replay.add(params.d, sizeof(params)); - } + sendMotionUp(frame ? (WebCore::Frame*) frame->framePointer() : 0, + 0, x, y, slop); + viewInvalidate(); clearTextEntry(); return pageScrolled; } DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, result->index(), x, y, rx, ry); - // const CachedFrame* oldFrame = 0; - // const CachedNode* oldFocusNode = root->currentFocus(&oldFrame); - // WebCore::IntPoint focusLocation = root->focusLocation(); - bool oldNodeIsTextArea = !retry && focusIsTextArea(DontAllowNewer); - root->setCachedFocus(const_cast<CachedFrame*>(frame), + setNavBounds(WebCore::IntRect(rx, ry, 1, 1)); + root->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(result)); - bool newNodeIsTextArea = focusIsTextArea(DontAllowNewer); + bool newNodeIsTextInput = cursorIsTextInput(DontAllowNewer); CachedNodeType type = result->type(); - if (type == NORMAL_CACHEDNODETYPE || newNodeIsTextArea) { - sendMotionUp(root->generation(), + if (type == NORMAL_CACHEDNODETYPE || newNodeIsTextInput) { + sendMotionUp( frame ? (WebCore::Frame*) frame->framePointer() : 0, result ? (WebCore::Node*) result->nodePointer() : 0, rx, ry, - slop, retry); - if (inval) - viewInvalidate(); - if (!retry) { - MotionUpParams params; - params.d.m_trigger = CommonParams::MotionUpParams; - params.d.m_generation = m_generation; - params.m_x = x; - params.m_y = y; - params.m_slop = slop; - // params.c.setFocus(oldFocusNode, oldFrame, root, focusLocation); - m_replay.add(params.d, sizeof(params)); - } - } else if (inval) - viewInvalidate(); - if (newNodeIsTextArea) { + slop); + } + viewInvalidate(); + if (newNodeIsTextInput) { updateTextEntry(); displaySoftKeyboard(); } else { setFollowedLink(true); - if (type != NORMAL_CACHEDNODETYPE) { + if (type != NORMAL_CACHEDNODETYPE) overrideUrlLoading(result->getExport()); - } - if (oldNodeIsTextArea) - clearTextEntry(); } return pageScrolled; } @@ -1615,51 +1009,34 @@ void getSelectionCaret(SkPath* path) path->lineTo(0, height); } -void sendFinalFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) +void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) { DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); - m_viewImpl->gNotifyFocusMutex.lock(); - m_viewImpl->m_blockNotifyFocus = true; - m_viewImpl->gNotifyFocusMutex.unlock(); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendFinalFocus, + env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMoveMouse, (jint) framePtr, (jint) nodePtr, x, y); checkException(env); } -void sendKitFocus() +void sendMoveMouseIfLatest() { 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_sendKitFocus); + env->CallVoidMethod(m_javaGlue.object(env).get(), + m_javaGlue.m_sendMoveMouseIfLatest); checkException(env); } -void sendMotionUp(int buildGeneration, - WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y, int slop, - bool retry) +void sendMotionUp( + WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y, int slop) { m_viewImpl->m_touchGeneration = m_viewImpl->m_generation = ++m_generation; - DBG_NAV_LOGD("buildGeneration=%d m_generation=%d framePtr=%p nodePtr=%p" - " x=%d y=%d slop=%d", buildGeneration, + DBG_NAV_LOGD("m_generation=%d framePtr=%p nodePtr=%p x=%d y=%d slop=%d", m_generation, framePtr, nodePtr, x, y, slop); LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp, m_generation, - buildGeneration, (jint) framePtr, (jint) nodePtr, x, y, slop, retry); - checkException(env); -} - -void setFocusData(int buildGeneration, WebCore::Frame* framePtr, - WebCore::Node* nodePtr, int x, int y, bool ignoreNullFocus) -{ - m_viewImpl->m_moveGeneration = m_viewImpl->m_generation = ++m_generation; - DBG_NAV_LOGD("moveGeneration=%d buildGeneration=%d framePtr=%p nodePtr=%p" - " x=%d y=%d", m_generation, buildGeneration, framePtr, nodePtr, x, y); - 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_setFocusData, m_generation, - buildGeneration, (jint) framePtr, (jint) nodePtr, x, y, ignoreNullFocus); + env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp, + m_generation, (jint) framePtr, (jint) nodePtr, x, y, slop); checkException(env); } @@ -1727,54 +1104,37 @@ void scrollBy(int dx, int dy) 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_scrollBy, + env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_scrollBy, dx, dy, true); checkException(env); } -bool updateFocusNode(JNIEnv* env) +bool hasCursorNode() { CachedRoot* root = getFrameCache(DontAllowNewer); if (!root) { DBG_NAV_LOG("!root"); return false; } - const CachedFrame* cachedFrame = 0; - const CachedNode* cachedFocusNode = root->currentFocus(&cachedFrame); - if (!cachedFocusNode) { - DBG_NAV_LOG("!cachedFocusNode"); + const CachedNode* cursorNode = root->currentCursor(); + DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p)", + cursorNode ? cursorNode->index() : -1, + cursorNode ? cursorNode->nodePointer() : 0); + return cursorNode; +} + +bool hasFocusNode() +{ + CachedRoot* root = getFrameCache(DontAllowNewer); + if (!root) { + DBG_NAV_LOG("!root"); return false; } - DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p)", - cachedFocusNode->index(), - cachedFocusNode->nodePointer()); - jobject focusnode = env->GetObjectField(m_javaGlue.object(env).get(), m_javaGlue.m_focusNode); - LOG_ASSERT(focusnode, "Could not find WebView's FocusNode"); - - bool isTextArea = cachedFocusNode->isTextArea(); - bool isTextField = cachedFocusNode->isTextField(); - int maxLength; - jstring jName; - if (isTextField) { - maxLength = cachedFocusNode->maxLength(); - const WebCore::String& name = cachedFocusNode->name(); - jName = env->NewString((jchar*)name.characters(), name.length()); - } else { - maxLength = -1; - jName = 0; - } - WebCore::IntRect bounds = cachedFocusNode->bounds(); - WebCore::String value = cachedFocusNode->getExport(); - jstring val = !value.isEmpty() ? env->NewString((jchar *)value.characters(), value.length()) : 0; - env->CallVoidMethod(focusnode, m_javaGlue.m_setAll, isTextField, isTextArea, cachedFocusNode->isPassword(), - cachedFocusNode->isAnchor(), cachedFocusNode->isRtlText(), maxLength, cachedFocusNode->textSize(), - bounds.x(), bounds.y(), bounds.right(), bounds.bottom(), (int)(cachedFocusNode->nodePointer()), - (int)(cachedFrame->framePointer()), val, jName, root->textGeneration()); - env->DeleteLocalRef(val); - env->DeleteLocalRef(focusnode); - if (isTextField) - env->DeleteLocalRef(jName); - return true; + const CachedNode* focusNode = root->currentFocus(); + DBG_NAV_LOGD("focusNode=%d (nodePointer=%p)", + focusNode ? focusNode->index() : -1, + focusNode ? focusNode->nodePointer() : 0); + return focusNode; } void updateTextEntry() @@ -1814,10 +1174,14 @@ void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds) checkException(env); } +int moveGeneration() +{ + return m_viewImpl->m_moveGeneration; +} + private: // local state for WebView // private to getFrameCache(); other functions operate in a different thread CachedRoot* m_frameCacheUI; // navigation data ready for use - FocusReplay m_replay; WebViewCore* m_viewImpl; WebCore::Node* m_invalidNode; int m_generation; // associate unique ID with sent kit focus to match with ui @@ -1859,7 +1223,7 @@ static void nativeClearFocus(JNIEnv *env, jobject obj, int x, int y) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearFocus(x, y, true); + view->clearCursor(x, y, true); } static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl) @@ -1869,6 +1233,92 @@ static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl) //Release(obj); } +static jint nativeCursorFramePointer(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + if (!root) + return 0; + const CachedFrame* frame = 0; + (void) root->currentCursor(&frame); + return reinterpret_cast<int>(frame ? frame->framePointer() : 0); +} + +static const CachedNode* getCursorNode(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + return root ? root->currentCursor() : 0; +} + +static const CachedNode* getFocusNode(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + return root ? root->currentFocus() : 0; +} + +static jboolean nativeCursorMatchesFocus(JNIEnv *env, jobject obj) +{ + const CachedNode* cursor = getCursorNode(env, obj); + const CachedNode* focus = getFocusNode(env, obj); + return cursor && focus && cursor->nodePointer() == focus->nodePointer(); +} + +static jobject nativeCursorNodeBounds(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + WebCore::IntRect bounds = node ? node->getBounds() + : WebCore::IntRect(0, 0, 0, 0); + jclass rectClass = env->FindClass("android/graphics/Rect"); + jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); + jobject rect = env->NewObject(rectClass, init, bounds.x(), + bounds.y(), bounds.right(), bounds.bottom()); + return rect; +} + +static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + return reinterpret_cast<int>(node ? node->nodePointer() : 0); +} + +static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) +{ + int L, T, R, B; + GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); + return WebCore::IntRect(L, T, R - L, B - T); +} + +static bool nativeCursorIntersects(JNIEnv *env, jobject obj, jobject visRect) +{ + const CachedNode* node = getCursorNode(env, obj); + return node ? node->getBounds().intersects(jrect_to_webrect(env, visRect)) + : false; +} + +static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + return node ? node->isAnchor() : false; +} + +static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + return node ? node->isTextField() || node->isTextArea() : false; +} + +static jobject nativeCursorText(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getCursorNode(env, obj); + if (!node) + return 0; + WebCore::String value = node->getExport(); + return !value.isEmpty() ? env->NewString((jchar *)value.characters(), + value.length()) : 0; +} + static void nativeDebugDump(JNIEnv *env, jobject obj) { #if DUMP_NAV_CACHE @@ -1893,8 +1343,7 @@ static void nativeDrawMatches(JNIEnv *env, jobject obj, jobject canv) view->drawMatches(canvas); } -static void nativeDrawFocusRing(JNIEnv *env, jobject obj, - jobject canv) +static void nativeDrawCursorRing(JNIEnv *env, jobject obj, jobject canv) { SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); if (!canv) { @@ -1906,7 +1355,7 @@ static void nativeDrawFocusRing(JNIEnv *env, jobject obj, DBG_NAV_LOG("!view"); return; } - view->drawFocusRing(canvas); + view->drawCursorRing(canvas); } static void nativeDrawSelection(JNIEnv *env, jobject obj, @@ -1954,6 +1403,79 @@ static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y) return ret; } +static bool nativeFocusIsPassword(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->isPassword() : false; +} + +static bool nativeFocusIsRtlText(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->isRtlText() : false; +} + +static bool nativeFocusIsTextField(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->isTextField() : false; +} + +static bool nativeFocusIsTextInput(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->isTextField() || node->isTextArea() : false; +} + +static jint nativeFocusMaxLength(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->maxLength() : false; +} + +static jobject nativeFocusName(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + if (!node) + return 0; + const WebCore::String& name = node->name(); + return env->NewString((jchar*)name.characters(), name.length()); +} + +static jobject nativeFocusNodeBounds(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + WebCore::IntRect bounds = node ? node->getBounds() + : WebCore::IntRect(0, 0, 0, 0); + jclass rectClass = env->FindClass("android/graphics/Rect"); + jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); + jobject rect = env->NewObject(rectClass, init, bounds.x(), + bounds.y(), bounds.right(), bounds.bottom()); + return rect; +} + +static jint nativeFocusNodePointer(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return reinterpret_cast<int>(node ? node->nodePointer() : 0); +} + +static jobject nativeFocusText(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + if (!node) + return 0; + WebCore::String value = node->getExport(); + return !value.isEmpty() ? env->NewString((jchar *)value.characters(), + value.length()) : 0; +} + +static jint nativeFocusTextSize(JNIEnv *env, jobject obj) +{ + const CachedNode* node = getFocusNode(env, obj); + return node ? node->textSize() : 0; +} + static bool nativeFocusNodeWantsKeyEvents(JNIEnv* env, jobject jwebview) { WebView* view = GET_NATIVE_VIEW(env, jwebview); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); @@ -1967,13 +1489,6 @@ static void nativeInstrumentReport(JNIEnv *env, jobject obj) #endif } -static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) -{ - int L, T, R, B; - GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B); - return WebCore::IntRect(L, T, R - L, B - T); -} - static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -1982,6 +1497,13 @@ static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) view->selectBestAt(rect); } +static jint nativeTextGeneration(JNIEnv *env, jobject obj) +{ + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + return root ? root->textGeneration() : 0; +} + static void nativeMarkNodeInvalid(JNIEnv *env, jobject obj, int node) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -1994,37 +1516,33 @@ static bool nativeMotionUp(JNIEnv *env, jobject obj, { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->motionUp(x, y, slop, true, false); + return view->motionUp(x, y, slop); } -static bool nativeUpdateFocusNode(JNIEnv *env, jobject obj) +static bool nativeHasCursorNode(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->updateFocusNode(env); + return GET_NATIVE_VIEW(env, obj)->hasCursorNode(); } -static bool nativeMoveFocus(JNIEnv *env, jobject obj, - int key, int count, bool ignoreScroll) +static bool nativeHasFocusNode(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->moveFocus(key, count, ignoreScroll, true, 0, 0); + return GET_NATIVE_VIEW(env, obj)->hasFocusNode(); } -static void nativeNotifyFocusSet(JNIEnv *env, jobject obj, bool inEditingMode) +static bool nativeMoveFocus(JNIEnv *env, jobject obj, + int key, int count, bool ignoreScroll) { WebView* view = GET_NATIVE_VIEW(env, obj); + DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->notifyFocusSet((WebView::FrameCachePermission) inEditingMode); + return view->moveCursor(key, count, ignoreScroll, true, 0, 0); } static void nativeRecomputeFocus(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->recomputeFocus(); +// view->recomputeFocus(); } static void nativeRecordButtons(JNIEnv* env, jobject obj, bool hasFocus, @@ -2035,13 +1553,6 @@ static void nativeRecordButtons(JNIEnv* env, jobject obj, bool hasFocus, view->nativeRecordButtons(hasFocus, pressed, invalidate); } -static void nativeResetFocus(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->resetFocus(); -} - static void nativeSetFindIsDown(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -2063,7 +1574,7 @@ static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) view->setHeightCanMeasure(measure); } -static jobject nativeGetFocusRingBounds(JNIEnv *env, jobject obj) +static jobject nativeGetCursorRingBounds(JNIEnv *env, jobject obj) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); @@ -2072,34 +1583,12 @@ static jobject nativeGetFocusRingBounds(JNIEnv *env, jobject obj) jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); LOG_ASSERT(init, "Could not find constructor for Rect"); WebCore::IntRect webRect; - view->focusRingBounds(&webRect); + view->cursorRingBounds(&webRect); jobject rect = env->NewObject(rectClass, init, webRect.x(), webRect.y(), webRect.right(), webRect.bottom()); return rect; } -static jobject nativeGetNavBounds(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - LOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - LOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect = view->getNavBounds(); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.right(), webRect.bottom()); - return rect; -} - -static void nativeSetNavBounds(JNIEnv *env, jobject obj, jobject jrect) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->setNavBounds(rect); -} - static int nativeFindAll(JNIEnv *env, jobject obj, jstring findLower, jstring findUpper) { @@ -2122,7 +1611,7 @@ static int nativeFindAll(JNIEnv *env, jobject obj, jstring findLower, WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in nativeFindAll"); view->setFindIsUp(true); - CachedRoot* root = view->getFrameCache(WebView::AllowNewer, false); + CachedRoot* root = view->getFrameCache(WebView::AllowNewer); if (!root) { env->ReleaseStringChars(findLower, findLowerChars); env->ReleaseStringChars(findUpper, findUpperChars); @@ -2189,6 +1678,11 @@ static void nativeDestroy(JNIEnv *env, jobject obj) delete view; } +static int nativeMoveGeneration(JNIEnv *env, jobject obj) +{ + return GET_NATIVE_VIEW(env, obj)->moveGeneration(); +} + static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y, bool ex) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -2248,32 +1742,76 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) * JNI registration */ static JNINativeMethod gJavaWebViewMethods[] = { - { "nativeFindAll", "(Ljava/lang/String;Ljava/lang/String;)I", - (void*) nativeFindAll }, - { "nativeFindNext", "(Z)V", - (void*) nativeFindNext }, { "nativeClearFocus", "(II)V", (void*) nativeClearFocus }, { "nativeCreate", "(I)V", (void*) nativeCreate }, + { "nativeCursorFramePointer", "()I", + (void*) nativeCursorFramePointer }, + { "nativeCursorMatchesFocus", "()Z", + (void*) nativeCursorMatchesFocus }, + { "nativeCursorNodeBounds", "()Landroid/graphics/Rect;", + (void*) nativeCursorNodeBounds }, + { "nativeCursorNodePointer", "()I", + (void*) nativeCursorNodePointer }, + { "nativeCursorIntersects", "(Landroid/graphics/Rect;)Z", + (void*) nativeCursorIntersects }, + { "nativeCursorIsAnchor", "()Z", + (void*) nativeCursorIsAnchor }, + { "nativeCursorIsTextInput", "()Z", + (void*) nativeCursorIsTextInput }, + { "nativeCursorText", "()Ljava/lang/String;", + (void*) nativeCursorText }, { "nativeDebugDump", "()V", (void*) nativeDebugDump }, { "nativeDestroy", "()V", (void*) nativeDestroy }, + { "nativeDrawCursorRing", "(Landroid/graphics/Canvas;)V", + (void*) nativeDrawCursorRing }, { "nativeDrawMatches", "(Landroid/graphics/Canvas;)V", (void*) nativeDrawMatches }, - { "nativeDrawFocusRing", "(Landroid/graphics/Canvas;)V", - (void*) nativeDrawFocusRing }, { "nativeDrawSelection", "(Landroid/graphics/Canvas;IIZ)V", (void*) nativeDrawSelection }, { "nativeDrawSelectionRegion", "(Landroid/graphics/Canvas;)V", (void*) nativeDrawSelectionRegion }, - { "nativeUpdateFocusNode", "()Z", - (void*) nativeUpdateFocusNode }, - { "nativeGetFocusRingBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetFocusRingBounds }, - { "nativeGetNavBounds", "()Landroid/graphics/Rect;", - (void*) nativeGetNavBounds }, + { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", + (void*) nativeDumpDisplayTree }, + { "nativeFindAll", "(Ljava/lang/String;Ljava/lang/String;)I", + (void*) nativeFindAll }, + { "nativeFindNext", "(Z)V", + (void*) nativeFindNext }, + { "nativeFocusIsPassword", "()Z", + (void*) nativeFocusIsPassword }, + { "nativeFocusIsRtlText", "()Z", + (void*) nativeFocusIsRtlText }, + { "nativeFocusIsTextField", "()Z", + (void*) nativeFocusIsTextField }, + { "nativeFocusIsTextInput", "()Z", + (void*) nativeFocusIsTextInput }, + { "nativeFocusMaxLength", "()I", + (void*) nativeFocusMaxLength }, + { "nativeFocusName", "()Ljava/lang/String;", + (void*) nativeFocusName }, + { "nativeFocusNodeBounds", "()Landroid/graphics/Rect;", + (void*) nativeFocusNodeBounds }, + { "nativeFocusNodePointer", "()I", + (void*) nativeFocusNodePointer }, + { "nativeFocusText", "()Ljava/lang/String;", + (void*) nativeFocusText }, + { "nativeFocusTextSize", "()I", + (void*) nativeFocusTextSize }, + { "nativeFocusNodeWantsKeyEvents", "()Z", + (void*)nativeFocusNodeWantsKeyEvents }, + { "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;", + (void*) nativeGetCursorRingBounds }, + { "nativeGetSelection", "()Landroid/graphics/Region;", + (void*) nativeGetSelection }, + { "nativeHasCursorNode", "()Z", + (void*) nativeHasCursorNode }, + { "nativeHasFocusNode", "()Z", + (void*) nativeHasFocusNode }, + { "nativeImageURI", "(II)Ljava/lang/String;", + (void*) nativeImageURI }, { "nativeInstrumentReport", "()V", (void*) nativeInstrumentReport }, { "nativeMarkNodeInvalid", "(I)V", @@ -2282,14 +1820,14 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeMotionUp }, { "nativeMoveFocus", "(IIZ)Z", (void*) nativeMoveFocus }, - { "nativeNotifyFocusSet", "(Z)V", - (void*) nativeNotifyFocusSet }, + { "nativeMoveGeneration", "()I", + (void*) nativeMoveGeneration }, + { "nativeMoveSelection", "(IIZ)V", + (void*) nativeMoveSelection }, { "nativeRecomputeFocus", "()V", (void*) nativeRecomputeFocus }, { "nativeRecordButtons", "(ZZZ)V", (void*) nativeRecordButtons }, - { "nativeResetFocus", "()V", - (void*) nativeResetFocus }, { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V", (void*) nativeSelectBestAt }, { "nativeSetFindIsDown", "()V", @@ -2298,20 +1836,10 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeSetFollowedLink }, { "nativeSetHeightCanMeasure", "(Z)V", (void*) nativeSetHeightCanMeasure }, - { "nativeSetNavBounds", "(Landroid/graphics/Rect;)V", - (void*) nativeSetNavBounds }, - { "nativeImageURI", "(II)Ljava/lang/String;", - (void*) nativeImageURI }, - { "nativeFocusNodeWantsKeyEvents", "()Z", - (void*)nativeFocusNodeWantsKeyEvents }, + { "nativeTextGeneration", "()I", + (void*) nativeTextGeneration }, { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", - (void*) nativeUpdateCachedTextfield }, - { "nativeMoveSelection", "(IIZ)V", - (void*) nativeMoveSelection }, - { "nativeGetSelection", "()Landroid/graphics/Region;", - (void*) nativeGetSelection }, - { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", - (void*) nativeDumpDisplayTree } + (void*) nativeUpdateCachedTextfield } }; int register_webview(JNIEnv* env) |