Bug 1379508: Part 2 - Ignore transforms when calculating child process offsets. r?kats draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 13 Jul 2017 15:33:25 -0700
changeset 608641 65b8fa0eb658dea04d1d8d3e509c61ebd06fad9d
parent 608640 367512a1947638dd4993e5f5ad9503c0c110374d
child 608642 a69c4c52512f72a18b6c1771ecd1594f4b7fb012
push id68357
push usermaglione.k@gmail.com
push dateThu, 13 Jul 2017 23:08:44 +0000
reviewerskats
bugs1379508
milestone56.0a1
Bug 1379508: Part 2 - Ignore transforms when calculating child process offsets. r?kats The current code is wrong in several ways when transforms are applied, but even if it were correct, it would give the wrong behavior. See comment in patch for more details. MozReview-Commit-ID: 3RaPuvENnWa
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -42,16 +42,17 @@
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsCOMPtr.h"
 #include "nsContentAreaDragDrop.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
+#include "nsFrameManager.h"
 #include "nsIBaseWindow.h"
 #include "nsIBrowser.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
@@ -1974,27 +1975,47 @@ TabParent::GetChildProcessOffset()
   if (!frameLoader) {
     return offset;
   }
   nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
   if (!targetFrame) {
     return offset;
   }
 
-  // Find out how far we're offset from the nearest widget.
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return offset;
   }
-  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget,
-                                                            LayoutDeviceIntPoint(0, 0),
-                                                            targetFrame);
-
-  return LayoutDeviceIntPoint::FromAppUnitsToNearest(
-           pt, targetFrame->PresContext()->AppUnitsPerDevPixel());
+
+  nsPresContext* presContext = targetFrame->PresContext();
+  nsIFrame* rootFrame = presContext->PresShell()->FrameManager()->GetRootFrame();
+  nsView* rootView = rootFrame->GetView();
+  if (!rootView) {
+    return offset;
+  }
+
+  // Note that we don't want to take into account transforms here:
+#if 0
+  nsPoint pt(0, 0);
+  nsLayoutUtils::TransformPoint(targetFrame, rootFrame, pt);
+#endif
+  // In practice, when transforms are applied to this frameLoader, we currently
+  // get the wrong results whether we take transforms into account here or not.
+  // But applying transforms here gives us the wrong results in all
+  // circumstances when transforms are applied, unless they're purely
+  // translational. It also gives us the wrong results whenever CSS transitions
+  // are used to apply transforms, since the offeets aren't updated as the
+  // transition is animated.
+  //
+  // What we actually need to do is apply the transforms to the coordinates of
+  // any events we send to the child, and reverse them for any screen
+  // coordinates that we retrieve from the child.
+
+  nsPoint pt = targetFrame->GetOffsetTo(rootFrame);
+  return -nsLayoutUtils::TranslateViewToWidget(presContext, rootView, pt, widget);
 }
 
 LayoutDeviceIntPoint
 TabParent::GetClientOffset()
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   nsCOMPtr<nsIWidget> docWidget = GetDocWidget();
 
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -544,16 +544,19 @@ public:
   // Returns the top-level widget for our frameloader's document.
   already_AddRefed<nsIWidget> GetDocWidget() const;
 
   const TabId GetTabId() const
   {
     return mTabId;
   }
 
+  // Returns the offset from the origin of our frameloader's nearest widget to
+  // the origin of its layout frame. This offset is used to translate event
+  // coordinates relative to the PuppetWidget origin in the child process.
   LayoutDeviceIntPoint GetChildProcessOffset();
 
   // Returns the offset from the on-screen origin of our top-level window's
   // widget (including window decorations) to the origin of our frameloader's
   // nearest widget. This offset is used to translate coordinates from the
   // PuppetWidget's origin to absolute screen coordinates in the child.
   LayoutDeviceIntPoint GetClientOffset();