Bug 1128238 - Ajust NPP_SetWindow and synth native event coords to account for the chrome offset of remote tabs. Prior to this the content process always assumed the tab was the window origin. r=aklotz
authorJim Mathies <jmathies@mozilla.com>
Wed, 08 Apr 2015 11:51:49 -0500
changeset 238188 9902d3bf59e47e18316cf907df3e6e4933075eda
parent 238187 3ccd83f8e32b5eb921f80389282c51380be2b70c
child 238189 4ab18dfd2884b239cf6135a13d3e8786ad48a119
push id28557
push userkwierso@gmail.com
push dateThu, 09 Apr 2015 00:04:16 +0000
treeherdermozilla-central@9a29065e2311 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1128238
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1128238 - Ajust NPP_SetWindow and synth native event coords to account for the chrome offset of remote tabs. Prior to this the content process always assumed the tab was the window origin. r=aklotz
dom/ipc/PBrowser.ipdl
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
layout/generic/nsPluginFrame.cpp
layout/generic/nsPluginFrame.h
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -338,16 +338,24 @@ parent:
      * Content process forward from PuppetWidget for synth mouse move
      * events.
      *
      * aPoint a synth point relative to the window
      */
     sync SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint);
 
     /**
+     * Returns the offset of this tab from the top level window
+     * origin in device pixels.
+     *
+     * aPoint offset values in device pixels.
+     */
+    sync GetTabOffset() returns (LayoutDeviceIntPoint aPoint);
+
+    /**
      * Gets the DPI of the screen corresponding to this browser.
      */
     sync GetDPI() returns (float value);
 
     /**
      * Gets the default scaling factor of the screen corresponding to this browser.
      */
     sync GetDefaultScale() returns (double value);
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1789,16 +1789,23 @@ TabParent::RecvEnableDisableCommands(con
     remoteBrowser->EnableDisableCommands(aAction,
                                          aEnabledCommands.Length(), enabledCommands,
                                          aDisabledCommands.Length(), disabledCommands);
   }
 
   return true;
 }
 
+bool
+TabParent::RecvGetTabOffset(LayoutDeviceIntPoint* aPoint)
+{
+  *aPoint = GetChildProcessOffset();
+  return true;
+}
+
 NS_IMETHODIMP
 TabParent::GetChildProcessOffset(int32_t* aOutCssX, int32_t* aOutCssY)
 {
   NS_ENSURE_ARG(aOutCssX);
   NS_ENSURE_ARG(aOutCssY);
   CSSPoint offset = LayoutDevicePoint(GetChildProcessOffset())
       * GetLayoutDeviceToCSSScale();
   *aOutCssX = offset.x;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -204,16 +204,17 @@ public:
                                            nsTArray<nsCString>&& aDisabledCommands) override;
     virtual bool RecvSetCursor(const uint32_t& aValue, const bool& aForce) override;
     virtual bool RecvSetBackgroundColor(const nscolor& aValue) override;
     virtual bool RecvSetStatus(const uint32_t& aType, const nsString& aStatus) override;
     virtual bool RecvIsParentWindowMainWidgetVisible(bool* aIsVisible) override;
     virtual bool RecvSynthesizeNativeMouseMove(const mozilla::LayoutDeviceIntPoint& aPoint) override;
     virtual bool RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip) override;
     virtual bool RecvHideTooltip() override;
+    virtual bool RecvGetTabOffset(LayoutDeviceIntPoint* aPoint) override;
     virtual bool RecvGetDPI(float* aValue) override;
     virtual bool RecvGetDefaultScale(double* aValue) override;
     virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
     virtual bool RecvZoomToRect(const uint32_t& aPresShellId,
                                 const ViewID& aViewId,
                                 const CSSRect& aRect) override;
     virtual bool RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
                                            const ViewID& aViewId,
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -620,16 +620,22 @@ nsPluginFrame::CallSetWindow(bool aCheck
   nsRootPresContext* rootPC = presContext->GetRootPresContext();
   if (!rootPC)
     return NS_ERROR_FAILURE;
   int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
   nsIFrame* rootFrame = rootPC->PresShell()->FrameManager()->GetRootFrame();
   nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame);
   nsIntRect intBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
 
