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
--- 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();