diff options
Diffstat (limited to 'WebKit')
-rw-r--r-- | WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp | 63 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/ChromeClientAndroid.h | 26 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/PlatformBridge.cpp | 19 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 94 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 7 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 2 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 50 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.h | 2 | ||||
-rw-r--r-- | WebKit/android/nav/CachedInput.cpp | 15 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 23 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.h | 7 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 142 |
12 files changed, 367 insertions, 83 deletions
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index 8390cbc..f14c2c1 100644 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -38,6 +38,7 @@ #include "FrameLoader.h" #include "FrameView.h" #include "Geolocation.h" +#include "GraphicsLayerAndroid.h" #include "Page.h" #include "Screen.h" #include "ScriptController.h" @@ -49,6 +50,68 @@ namespace android { +#if USE(ACCELERATED_COMPOSITING) + +void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client) +{ + m_syncTimer.stop(); + compositingLayerSync(); +} + +void ChromeClientAndroid::compositingLayerSync() +{ + if (!m_rootGraphicsLayer) { + scheduleCompositingLayerSync(); + return; + } + + if (m_webFrame) { + FrameView* frameView = m_webFrame->page()->mainFrame()->view(); + if (frameView && !frameView->layoutPending() && !frameView->needsLayout()) { + frameView->syncCompositingStateRecursive(); + GraphicsLayerAndroid* androidGraphicsLayer = + static_cast<GraphicsLayerAndroid*>(m_rootGraphicsLayer); + if (androidGraphicsLayer) + androidGraphicsLayer->sendImmediateRepaint(); + return; + } + } + if (m_askToDrawAgain) { + m_askToDrawAgain = false; + scheduleCompositingLayerSync(); + } +} + +void ChromeClientAndroid::scheduleCompositingLayerSync() +{ + if (!m_syncTimer.isActive()) + m_syncTimer.startOneShot(0.001); // 1ms + else + m_askToDrawAgain = true; +} + +void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization() +{ + // This should not be needed +} + +void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame* frame, WebCore::GraphicsLayer* layer) +{ + m_rootGraphicsLayer = layer; + if (!layer) { + WebViewCore::getWebViewCore(frame->view())->setRootLayer(0); + return; + } + WebCore::GraphicsLayerAndroid* androidGraphicsLayer = static_cast<GraphicsLayerAndroid*>(layer); + if (frame && frame->view() && androidGraphicsLayer) { + androidGraphicsLayer->setFrame(frame); + WebCore::LayerAndroid* androidLayer = new LayerAndroid(androidGraphicsLayer->contentLayer()); + WebViewCore::getWebViewCore(frame->view())->setRootLayer((int)androidLayer); + } +} + +#endif + void ChromeClientAndroid::setWebFrame(android::WebFrame* webframe) { Release(m_webFrame); diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h index 7396997..45dd078 100644 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h +++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h @@ -43,7 +43,13 @@ namespace android { class ChromeClientAndroid : public ChromeClient { public: - ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0) { } + ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0) +#if USE(ACCELERATED_COMPOSITING) + , m_rootGraphicsLayer(0) + , m_askToDrawAgain(false) + , m_syncTimer(this, &ChromeClientAndroid::syncTimerFired) +#endif + { } virtual void chromeDestroyed(); virtual void setWindowRect(const FloatRect&); @@ -149,13 +155,27 @@ namespace android { // Android-specific void setWebFrame(android::WebFrame* webframe); void wakeUpMainThreadWithNewQuota(long newQuota); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g); + virtual void setNeedsOneShotDrawingSynchronization(); + virtual void scheduleCompositingLayerSync(); + void compositingLayerSync(); + void syncTimerFired(Timer<ChromeClientAndroid>*); +#endif + private: android::WebFrame* m_webFrame; + // The Geolocation permissions manager. + OwnPtr<GeolocationPermissions> m_geolocationPermissions; +#if USE(ACCELERATED_COMPOSITING) + WebCore::GraphicsLayer* m_rootGraphicsLayer; + bool m_askToDrawAgain; + Timer<ChromeClientAndroid> m_syncTimer; +#endif WTF::ThreadCondition m_quotaThreadCondition; WTF::Mutex m_quotaThreadLock; long m_newQuota; - // The Geolocation permissions manager. - OwnPtr<GeolocationPermissions> m_geolocationPermissions; }; } diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp index e4fe4ce..e93d3da 100644 --- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -28,11 +28,28 @@ #include "JavaSharedClient.h" #include "KeyGeneratorClient.h" +#include "WebViewCore.h" using namespace android; namespace WebCore { +#if USE(ACCELERATED_COMPOSITING) + +void PlatformBridge::setRootLayer(const WebCore::FrameView* view, int layer) +{ + android::WebViewCore* core = android::WebViewCore::getWebViewCore(view); + core->setRootLayer(layer); +} + +void PlatformBridge::immediateRepaint(const WebCore::FrameView* view) +{ + android::WebViewCore* core = android::WebViewCore::getWebViewCore(view); + core->immediateRepaint(); +} + +#endif // USE(ACCELERATED_COMPOSITING) + WTF::Vector<String> PlatformBridge::getSupportedKeyStrengthList() { KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient(); @@ -51,4 +68,4 @@ String PlatformBridge::getSignedPublicKeyAndChallengeString(unsigned index, cons return client->getSignedPublicKeyAndChallengeString(index, challenge, url); } -}
\ No newline at end of file +} diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 896d902..ee1f880 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -57,6 +57,7 @@ #include "HTMLElement.h" #include "HTMLImageElement.h" #include "HTMLInputElement.h" +#include "HTMLLabelElement.h" #include "HTMLMapElement.h" #include "HTMLNames.h" #include "HTMLOptGroupElement.h" @@ -68,6 +69,7 @@ #include "KeyboardCodes.h" #include "Navigator.h" #include "Node.h" +#include "NodeList.h" #include "Page.h" #include "PageGroup.h" #include "PlatformKeyboardEvent.h" @@ -130,6 +132,11 @@ FILE* gRenderTreeFile = 0; #include "TimeCounter.h" #endif +#if USE(ACCELERATED_COMPOSITING) +#include "GraphicsLayerAndroid.h" +#include "RenderLayerCompositor.h" +#endif + /* We pass this flag when recording the actual content, so that we don't spend time actually regionizing complex path clips, when all we really want to do is record them. @@ -195,6 +202,8 @@ struct WebViewCore::JavaGlue { jmethodID m_updateViewport; jmethodID m_sendNotifyProgressFinished; jmethodID m_sendViewInvalidate; + jmethodID m_sendImmediateRepaint; + jmethodID m_setRootLayer; jmethodID m_updateTextfield; jmethodID m_updateTextSelection; jmethodID m_clearTextEntry; @@ -277,6 +286,8 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V"); m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V"); + m_javaGlue->m_sendImmediateRepaint = GetJMethod(env, clazz, "sendImmediateRepaint", "()V"); + m_javaGlue->m_setRootLayer = GetJMethod(env, clazz, "setRootLayer", "(I)V"); m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V"); m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V"); m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); @@ -879,6 +890,28 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate) checkException(env); } +#if USE(ACCELERATED_COMPOSITING) + +void WebViewCore::immediateRepaint() +{ + 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_sendImmediateRepaint); + checkException(env); +} + +void WebViewCore::setRootLayer(int layer) +{ + JNIEnv* env = JSC::Bindings::getJNIEnv(); + env->CallVoidMethod(m_javaGlue->object(env).get(), + m_javaGlue->m_setRootLayer, + layer); + checkException(env); +} + +#endif // USE(ACCELERATED_COMPOSITING) + void WebViewCore::contentDraw() { JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1156,14 +1189,14 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, r->setNeedsLayoutAndPrefWidthsRecalc(); m_mainFrame->view()->forceLayout(); // scroll to restore current screen center - if (!node) - 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(), - newBounds.width(), newBounds.height()); - scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(), - false); + if (node) { + const WebCore::IntRect& newBounds = node->getRect(); + DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d," + "h=%d,ns=%d)", newBounds.x(), newBounds.y(), + newBounds.width(), newBounds.height()); + scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(), + false); + } } } @@ -1237,6 +1270,22 @@ WebCore::String WebViewCore::retrieveAnchorText(WebCore::Frame* frame, WebCore:: return anchor ? anchor->text() : WebCore::String(); } +WebCore::String WebViewCore::requestLabel(WebCore::Frame* frame, + WebCore::Node* node) +{ + if (CacheBuilder::validNode(m_mainFrame, frame, node)) { + RefPtr<WebCore::NodeList> list = node->document()->getElementsByTagName("label"); + unsigned length = list->length(); + for (unsigned i = 0; i < length; i++) { + WebCore::HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>( + list->item(i)); + if (label->correspondingControl() == node) + return label->innerHTML(); + } + } + return WebCore::String(); +} + void WebViewCore::updateCacheOnNodeChange() { gCursorBoundsMutex.lock(); @@ -1267,6 +1316,12 @@ void WebViewCore::updateCacheOnNodeChange() void WebViewCore::updateFrameCache() { +#if USE(ACCELERATED_COMPOSITING) + ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>( + mainFrame()->page()->chrome()->client()); + chromeC->scheduleCompositingLayerSync(); +#endif + if (!m_frameCacheOutOfDate) { DBG_NAV_LOG("!m_frameCacheOutOfDate"); return; @@ -2098,6 +2153,16 @@ int WebViewCore::handleTouchEvent(int action, int x, int y) { int preventDefault = 0; +#if USE(ACCELERATED_COMPOSITING) + RenderView* contentRenderer = m_mainFrame->contentRenderer(); + GraphicsLayerAndroid* rootLayer = 0; + if (contentRenderer) + rootLayer = static_cast<GraphicsLayerAndroid*>( + contentRenderer->compositor()->rootPlatformLayer()); + if (rootLayer) + rootLayer->pauseDisplay(true); +#endif + #if ENABLE(TOUCH_EVENTS) // Android WebCore::TouchEventType type = WebCore::TouchEventCancel; switch (action) { @@ -2125,6 +2190,10 @@ int WebViewCore::handleTouchEvent(int action, int x, int y) preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te); #endif +#if USE(ACCELERATED_COMPOSITING) + if (rootLayer) + rootLayer->pauseDisplay(false); +#endif return preventDefault; } @@ -2677,6 +2746,13 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) return ret; } +static jstring RequestLabel(JNIEnv *env, jobject obj, int framePointer, + int nodePointer) +{ + return WebCoreStringToJString(env, GET_NATIVE_VIEW(env, obj)->requestLabel( + (WebCore::Frame*) framePointer, (WebCore::Node*) nodePointer)); +} + static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj) { GET_NATIVE_VIEW(env, obj)->updateFrameCacheIfLoading(); @@ -3357,6 +3433,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { { "nativeResume", "()V", (void*) Resume }, { "nativeFreeMemory", "()V", (void*) FreeMemory }, { "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags }, + { "nativeRequestLabel", "(II)Ljava/lang/String;", + (void*) RequestLabel }, { "nativeUpdateFrameCacheIfLoading", "()V", (void*) UpdateFrameCacheIfLoading }, { "nativeProvideVisitedHistory", "([Ljava/lang/String;)V", diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 4c8de78..912b8e6 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -126,6 +126,11 @@ namespace android { */ void contentDraw(); +#if USE(ACCELERATED_COMPOSITING) + void immediateRepaint(); + void setRootLayer(int layer); +#endif + /** Invalidate the view/screen, NOT the content/DOM, but expressed in * content/DOM coordinates (i.e. they need to eventually be scaled, * by webview into view.java coordinates @@ -241,7 +246,7 @@ namespace android { WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node); WebCore::String retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node); - + WebCore::String requestLabel(WebCore::Frame* , WebCore::Node* ); WebCore::String getSelection(SkRegion* ); // Create a single picture to represent the drawn DOM (used by navcache) diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index ce78c29..c4c25db 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -1099,7 +1099,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, goto keepTextNode; } if (node->hasTagName(WebCore::HTMLNames::inputTag)) { - HTMLInputElement* input = (HTMLInputElement*) node; + HTMLInputElement* input = static_cast<HTMLInputElement*>(node); HTMLInputElement::InputType inputType = input->inputType(); if (input->isTextField()) { type = TEXT_INPUT_CACHEDNODETYPE; diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index a95a401..299dc53 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -441,14 +441,18 @@ const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const } const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, - int* best, const CachedFrame** framePtr, int* x, int* y) const + const CachedFrame** framePtr, int* x, int* y) const { - const CachedNode* result = NULL; - int rectWidth = rect.width(); - WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1), - rect.y() + (rect.height() >> 1)); mRoot->setupScrolledBounds(); - for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { + for (const CachedFrame* frame = mCachedFrames.end() - 1; + frame != mCachedFrames.begin() - 1; frame--) { + const CachedNode* frameResult = frame->findBestHitAt(rect, + framePtr, x, y); + if (NULL != frameResult) + return frameResult; + } + for (const CachedNode* test = mCachedNodes.end() - 1; + test != mCachedNodes.begin() - 1; test--) { if (test->disabled()) continue; const WebCore::IntRect& testRect = test->hitBounds(); @@ -459,29 +463,19 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, testData.mMouseBounds = testData.mNodeBounds = testRect; if (mRoot->maskIfHidden(&testData) == true) continue; - const WebCore::IntRect& bounds = testData.mMouseBounds; - 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) - continue; - *best = distance; - result = test; - *framePtr = this; - 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(); - frame != mCachedFrames.end(); frame++) { - const CachedNode* frameResult = frame->findBestHitAt(rect, best, - framePtr, x, y); - if (NULL != frameResult) - result = frameResult; + for (unsigned i = 0; i < test->cursorRings().size(); i++) { + const WebCore::IntRect& cursorRect = test->cursorRings().at(i); + if (cursorRect.intersects(rect)) { + WebCore::IntRect intersection(cursorRect); + intersection.intersect(rect); + *x = intersection.x() + (intersection.width() >> 1); + *y = intersection.y() + (intersection.height() >> 1); + *framePtr = this; + return test; + } + } } - return result; + return NULL; } void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h index f0996f7..7a00539 100644 --- a/WebKit/android/nav/CachedFrame.h +++ b/WebKit/android/nav/CachedFrame.h @@ -85,7 +85,7 @@ public: int* y, bool checkForHidden) const; const CachedFrame* findBestFrameAt(int x, int y) const; const CachedNode* findBestHitAt(const WebCore::IntRect& , - int* best, const CachedFrame** , int* x, int* y) const; + const CachedFrame** , int* x, int* y) const; void finishInit(); CachedFrame* firstChild() { return mCachedFrames.begin(); } const CachedFrame* firstChild() const { return mCachedFrames.begin(); } diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp index 52d2066..d7b96e3 100644 --- a/WebKit/android/nav/CachedInput.cpp +++ b/WebKit/android/nav/CachedInput.cpp @@ -38,18 +38,23 @@ CachedInput* CachedInput::Debug::base() const { return nav; } -void CachedInput::Debug::print() const -{ - CachedInput* b = base(); +static void printWebCoreString(const char* label, + const WebCore::String& string) { char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), "// char* mName=\""); - const UChar* ch = b->mName.characters(); + size_t index = snprintf(scratch, sizeof(scratch), label); + const UChar* ch = string.characters(); while (ch && *ch && index < sizeof(scratch)) { UChar c = *ch++; if (c < ' ' || c >= 0x7f) c = ' '; scratch[index++] = c; } DUMP_NAV_LOGD("%.*s\"\n", index, scratch); +} + +void CachedInput::Debug::print() const +{ + CachedInput* b = base(); + printWebCoreString("// char* mName=\"", b->mName); DUMP_NAV_LOGD("// void* mForm=%p;", b->mForm); DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength); DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize); diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index 2354ebc..e783eae 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -756,14 +756,17 @@ bool CachedRoot::checkRings(const WTF::Vector<WebCore::IntRect>& rings, return ringCheck.success(); } -CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const +CachedRoot::ImeAction CachedRoot::currentTextFieldAction() const { - const CachedFrame* cursorFrame; - const CachedNode* cursor = currentCursor(&cursorFrame); - if (!cursor) { - // Error case. The cursor has no action, because there is no node under - // the cursor - return FAILURE; + const CachedFrame* currentFrame; + const CachedNode* current = currentCursor(¤tFrame); + if (!current) { + // Although the cursor is not on a textfield, a textfield may have + // focus. Find the action for that textfield. + current = currentFocus(¤tFrame); + if (!current) + // Error case. No cursor and no focus. + return FAILURE; } const CachedNode* firstTextfield = nextTextField(0, 0, false); if (!firstTextfield) { @@ -773,8 +776,8 @@ CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const // Now find the next textfield/area starting with the cursor const CachedFrame* potentialFrame; const CachedNode* potentialNext - = cursorFrame->nextTextField(cursor, &potentialFrame, true); - if (potentialNext && cursorFrame->textInput(cursor)->formPointer() + = currentFrame->nextTextField(current, &potentialFrame, true); + if (potentialNext && currentFrame->textInput(current)->formPointer() == potentialFrame->textInput(potentialNext)->formPointer()) { // There is a textfield/area after the cursor in the same form, // so the textfield under the cursor should have the NEXT action @@ -797,7 +800,7 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, 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); + node = findBestHitAt(rect, framePtr, x, y); DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), node == NULL ? NULL : node->nodePointer()); } diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h index 435937a..5fdf8df 100644 --- a/WebKit/android/nav/CachedRoot.h +++ b/WebKit/android/nav/CachedRoot.h @@ -52,11 +52,12 @@ public: void checkForJiggle(int* ) const; bool checkRings(const WTF::Vector<WebCore::IntRect>& rings, const WebCore::IntRect& bounds) const; - WebCore::IntPoint cursorLocation() const; // This method returns the desired ImeAction for the textfield where the - // mouse cursor currently is. If the mouse cursor is not on a textfield, + // mouse cursor currently is, or where the focus is if there is no mouse + // cursor. If the mouse cursor is not on a textfield, // it will return FAILURE - ImeAction cursorTextFieldAction() const; + ImeAction currentTextFieldAction() const; + WebCore::IntPoint cursorLocation() const; int documentHeight() { return mContents.height(); } int documentWidth() { return mContents.width(); } const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index c29cb22..1267647 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -28,6 +28,7 @@ #include <config.h> #include "android_graphics.h" +#include "AndroidAnimation.h" #include "AndroidLog.h" #include "AtomicString.h" #include "CachedFrame.h" @@ -39,6 +40,7 @@ #include "HTMLInputElement.h" #include "IntPoint.h" #include "IntRect.h" +#include "LayerAndroid.h" #include "Node.h" #include "PlatformGraphicsContext.h" #include "PlatformString.h" @@ -104,11 +106,11 @@ struct JavaGlue { jmethodID m_sendMoveMouse; jmethodID m_sendMoveMouseIfLatest; jmethodID m_sendMotionUp; + jmethodID m_domChangedFocus; jmethodID m_getScaledMaxXScroll; jmethodID m_getScaledMaxYScroll; jmethodID m_getVisibleRect; jmethodID m_rebuildWebTextView; - jmethodID m_setOkayToNotMatch; jmethodID m_displaySoftKeyboard; jmethodID m_viewInvalidate; jmethodID m_viewInvalidateRect; @@ -134,11 +136,11 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V"); m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V"); m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V"); + m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()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;"); m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V"); - m_javaGlue.m_setOkayToNotMatch = GetJMethod(env, clazz, "setOkayNotToMatch", "()V"); m_javaGlue.m_displaySoftKeyboard = GetJMethod(env, clazz, "displaySoftKeyboard", "(Z)V"); m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V"); @@ -613,6 +615,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer) } DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true"); bool hadCursor = m_frameCacheUI && m_frameCacheUI->currentCursor(); + const CachedNode* oldFocus = m_frameCacheUI ? m_frameCacheUI->currentFocus() : 0; m_viewImpl->gFrameCacheMutex.lock(); delete m_frameCacheUI; delete m_navPictureUI; @@ -623,6 +626,19 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer) m_viewImpl->m_navPictureKit = 0; m_viewImpl->gFrameCacheMutex.unlock(); fixCursor(); + if (oldFocus && m_frameCacheUI) { + const CachedNode* newFocus = m_frameCacheUI->currentFocus(); + if (newFocus && oldFocus != newFocus && newFocus->isTextInput() + && oldFocus->isTextInput() + && newFocus != m_frameCacheUI->currentCursor()) { + // The focus has changed. We may need to update things. + 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_domChangedFocus); + checkException(env); + } + } if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) viewInvalidate(); // redraw in case cursor ring is still visible return m_frameCacheUI; @@ -839,7 +855,7 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll) void notifyProgressFinished() { DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); - rebuildWebTextView(false); + rebuildWebTextView(); #if DEBUG_NAV_UI if (m_frameCacheUI) { const CachedNode* focus = m_frameCacheUI->currentFocus(); @@ -951,7 +967,9 @@ bool motionUp(int x, int y, int slop) } DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, result->index(), x, y, rx, ry); - setNavBounds(WebCore::IntRect(rx, ry, 1, 1)); + WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1); + setNavBounds(navBounds); + root->rootHistory()->setMouseBounds(navBounds); updateCursorBounds(root, frame, result); root->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(result)); @@ -964,7 +982,7 @@ bool motionUp(int x, int y, int slop) viewInvalidate(); if (result->isTextInput()) { bool isReadOnly = frame->textInput(result)->isReadOnly(); - rebuildWebTextView(true); + rebuildWebTextView(); if (!isReadOnly) displaySoftKeyboard(true); } else { @@ -1277,7 +1295,7 @@ bool hasFocusNode() return focusNode; } -void rebuildWebTextView(bool needNotMatchFocus) +void rebuildWebTextView() { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject obj = m_javaGlue.object(env); @@ -1287,10 +1305,6 @@ void rebuildWebTextView(bool needNotMatchFocus) return; env->CallVoidMethod(obj.get(), m_javaGlue.m_rebuildWebTextView); checkException(env); - if (needNotMatchFocus) { - env->CallVoidMethod(obj.get(), m_javaGlue.m_setOkayToNotMatch); - checkException(env); - } } void displaySoftKeyboard(bool isTextView) @@ -1592,6 +1606,86 @@ static void nativeDrawMatches(JNIEnv *env, jobject obj, jobject canv) view->drawMatches(canvas); } +static void nativeDrawLayers(JNIEnv *env, jobject obj, + jint layer, jfloat scrollX, jfloat scrollY, + jfloat scale, jobject canv) +{ + if (!env) + return; + if (!layer) + return; + if (!canv) + return; + +#if USE(ACCELERATED_COMPOSITING) + LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer); + SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); + if (canvas) + layerImpl->paintOn(scrollX, scrollY, scale, canvas); +#endif +} + +static void nativeUpdateLayers(JNIEnv *env, jobject obj, + jint layer, jint updates) +{ + if (!env) + return; + if (!layer) + return; + if (!updates) + return; + +#if USE(ACCELERATED_COMPOSITING) + Vector<RefPtr<AndroidAnimationValue> >* updatesImpl = + reinterpret_cast<Vector<RefPtr<AndroidAnimationValue> >* >(updates); + if (updatesImpl) { + for (unsigned int i = 0; i < updatesImpl->size(); i++) + (updatesImpl->at(i))->apply(); + delete updatesImpl; + } +#endif +} + +static bool nativeLayersHaveAnimations(JNIEnv *env, jobject obj, jint layer) +{ + if (!env) + return false; + if (!layer) + return false; +#if USE(ACCELERATED_COMPOSITING) + LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer); + return layerImpl->hasAnimations(); +#else + return false; +#endif +} + +static int nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint layer) +{ + if (!env) + return 0; + if (!layer) + return 0; +#if USE(ACCELERATED_COMPOSITING) + LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer); + return reinterpret_cast<int>(layerImpl->evaluateAnimations()); +#else + return 0; +#endif +} + +static void nativeDestroyLayer(JNIEnv *env, jobject obj, jint layer) +{ + if (!env) + return; + if (!layer) + return; +#if USE(ACCELERATED_COMPOSITING) + LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer); + delete layerImpl; +#endif +} + static void nativeDrawCursorRing(JNIEnv *env, jobject obj, jobject canv) { SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv); @@ -1767,12 +1861,6 @@ static int nativeFocusCandidateType(JNIEnv *env, jobject obj) } } -static bool nativeFocusCandidateIsPlugin(JNIEnv *env, jobject obj) -{ - const CachedNode* node = getFocusCandidate(env, obj); - return node ? node->isPlugin() : false; -} - static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj) { const CachedNode* node = getFocusNode(env, obj); @@ -2002,11 +2090,13 @@ static void nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); if (!root) return; - const CachedNode* cursor = root->currentCursor(); - if (!cursor) + const CachedNode* current = root->currentCursor(); + if (!current) + current = root->currentFocus(); + if (!current) return; const CachedFrame* frame; - const CachedNode* next = root->nextTextField(cursor, &frame, true); + const CachedNode* next = root->nextTextField(current, &frame, true); if (!next) return; const WebCore::IntRect& bounds = next->bounds(); @@ -2027,7 +2117,7 @@ static jint nativeTextFieldAction(JNIEnv *env, jobject obj) CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); if (!root) return static_cast<jint>(CachedRoot::FAILURE); - return static_cast<jint>(root->cursorTextFieldAction()); + return static_cast<jint>(root->currentTextFieldAction()); } static int nativeMoveGeneration(JNIEnv *env, jobject obj) @@ -2131,6 +2221,16 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeDestroy }, { "nativeDrawCursorRing", "(Landroid/graphics/Canvas;)V", (void*) nativeDrawCursorRing }, + { "nativeDestroyLayer", "(I)V", + (void*) nativeDestroyLayer }, + { "nativeLayersHaveAnimations", "(I)Z", + (void*) nativeLayersHaveAnimations }, + { "nativeEvaluateLayersAnimations", "(I)I", + (void*) nativeEvaluateLayersAnimations }, + { "nativeDrawLayers", "(IFFFLandroid/graphics/Canvas;)V", + (void*) nativeDrawLayers }, + { "nativeUpdateLayers", "(II)V", + (void*) nativeUpdateLayers }, { "nativeDrawMatches", "(Landroid/graphics/Canvas;)V", (void*) nativeDrawMatches }, { "nativeDrawSelectionPointer", "(Landroid/graphics/Canvas;FIIZ)V", @@ -2147,8 +2247,6 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeFocusCandidateFramePointer }, { "nativeFocusCandidateIsPassword", "()Z", (void*) nativeFocusCandidateIsPassword }, - { "nativeFocusCandidateIsPlugin", "()Z", - (void*) nativeFocusCandidateIsPlugin }, { "nativeFocusCandidateIsRtlText", "()Z", (void*) nativeFocusCandidateIsRtlText }, { "nativeFocusCandidateIsTextInput", "()Z", |