diff options
| author | Grace Kloba <klobag@google.com> | 2010-01-19 19:00:16 -0800 |
|---|---|---|
| committer | Grace Kloba <klobag@google.com> | 2010-01-20 08:44:59 -0800 |
| commit | 1f15f3a9f6dc2a169bbd160e2e1abb161f9927d9 (patch) | |
| tree | 3f05712e2467690c62b0a7e92e800cdc8fb6d011 | |
| parent | 032a9065415ac4791c8d73bceba10cfa9fc77bf7 (diff) | |
| download | external_webkit-1f15f3a9f6dc2a169bbd160e2e1abb161f9927d9.zip external_webkit-1f15f3a9f6dc2a169bbd160e2e1abb161f9927d9.tar.gz external_webkit-1f15f3a9f6dc2a169bbd160e2e1abb161f9927d9.tar.bz2 | |
Changing plugin setwindow() to use page coordinate
instead of frame as it is what Flash expects. For
other port like Mac, it passes the window coordinate
to the plugin. In Android, plugin always sees the
full page and we use the visible screen rect to
indicate whether it is visible.
Change to use page coordinate across PluginView and
PluginWidget for consistency. This should fix the
problem Ben saw with plugin inside iframe (which is
caused by a race condition) and the cnnn ad problem
Adobe has.
| -rw-r--r-- | WebCore/plugins/PluginView.cpp | 7 | ||||
| -rw-r--r-- | WebCore/plugins/PluginView.h | 2 | ||||
| -rw-r--r-- | WebCore/plugins/android/PluginViewAndroid.cpp | 69 | ||||
| -rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 1 | ||||
| -rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.cpp | 84 | ||||
| -rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.h | 21 |
6 files changed, 75 insertions, 109 deletions
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp index 129a21c..89713b5 100644 --- a/WebCore/plugins/PluginView.cpp +++ b/WebCore/plugins/PluginView.cpp @@ -131,15 +131,8 @@ void PluginView::setFrameRect(const IntRect& rect) if (m_element->document()->printing()) return; -#if defined(ANDROID_PLUGINS) - if (m_isStarted && (rect != frameRect())) { - Widget::setFrameRect(rect); - setNPWindowRect(rect); // only call when it changes - } -#else if (rect != frameRect()) Widget::setFrameRect(rect); -#endif updatePluginWidget(); diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h index a5618f7..0ce9c7c 100644 --- a/WebCore/plugins/PluginView.h +++ b/WebCore/plugins/PluginView.h @@ -373,7 +373,7 @@ public: private: -#if defined(XP_UNIX) || defined(Q_WS_X11) || PLATFORM(SYMBIAN) +#if defined(XP_UNIX) || defined(Q_WS_X11) || PLATFORM(SYMBIAN) || defined(ANDROID_PLUGINS) void setNPWindowIfNeeded(); #elif defined(XP_MACOSX) NP_CGContext m_npCgContext; diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp index e10641d..c4bccdb 100644 --- a/WebCore/plugins/android/PluginViewAndroid.cpp +++ b/WebCore/plugins/android/PluginViewAndroid.cpp @@ -206,11 +206,11 @@ void PluginView::handleTouchEvent(TouchEvent* event) evt.data.touch.modifiers = 0; // todo - // convert to coordinates that are relative to the plugin. The pageX / pageY - // values are the only values in the event that are consistently in frame - // coordinates despite their misleading name. - evt.data.touch.x = event->pageX() - m_npWindow.x; - evt.data.touch.y = event->pageY() - m_npWindow.y; + // convert to coordinates that are relative to the plugin. + IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal( + IntPoint(event->pageX(), event->pageY()))); + evt.data.touch.x = localPos.x(); + evt.data.touch.y = localPos.y(); int16 ret = m_plugin->pluginFuncs()->event(m_instance, &evt); if (ignoreRet) @@ -243,11 +243,11 @@ void PluginView::handleMouseEvent(MouseEvent* event) SkANP::InitEvent(&evt, kMouse_ANPEventType); evt.data.mouse.action = isUp ? kUp_ANPMouseAction : kDown_ANPMouseAction; - // convert to coordinates that are relative to the plugin. The pageX / pageY - // values are the only values in the event that are consistently in frame - // coordinates despite their misleading name. - evt.data.mouse.x = event->pageX() - m_npWindow.x; - evt.data.mouse.y = event->pageY() - m_npWindow.y; + // convert to coordinates that are relative to the plugin. + IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal( + IntPoint(event->pageX(), event->pageY()))); + evt.data.mouse.x = localPos.x(); + evt.data.mouse.y = localPos.y(); if (isDown) { // The plugin needs focus to receive keyboard events if (Page* page = m_parentFrame->page()) @@ -394,21 +394,34 @@ void PluginView::setParent(ScrollView* parent) } } -void PluginView::setNPWindowRect(const IntRect& rect) +void PluginView::setNPWindowRect(const IntRect&) { - if (!m_isStarted) - return; + setNPWindowIfNeeded(); +} - // the rect is relative to the frameview's (0,0) - m_npWindow.x = rect.x(); - m_npWindow.y = rect.y(); - m_npWindow.width = rect.width(); - m_npWindow.height = rect.height(); +void PluginView::setNPWindowIfNeeded() +{ + if (!m_isStarted || !parent()) + return; - m_npWindow.clipRect.left = 0; - m_npWindow.clipRect.top = 0; - m_npWindow.clipRect.right = rect.width(); - m_npWindow.clipRect.bottom = rect.height(); + // in Android, plugin always get the setwindow() in the page coordinate. + IntRect pageRect = m_windowRect; + ScrollView* top = parent(); + while (top->parent()) + top = top->parent(); + // only the top ScrollView can have the offset + pageRect.move(top->scrollOffset()); + + // the m_npWindow is relative to the page + m_npWindow.x = pageRect.x(); + m_npWindow.y = pageRect.y(); + m_npWindow.width = pageRect.width(); + m_npWindow.height = pageRect.height(); + + m_npWindow.clipRect.left = pageRect.x(); + m_npWindow.clipRect.top = pageRect.y(); + m_npWindow.clipRect.right = pageRect.x() + pageRect.width(); + m_npWindow.clipRect.bottom = pageRect.y() + pageRect.height(); if (m_plugin->pluginFuncs()->setwindow) { #if USE(JSC) @@ -587,16 +600,22 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) } m_window->inval(rect, false); + context->save(); + context->translate(frame.x(), frame.y()); m_window->draw(android_gc2canvas(context)); + context->restore(); } -// new as of SVN 38068, Nov 5 2008 void PluginView::updatePluginWidget() { - // I bet/hope we can move all of setNPWindowRect() into here FrameView* frameView = static_cast<FrameView*>(parent()); if (frameView) { - m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); + IntRect oldWindowRect = m_windowRect; + + m_windowRect = frameView->contentsToWindow(frameRect()); + + if (m_windowRect != oldWindowRect) + setNPWindowIfNeeded(); } } diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 5d2b8bb..a1f4354 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -1422,7 +1422,6 @@ void WebViewCore::drawPlugins() SkIRect dirty; if (w->isDirty(&dirty)) { w->draw(); - w->localToDocumentCoords(&dirty); inval.op(dirty, SkRegion::kUnion_Op); } } diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp index 0fcdc3b..7a4b9a3 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -48,7 +48,7 @@ PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) m_eventFlags = 0; m_pluginWindow = NULL; m_requestedVisibleRectCount = 0; - m_requestedFrameRect.setEmpty(); + m_requestedDocRect.setEmpty(); m_visibleDocRect.setEmpty(); m_pluginBounds.setEmpty(); m_hasFocus = false; @@ -106,12 +106,10 @@ void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { if (m_drawingModel == kSurface_ANPDrawingModel) { - IntPoint docPoint = frameToDocumentCoords(window->x, window->y); - // if the surface exists check for changes and update accordingly if (m_embeddedView && m_pluginBounds != oldPluginBounds) { - m_core->updateSurface(m_embeddedView, docPoint.x(), docPoint.y(), + m_core->updateSurface(m_embeddedView, window->x, window->y, window->width, window->height); // if the surface does not exist then create a new surface @@ -120,13 +118,12 @@ void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { WebCore::PluginPackage* pkg = m_pluginView->plugin(); NPP instance = m_pluginView->instance(); - jobject pluginSurface; pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue, static_cast<void*>(&pluginSurface)); jobject tempObj = m_core->addSurface(pluginSurface, - docPoint.x(), docPoint.y(), + window->x, window->y, window->width, window->height); if (tempObj) { JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -134,7 +131,7 @@ void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { } } if (m_isFullScreen && m_pluginBounds != oldPluginBounds) { - m_core->updateFullScreenPlugin(docPoint.x(), docPoint.y(), + m_core->updateFullScreenPlugin(window->x, window->y, window->width, window->height); } } else { @@ -149,14 +146,7 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { return true; } -void PluginWidgetAndroid::localToDocumentCoords(SkIRect* rect) const { - if (m_pluginWindow) { - IntPoint pluginDocCoords = frameToDocumentCoords(m_pluginWindow->x, - m_pluginWindow->y); - rect->offset(pluginDocCoords.x(), pluginDocCoords.y()); - } -} - +// returned rect is in the page coordinate bool PluginWidgetAndroid::isDirty(SkIRect* rect) const { // nothing to report if we haven't had setWindow() called yet if (NULL == m_flipPixelRef) { @@ -169,6 +159,7 @@ bool PluginWidgetAndroid::isDirty(SkIRect* rect) const { } else { if (rect) { *rect = dirty.getBounds(); + rect->offset(m_pluginWindow->x, m_pluginWindow->y); } return true; } @@ -216,8 +207,7 @@ void PluginWidgetAndroid::draw(SkCanvas* canvas) { if (canvas && m_pluginWindow) { SkBitmap bm(bitmap); bm.setPixelRef(m_flipPixelRef); - canvas->drawBitmap(bm, SkIntToScalar(m_pluginWindow->x), - SkIntToScalar(m_pluginWindow->y), NULL); + canvas->drawBitmap(bm, 0, 0); } } break; @@ -290,7 +280,7 @@ void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float int newScreenH = m_visibleDocRect.height(); if (oldScreenW != newScreenW || oldScreenH != newScreenH) - computeVisibleFrameRect(); + computeVisibleDocRect(); bool visible = SkIRect::Intersects(m_visibleDocRect, m_pluginBounds); if(m_visible != visible) { @@ -335,10 +325,10 @@ void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) } } #endif - computeVisibleFrameRect(); + computeVisibleDocRect(); } -void PluginWidgetAndroid::computeVisibleFrameRect() { +void PluginWidgetAndroid::computeVisibleDocRect() { // ensure the visibleDocRect has been set (i.e. not equal to zero) if (m_visibleDocRect.isEmpty() || !m_pluginWindow) @@ -352,7 +342,7 @@ void PluginWidgetAndroid::computeVisibleFrameRect() { ANPRectI* rect = &m_requestedVisibleRect[counter]; - // create skia rect for easier manipulation and convert it to frame coordinates + // create skia rect for easier manipulation and convert it to page coordinates SkIRect pluginRect; pluginRect.set(rect->left, rect->top, rect->right, rect->bottom); pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y); @@ -384,35 +374,27 @@ void PluginWidgetAndroid::computeVisibleFrameRect() { visibleRect = pluginRect; } - m_requestedFrameRect = visibleRect; - scrollToVisibleFrameRect(); + m_requestedDocRect = visibleRect; + scrollToVisibleDocRect(); } -void PluginWidgetAndroid::scrollToVisibleFrameRect() { +void PluginWidgetAndroid::scrollToVisibleDocRect() { - if (!m_hasFocus || m_requestedFrameRect.isEmpty() || m_visibleDocRect.isEmpty()) { + if (!m_hasFocus || m_requestedDocRect.isEmpty() || m_visibleDocRect.isEmpty()) { #if DEBUG_VISIBLE_RECTS - SkDebugf("%s call m_hasFocus=%d m_requestedFrameRect.isEmpty()=%d" + SkDebugf("%s call m_hasFocus=%d m_requestedDocRect.isEmpty()=%d" " m_visibleDocRect.isEmpty()=%d", __FUNCTION__, m_hasFocus, - m_requestedFrameRect.isEmpty(), m_visibleDocRect.isEmpty()); + m_requestedDocRect.isEmpty(), m_visibleDocRect.isEmpty()); #endif return; } - // if the entire rect is already visible then we don't need to scroll, which - // requires converting the m_requestedFrameRect from frame to doc coordinates - IntPoint pluginDocPoint = frameToDocumentCoords(m_requestedFrameRect.fLeft, - m_requestedFrameRect.fTop); - SkIRect requestedDocRect; - requestedDocRect.set(pluginDocPoint.x(), pluginDocPoint.y(), - pluginDocPoint.x() + m_requestedFrameRect.width(), - pluginDocPoint.y() + m_requestedFrameRect.height()); - - if (m_visibleDocRect.contains(requestedDocRect)) + // if the entire rect is already visible then we don't need to scroll + if (m_visibleDocRect.contains(m_requestedDocRect)) return; // find the center of the visibleRect in document coordinates - int rectCenterX = requestedDocRect.fLeft + requestedDocRect.width()/2; - int rectCenterY = requestedDocRect.fTop + requestedDocRect.height()/2; + int rectCenterX = m_requestedDocRect.fLeft + m_requestedDocRect.width()/2; + int rectCenterY = m_requestedDocRect.fTop + m_requestedDocRect.height()/2; // find document coordinates for center of the visible screen int screenCenterX = m_visibleDocRect.fLeft + m_visibleDocRect.width()/2; @@ -430,24 +412,6 @@ void PluginWidgetAndroid::scrollToVisibleFrameRect() { core->scrollBy(deltaX, deltaY, true); } -IntPoint PluginWidgetAndroid::frameToDocumentCoords(int frameX, int frameY) const { - IntPoint docPoint = IntPoint(frameX, frameY); - - const ScrollView* currentScrollView = m_pluginView->parent(); - if (currentScrollView) { - const ScrollView* parentScrollView = currentScrollView->parent(); - while (parentScrollView) { - - docPoint.move(currentScrollView->x(), currentScrollView->y()); - - currentScrollView = parentScrollView; - parentScrollView = parentScrollView->parent(); - } - } - - return docPoint; -} - void PluginWidgetAndroid::requestFullScreen() { if (m_isFullScreen || !m_embeddedView) { return; @@ -463,9 +427,8 @@ void PluginWidgetAndroid::requestFullScreen() { m_core->destroySurface(m_embeddedView); // add the full screen view - IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y); m_core->showFullScreenPlugin(m_embeddedView, m_pluginView->instance(), - docPoint.x(), docPoint.y(), m_pluginWindow->width, + m_pluginWindow->x, m_pluginWindow->y, m_pluginWindow->width, m_pluginWindow->height); m_isFullScreen = true; } @@ -481,8 +444,7 @@ void PluginWidgetAndroid::exitFullScreen(bool pluginInitiated) { } // add the embedded view back - IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y); - m_core->updateSurface(m_embeddedView, docPoint.x(), docPoint.y(), + m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y, m_pluginWindow->width, m_pluginWindow->height); // send event to notify plugin of full screen change diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h index eba0b69..f0cebcf 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.h +++ b/WebKit/android/plugins/PluginWidgetAndroid.h @@ -73,14 +73,8 @@ struct PluginWidgetAndroid { */ bool setDrawingModel(ANPDrawingModel); - /* Utility method to convert from local (plugin) coordinates to document - coordinates. Needed (for instance) to convert the dirty rectangle into - document coordinates to inturn inval the screen. - */ - void localToDocumentCoords(SkIRect*) const; - - /* Returns true (and optionally updates rect with the dirty bounds) if - the plugin has invalidate us. + /* Returns true (and optionally updates rect with the dirty bounds in the + page coordinate) if the plugin has invalidate us. */ bool isDirty(SkIRect* dirtyBounds = NULL) const; /* Called by PluginView to invalidate a portion of the plugin area (in @@ -141,9 +135,8 @@ struct PluginWidgetAndroid { bool inFullScreen() { return m_isFullScreen; } private: - WebCore::IntPoint frameToDocumentCoords(int frameX, int frameY) const; - void computeVisibleFrameRect(); - void scrollToVisibleFrameRect(); + void computeVisibleDocRect(); + void scrollToVisibleDocRect(); WebCore::PluginView* m_pluginView; android::WebViewCore* m_core; @@ -151,9 +144,9 @@ private: ANPDrawingModel m_drawingModel; ANPEventFlags m_eventFlags; NPWindow* m_pluginWindow; - SkIRect m_pluginBounds; - SkIRect m_visibleDocRect; - SkIRect m_requestedFrameRect; + SkIRect m_pluginBounds; // relative to the page + SkIRect m_visibleDocRect; // relative to the page + SkIRect m_requestedDocRect; // relative to the page bool m_hasFocus; bool m_isFullScreen; bool m_visible; |
