OSDN Git Service

Fixing mouse and touch coordinates inside iframes.
authorDerek Sollenberger <djsollen@google.com>
Mon, 3 Aug 2009 19:45:38 +0000 (15:45 -0400)
committerDerek Sollenberger <djsollen@google.com>
Mon, 3 Aug 2009 20:27:57 +0000 (16:27 -0400)
WebCore/plugins/android/PluginViewAndroid.cpp
WebKit/android/plugins/PluginWidgetAndroid.cpp
WebKit/android/plugins/PluginWidgetAndroid.h

index 54a085d..d88692d 100644 (file)
@@ -228,13 +228,11 @@ void PluginView::handleTouchEvent(TouchEvent* event)
 
     evt.data.touch.modifiers = 0;   // todo
 
-    // the event is relative to the window's (0,0), so use convertToContainingWindow
-    IntPoint winCoordinates = IntPoint(event->x(), event->y());
-    IntPoint docCoordinates = parent()->windowToContents(winCoordinates);
-
-    // convert to coordinates that are relative to the plugin
-    evt.data.touch.x = docCoordinates.x() - m_npWindow.x;
-    evt.data.touch.y = docCoordinates.y() - m_npWindow.y;
+    // 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;
 
     if (m_plugin->pluginFuncs()->event(m_instance, &evt)) {
         event->setDefaultPrevented(true);
@@ -253,13 +251,11 @@ void PluginView::handleMouseEvent(MouseEvent* event)
         SkANP::InitEvent(&evt, kMouse_ANPEventType);
         evt.data.mouse.action = isUp ? kUp_ANPMouseAction : kDown_ANPMouseAction;
 
-        // the event is relative to the window's (0,0), so use convertToContainingWindow
-        IntPoint winCoordinates = IntPoint(event->x(), event->y());
-        IntPoint docCoordinates = parent()->windowToContents(winCoordinates);
-
-        // convert to coordinates that are relative to the plugin
-        evt.data.mouse.x = docCoordinates.x() - m_npWindow.x;
-        evt.data.mouse.y = docCoordinates.y() - m_npWindow.y;
+        // 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;
     }
     else {
       return;
@@ -377,21 +373,16 @@ void PluginView::setNPWindowRect(const IntRect& rect)
     if (!m_isStarted)
         return;
 
-    const int width = rect.width();
-    const int height = rect.height();
-
-    // the rect is relative to the frameview's (0,0), so use convertToContainingWindow
-    IntPoint p = parent()->convertToContainingWindow(rect.location());
-    m_npWindow.x = p.x();
-    m_npWindow.y = p.y();
-
-    m_npWindow.width = width;
-    m_npWindow.height = height;
+    // 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();
 
     m_npWindow.clipRect.left = 0;
     m_npWindow.clipRect.top = 0;
-    m_npWindow.clipRect.right = width;
-    m_npWindow.clipRect.bottom = height;
+    m_npWindow.clipRect.right = rect.width();
+    m_npWindow.clipRect.bottom = rect.height();
 
     if (m_plugin->pluginFuncs()->setwindow) {
 #if USE(JSC)
index 30a55cb..96aa74b 100644 (file)
@@ -71,7 +71,8 @@ void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) {
 
     if (m_drawingModel == kSurface_ANPDrawingModel) {
         if (m_surface) {
-            m_surface->attach(window->x, window->y, window->width, window->height);
+            IntPoint docPoint = getDocumentCoordinates(window->x, window->y);
+            m_surface->attach(docPoint.x(), docPoint.y(), window->width, window->height);
         }
     } else {
         m_flipPixelRef->safeUnref();
@@ -292,9 +293,7 @@ void PluginWidgetAndroid::scrollToVisibleFrameRect() {
     // this requires converting the m_requestedFrameRect from frame to doc coordinates
 
     // find the center of the visibleRect in document coordinates
-    ScrollView* scrollView = m_pluginView->parent();
-    IntPoint pluginFramePoint = IntPoint(m_requestedFrameRect.fLeft, m_requestedFrameRect.fTop);
-    IntPoint pluginDocPoint = scrollView->convertToContainingWindow(pluginFramePoint);
+    IntPoint pluginDocPoint = getDocumentCoordinates(m_requestedFrameRect.fLeft, m_requestedFrameRect.fTop);
     int rectCenterX = pluginDocPoint.x() + m_requestedFrameRect.width()/2;
     int rectCenterY = pluginDocPoint.y() + m_requestedFrameRect.height()/2;
 
@@ -306,6 +305,25 @@ void PluginWidgetAndroid::scrollToVisibleFrameRect() {
     int deltaX = rectCenterX - screenCenterX;
     int deltaY = rectCenterY - screenCenterY;
 
+    ScrollView* scrollView = m_pluginView->parent();
     android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
     core->scrollBy(deltaX, deltaY, true);
 }
+
+IntPoint PluginWidgetAndroid::getDocumentCoordinates(int frameX, int frameY) {
+    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;
+}
index 1da618f..cc2d206 100644 (file)
@@ -27,6 +27,7 @@
 #define PluginWidgetAndroid_H
 
 #include "android_npapi.h"
+#include "IntPoint.h"
 #include "SkRect.h"
 
 #include <wtf/OwnPtr.h>
@@ -132,6 +133,7 @@ struct PluginWidgetAndroid {
     void setVisibleRects(const ANPRectI rects[], int32_t count);
 
 private:
+    WebCore::IntPoint getDocumentCoordinates(int frameX, int frameY);
     void computeVisibleFrameRect();
     void scrollToVisibleFrameRect();