+  // In e10s, this returns the offset to the top level window, in non-e10s
+  // it return 0,0.
+  LayoutDeviceIntPoint intOffset = GetRemoteTabChromeOffset();
+  intBounds.x += intOffset.x;
+  intBounds.y += intOffset.y;
+
   // window must be in "display pixels"
   double scaleFactor = 1.0;
   if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
     scaleFactor = 1.0;
   }
   size_t intScaleFactor = ceil(scaleFactor);
   window->x = intBounds.x / intScaleFactor;
   window->y = intBounds.y / intScaleFactor;
@@ -748,34 +754,68 @@ nsPluginFrame::IsHidden(bool aCheckVisib
          !hidden.LowerCaseEqualsLiteral("off")))) {
       return true;
     }
   }
 
   return false;
 }
 
-nsIntPoint nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
+mozilla::LayoutDeviceIntPoint
+nsPluginFrame::GetRemoteTabChromeOffset()
+{
+  LayoutDeviceIntPoint offset;
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetContent()->OwnerDoc()->GetWindow());
+    if (window) {
+      nsCOMPtr<nsIDOMWindow> topWindow;
+      window->GetTop(getter_AddRefs(topWindow));
+      if (topWindow) {
+        dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
+        if (tc) {
+          LayoutDeviceIntPoint chromeOffset;
+          tc->SendGetTabOffset(&chromeOffset);
+          offset -= chromeOffset;
+        }
+      }
+    }
+  }
+  return offset;
+}
+
+nsIntPoint
+nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
 {
   nsView * parentWithView;
   nsPoint origin(0,0);
 
   GetOffsetFromView(origin, &parentWithView);
 
   // if it's windowless, let's make sure we have our origin set right
   // it may need to be corrected, like after scrolling
   if (aWindowless && parentWithView) {
     nsPoint offsetToWidget;
     parentWithView->GetNearestWidget(&offsetToWidget);
     origin += offsetToWidget;
   }
   origin += GetContentRectRelativeToSelf().TopLeft();
 
-  return nsIntPoint(PresContext()->AppUnitsToDevPixels(origin.x),
-                    PresContext()->AppUnitsToDevPixels(origin.y));
+  nsIntPoint pt(PresContext()->AppUnitsToDevPixels(origin.x),
+                PresContext()->AppUnitsToDevPixels(origin.y));
+
+  // If we're in the content process offsetToWidget is tied to the top level
+  // widget we can access in the child process, which is the tab. We need the
+  // offset all the way up to the top level native window here. (If this is
+  // non-e10s this routine will return 0,0.)
+  if (aWindowless) {
+    mozilla::LayoutDeviceIntPoint lpt = GetRemoteTabChromeOffset();
+    pt += nsIntPoint(lpt.x, lpt.y);
+  }
+
+  return pt;
 }
 
 void
 nsPluginFrame::DidReflow(nsPresContext*            aPresContext,
                          const nsHTMLReflowState*  aReflowState,
                          nsDidReflowStatus         aStatus)
 {
   // Do this check before calling the superclass, as that clears
--- a/layout/generic/nsPluginFrame.h
+++ b/layout/generic/nsPluginFrame.h
@@ -9,16 +9,17 @@
 #define nsPluginFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsIObjectFrame.h"
 #include "nsFrame.h"
 #include "nsRegion.h"
 #include "nsDisplayList.h"
 #include "nsIReflowCallback.h"
+#include "Units.h"
 
 #ifdef XP_WIN
 #include <windows.h> // For HWND :(
 // Undo the windows.h damage
 #undef GetMessage
 #undef CreateEvent
 #undef GetClassName
 #undef GetBinaryType
@@ -215,16 +216,23 @@ protected:
   // check attributes and optionally CSS to see if we should display anything
   bool IsHidden(bool aCheckVisibilityStyle = true) const;
 
   bool IsOpaque() const;
   bool IsTransparentMode() const;
   bool IsPaintedByGecko() const;
 
   nsIntPoint GetWindowOriginInPixels(bool aWindowless);
+  
+  /*
+   * If this frame is in a remote tab, return the tab offset to
+   * the origin of the chrome window. In non-e10s, this return 0,0.
+   * This api sends a sync ipc request so be careful about use.
+   */
+  mozilla::LayoutDeviceIntPoint GetRemoteTabChromeOffset();
 
   static void PaintPrintPlugin(nsIFrame* aFrame,
                                nsRenderingContext* aRenderingContext,
                                const nsRect& aDirtyRect, nsPoint aPt);
   void PrintPlugin(nsRenderingContext& aRenderingContext,
                    const nsRect& aDirtyRect);
   void PaintPlugin(nsDisplayListBuilder* aBuilder,
                    nsRenderingContext& aRenderingContext,