Commit 173d001b authored by Botond Ballo's avatar Botond Ballo
Browse files

Bug 1556556 - Propagate RelativeTo far and wide. r=kats,mattwoodrow

This "upgrades" various nsLayoutUtils functions which take as inputs
a set of coordinates and a frame that the coordinates are relative to,
to accept a RelativeTo object instead of a frame.

Most of the patch is just dumb propagation, but the few places where
we use an explicit ViewportType::Visual are important. There are
probably a few other places I've overlooked, but this seems to cover
the important ones that come up commonly.

There are undoubtedly other functions into which we can propagate
RelativeTo, in this patch I've propagated it as far as necessary
for my needs in this bug (mainly GetTransformToAncestor() and
GetEventCoordinatesRelativeTo()).

Differential Revision: https://phabricator.services.mozilla.com/D68919
parent 6bda5b20
......@@ -12346,8 +12346,8 @@ already_AddRefed<nsDOMCaretPosition> Document::CaretPositionFromPoint(
nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &aOffset);
LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint(
CSSPoint(aX, aY), aOffset, GetPresContext());
nsPoint adjustedPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, refPoint, ptFrame);
nsPoint adjustedPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
widget, refPoint, RelativeTo{ptFrame});
 
nsFrame::ContentOffsets offsets =
ptFrame->GetContentOffsetsFromPoint(adjustedPoint);
......
......@@ -3227,8 +3227,9 @@ already_AddRefed<DOMMatrixReadOnly> Element::GetTransformToAncestor(
// If aAncestor is not actually an ancestor of this (including nullptr),
// then the call to GetTransformToAncestor will return the transform
// all the way up through the parent chain.
transform = nsLayoutUtils::GetTransformToAncestor(
primaryFrame, ancestorFrame, nsIFrame::IN_CSS_UNITS)
transform = nsLayoutUtils::GetTransformToAncestor(RelativeTo{primaryFrame},
RelativeTo{ancestorFrame},
nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}
......@@ -3243,7 +3244,8 @@ already_AddRefed<DOMMatrixReadOnly> Element::GetTransformToParent() {
Matrix4x4 transform;
if (primaryFrame) {
nsIFrame* parentFrame = primaryFrame->GetParent();
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame, parentFrame,
transform = nsLayoutUtils::GetTransformToAncestor(RelativeTo{primaryFrame},
RelativeTo{parentFrame},
nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}
......@@ -3259,7 +3261,8 @@ already_AddRefed<DOMMatrixReadOnly> Element::GetTransformToViewport() {
if (primaryFrame) {
transform =
nsLayoutUtils::GetTransformToAncestor(
primaryFrame, nsLayoutUtils::GetDisplayRootFrame(primaryFrame),
RelativeTo{primaryFrame},
RelativeTo{nsLayoutUtils::GetDisplayRootFrame(primaryFrame)},
nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}
......
......@@ -3231,8 +3231,8 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
LayoutDeviceIntPoint pt =
nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext());
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(
widget, pt, RelativeTo{rootFrame});
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
// This can happen if the page hasn't loaded yet or if the point
// is outside the frame.
......@@ -3242,8 +3242,8 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
// Convert point to coordinates relative to the target frame, which is
// what targetFrame's SelectByTypeAtPoint expects.
nsPoint relPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
nsPoint relPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
widget, pt, RelativeTo{targetFrame});
nsresult rv = static_cast<nsFrame*>(targetFrame)
->SelectByTypeAtPoint(GetPresContext(), relPoint, amount,
......
......@@ -2549,8 +2549,8 @@ nsresult ContentEventHandler::OnQueryCharacterAtPoint(
eventOnRoot.mRefPoint += aEvent->mWidget->WidgetToScreenOffset() -
rootWidget->WidgetToScreenOffset();
}
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame);
nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(
&eventOnRoot, RelativeTo{rootFrame});
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
if (!targetFrame || !targetFrame->GetContent() ||
......
......@@ -612,8 +612,8 @@ CSSIntPoint Event::GetClientCoords(nsPresContext* aPresContext,
if (!rootFrame) {
return CSSIntPoint(0, 0);
}
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, rootFrame);
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, aPoint, RelativeTo{rootFrame});
return CSSIntPoint::FromAppUnitsRounded(pt);
}
......@@ -646,8 +646,8 @@ CSSIntPoint Event::GetOffsetCoords(nsPresContext* aPresContext,
CSSIntPoint clientCoords =
GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
nsPoint pt = CSSPixel::ToAppUnits(clientCoords);
if (nsLayoutUtils::TransformPoint(rootFrame, frame, pt) ==
nsLayoutUtils::TRANSFORM_SUCCEEDED) {
if (nsLayoutUtils::TransformPoint(RelativeTo{rootFrame}, RelativeTo{frame},
pt) == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
pt -= frame->GetPaddingRectRelativeToSelf().TopLeft();
return CSSPixel::FromAppUnitsRounded(pt);
}
......
......@@ -3798,7 +3798,7 @@ static bool ShouldBlockCustomCursor(nsPresContext* aPresContext,
}
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, topLevel->PresShell()->GetRootFrame());
aEvent, RelativeTo{topLevel->PresShell()->GetRootFrame()});
nsSize size(CSSPixel::ToAppUnits(width), CSSPixel::ToAppUnits(height));
nsPoint hotspot(CSSPixel::ToAppUnits(aCursor.mHotspot.x),
......@@ -3893,8 +3893,8 @@ void EventStateManager::UpdateCursor(nsPresContext* aPresContext,
}
// If not locked, look for correct cursor
else if (aTargetFrame) {
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aTargetFrame);
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{aTargetFrame});
Maybe<nsIFrame::Cursor> framecursor = aTargetFrame->GetCursor(pt);
// Avoid setting cursor when the mouse is over a windowless plugin.
if (!framecursor) {
......
......@@ -181,7 +181,8 @@ nsIntPoint UIEvent::GetLayerPoint() const {
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
if (!targetFrame) return mLayerPoint;
nsIFrame* layer = nsLayoutUtils::GetClosestLayer(targetFrame);
nsPoint pt(nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, layer));
nsPoint pt(
nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, RelativeTo{layer}));
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
}
......
......@@ -563,7 +563,7 @@ void HTMLCanvasElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
return;
}
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(evt, frame);
nsLayoutUtils::GetEventCoordinatesRelativeTo(evt, RelativeTo{frame});
nsRect paddingRect = frame->GetContentRectRelativeToSelf();
Point hitpoint;
hitpoint.x = (ptInRoot.x - paddingRect.x) / AppUnitsPerCSSPixel();
......
......@@ -1833,9 +1833,9 @@ static NPCocoaEvent TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent,
anEvent->mMessage == eMouseUp ||
anEvent->mMessage == eLegacyMouseLineOrPageScroll ||
anEvent->mMessage == eMouseOver || anEvent->mMessage == eMouseOut) {
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(anEvent, aObjectFrame) -
aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
anEvent, RelativeTo{aObjectFrame}) -
aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = aObjectFrame->PresContext();
// Plugin event coordinates need to be translated from device pixels
// into "display pixels" in HiDPI modes.
......@@ -2164,9 +2164,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(
anEvent.mMessage == eMouseOver || anEvent.mMessage == eMouseOut ||
anEvent.mMessage == eMouseMove || anEvent.mMessage == eWheel,
"Incorrect event type for coordinate translation");
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
&anEvent, RelativeTo{mPluginFrame}) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = mPluginFrame->PresContext();
nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
presContext->AppUnitsToDevPixels(pt.y));
......@@ -2246,9 +2246,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(
// Get reference point relative to plugin origin.
const nsPresContext* presContext = mPluginFrame->PresContext();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint appPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
&anEvent, RelativeTo{mPluginFrame}) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();
......
......@@ -566,7 +566,7 @@ static bool PrepareForSetTargetAPZCNotification(
nsTArray<ScrollableLayerGuid>* aTargets) {
ScrollableLayerGuid guid(aLayersId, 0, ScrollableLayerGuid::NULL_SCROLL_ID);
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aWidget, aRefPoint, aRootFrame);
aWidget, aRefPoint, RelativeTo{aRootFrame, ViewportType::Visual});
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(aRootFrame, point);
nsIScrollableFrame* scrollAncestor =
target ? nsLayoutUtils::GetAsyncScrollableAncestorFrame(target)
......@@ -772,7 +772,8 @@ void APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
nsTArray<TouchBehaviorFlags> flags;
for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
flags.AppendElement(TouchActionHelper::GetAllowedTouchBehavior(
aWidget, rootFrame, aEvent.mTouches[i]->mRefPoint));
aWidget, RelativeTo{rootFrame, ViewportType::Visual},
aEvent.mTouches[i]->mRefPoint));
}
aCallback(aInputBlockId, std::move(flags));
}
......
......@@ -47,7 +47,7 @@ static void UpdateAllowedBehavior(StyleTouchAction aTouchActionValue,
}
TouchBehaviorFlags TouchActionHelper::GetAllowedTouchBehavior(
nsIWidget* aWidget, nsIFrame* aRootFrame,
nsIWidget* aWidget, RelativeTo aRootFrame,
const LayoutDeviceIntPoint& aPoint) {
TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN |
AllowedTouchBehavior::HORIZONTAL_PAN |
......@@ -57,7 +57,8 @@ TouchBehaviorFlags TouchActionHelper::GetAllowedTouchBehavior(
nsPoint relativePoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, aRootFrame);
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(aRootFrame, relativePoint);
nsIFrame* target =
nsLayoutUtils::GetFrameForPoint(aRootFrame.mFrame, relativePoint);
if (!target) {
return behavior;
}
......
......@@ -8,6 +8,7 @@
#define __mozilla_layers_TouchActionHelper_h__
#include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
#include "nsLayoutUtils.h" // for RelativeTo
class nsIFrame;
class nsIWidget;
......@@ -28,7 +29,7 @@ class TouchActionHelper {
* http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
*/
static TouchBehaviorFlags GetAllowedTouchBehavior(
nsIWidget* aWidget, nsIFrame* aRootFrame,
nsIWidget* aWidget, RelativeTo aRootFrame,
const LayoutDeviceIntPoint& aPoint);
};
......
......@@ -698,8 +698,8 @@ nsPoint AccessibleCaretEventHub::GetTouchEventPosition(
// Get event coordinate relative to root frame.
nsIFrame* rootFrame = mPresShell->GetRootFrame();
return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint,
rootFrame);
return nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, touchIntPoint, RelativeTo{rootFrame});
}
}
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
......@@ -712,7 +712,7 @@ nsPoint AccessibleCaretEventHub::GetMouseEventPosition(
// Get event coordinate relative to root frame.
nsIFrame* rootFrame = mPresShell->GetRootFrame();
return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mouseIntPoint,
rootFrame);
RelativeTo{rootFrame});
}
} // namespace mozilla
......@@ -565,7 +565,8 @@ nsresult AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) {
// something under the original point will be selected, which may not be the
// original text the user wants to select.
nsPoint ptInFrame = aPoint;
nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame);
nsLayoutUtils::TransformPoint(RelativeTo{rootFrame}, RelativeTo{ptFrame},
ptInFrame);
// Firstly check long press on an empty editable content.
Element* newFocusEditingHost = GetEditingHostForFrame(ptFrame);
......@@ -1229,7 +1230,8 @@ nsresult AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint) {
nsIFrame* newFrame = nullptr;
nsPoint newPoint;
nsPoint ptInFrame = point;
nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame);
nsLayoutUtils::TransformPoint(RelativeTo{rootFrame}, RelativeTo{ptFrame},
ptInFrame);
result = fs->ConstrainFrameAndPointToAnchorSubtree(ptFrame, ptInFrame,
&newFrame, newPoint);
if (NS_FAILED(result) || !newFrame) {
......@@ -1378,7 +1380,8 @@ void AccessibleCaretManager::StartSelectionAutoScrollTimer(
nsIFrame* rootFrame = mPresShell->GetRootFrame();
MOZ_ASSERT(rootFrame);
nsPoint ptInScrolled = aPoint;
nsLayoutUtils::TransformPoint(rootFrame, capturingFrame, ptInScrolled);
nsLayoutUtils::TransformPoint(RelativeTo{rootFrame},
RelativeTo{capturingFrame}, ptInScrolled);
RefPtr<nsFrameSelection> fs = GetFrameSelection();
MOZ_ASSERT(fs);
......
......@@ -261,8 +261,8 @@ static nsIContent* GetClickableAncestor(
return nullptr;
}
static nscoord AppUnitsFromMM(nsIFrame* aFrame, uint32_t aMM) {
nsPresContext* pc = aFrame->PresContext();
static nscoord AppUnitsFromMM(RelativeTo aFrame, uint32_t aMM) {
nsPresContext* pc = aFrame.mFrame->PresContext();
PresShell* presShell = pc->PresShell();
float result = float(aMM) * (pc->DeviceContext()->AppUnitsPerPhysicalInch() /
MM_PER_INCH_FLOAT);
......@@ -274,17 +274,18 @@ static nscoord AppUnitsFromMM(nsIFrame* aFrame, uint32_t aMM) {
* Clip aRect with the bounds of aFrame in the coordinate system of
* aRootFrame. aRootFrame is an ancestor of aFrame.
*/
static nsRect ClipToFrame(nsIFrame* aRootFrame, nsIFrame* aFrame,
static nsRect ClipToFrame(const nsIFrame* aRootFrame, const nsIFrame* aFrame,
nsRect& aRect) {
nsRect bound = nsLayoutUtils::TransformFrameRectToAncestor(
aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()), aRootFrame);
aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()),
RelativeTo{aRootFrame, ViewportType::Visual});
nsRect result = bound.Intersect(aRect);
return result;
}
static nsRect GetTargetRect(nsIFrame* aRootFrame,
static nsRect GetTargetRect(RelativeTo aRootFrame,
const nsPoint& aPointRelativeToRootFrame,
nsIFrame* aRestrictToDescendants,
const nsIFrame* aRestrictToDescendants,
const EventRadiusPrefs* aPrefs, uint32_t aFlags) {
nsMargin m(AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[0]),
AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[1]),
......@@ -296,7 +297,7 @@ static nsRect GetTargetRect(nsIFrame* aRootFrame,
// Don't clip this rect to the root scroll frame if the flag to ignore the
// root scroll frame is set. Note that the GetClosest code will still
// enforce that the target found is a descendant of aRestrictToDescendants.
r = ClipToFrame(aRootFrame, aRestrictToDescendants, r);
r = ClipToFrame(aRootFrame.mFrame, aRestrictToDescendants, r);
}
return r;
}
......@@ -340,11 +341,11 @@ static void SubtractFromExposedRegion(nsRegion* aExposedRegion,
}
}
static nsIFrame* GetClosest(nsIFrame* aRoot,
static nsIFrame* GetClosest(const nsIFrame* aRoot,
const nsPoint& aPointRelativeToRootFrame,
const nsRect& aTargetRect,
const EventRadiusPrefs* aPrefs,
nsIFrame* aRestrictToDescendants,
const nsIFrame* aRestrictToDescendants,
nsIContent* aClickableAncestor,
nsTArray<nsIFrame*>& aCandidates) {
nsIFrame* bestTarget = nullptr;
......@@ -356,7 +357,8 @@ static nsIFrame* GetClosest(nsIFrame* aRoot,
bool preservesAxisAlignedRectangles = false;
nsRect borderBox = nsLayoutUtils::TransformFrameRectToAncestor(
f, nsRect(nsPoint(0, 0), f->GetSize()), aRoot,
f, nsRect(nsPoint(0, 0), f->GetSize()),
RelativeTo{aRoot, ViewportType::Visual},
&preservesAxisAlignedRectangles);
PET_LOG("Checking candidate %p with border box %s\n", f,
mozilla::layers::Stringify(borderBox).c_str());
......@@ -419,7 +421,7 @@ static nsIFrame* GetClosest(nsIFrame* aRoot,
}
nsIFrame* FindFrameTargetedByInputEvent(
WidgetGUIEvent* aEvent, nsIFrame* aRootFrame,
WidgetGUIEvent* aEvent, RelativeTo aRootFrame,
const nsPoint& aPointRelativeToRootFrame, uint32_t aFlags) {
using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
EnumSet<FrameForPointOption> options;
......@@ -427,13 +429,13 @@ nsIFrame* FindFrameTargetedByInputEvent(
options += FrameForPointOption::IgnoreRootScrollFrame;
}
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(
aRootFrame, aPointRelativeToRootFrame, options);
aRootFrame.mFrame, aPointRelativeToRootFrame, options);
PET_LOG(
"Found initial target %p for event class %s message %s point %s "
"relative to root frame %p\n",
target, ToChar(aEvent->mClass), ToChar(aEvent->mMessage),
mozilla::layers::Stringify(aPointRelativeToRootFrame).c_str(),
aRootFrame);
aRootFrame.mFrame);
const EventRadiusPrefs* prefs = GetPrefsFor(aEvent->mClass);
if (!prefs || !prefs->mEnabled || EventRetargetSuppression::IsActive()) {
......@@ -467,23 +469,23 @@ nsIFrame* FindFrameTargetedByInputEvent(
// a mouse event handler for example, targets that are !GetClickableAncestor
// can never be targeted --- something nsSubDocumentFrame in an ancestor
// document would be targeted instead.
nsIFrame* restrictToDescendants =
target ? target->PresShell()->GetRootFrame() : aRootFrame;
const nsIFrame* restrictToDescendants =
target ? target->PresShell()->GetRootFrame() : aRootFrame.mFrame;
nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
restrictToDescendants, prefs, aFlags);
PET_LOG("Expanded point to target rect %s\n",
mozilla::layers::Stringify(targetRect).c_str());
AutoTArray<nsIFrame*, 8> candidates;
nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect,
nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame.mFrame, targetRect,
candidates, options);
if (NS_FAILED(rv)) {
return target;
}
nsIFrame* closestClickable =
GetClosest(aRootFrame, aPointRelativeToRootFrame, targetRect, prefs,
restrictToDescendants, clickableAncestor, candidates);
GetClosest(aRootFrame.mFrame, aPointRelativeToRootFrame, targetRect,
prefs, restrictToDescendants, clickableAncestor, candidates);
if (closestClickable) {
target = closestClickable;
}
......@@ -494,7 +496,7 @@ nsIFrame* FindFrameTargetedByInputEvent(
// Note that dumping the frame tree at the top of the function may flood
// logcat on Android devices and cause the PET_LOGs to get dropped.
if (MOZ_LOG_TEST(sEvtTgtLog, LogLevel::Verbose)) {
aRootFrame->DumpFrameTree();
aRootFrame.mFrame->DumpFrameTree();
}
#endif
......@@ -507,22 +509,22 @@ nsIFrame* FindFrameTargetedByInputEvent(
// clamp it to the bounds, and then make it relative to the root frame again.
nsPoint point = aPointRelativeToRootFrame;
if (nsLayoutUtils::TRANSFORM_SUCCEEDED !=
nsLayoutUtils::TransformPoint(aRootFrame, target, point)) {
nsLayoutUtils::TransformPoint(aRootFrame, RelativeTo{target}, point)) {
return target;
}
point = target->GetRectRelativeToSelf().ClampPoint(point);
if (nsLayoutUtils::TRANSFORM_SUCCEEDED !=
nsLayoutUtils::TransformPoint(target, aRootFrame, point)) {
nsLayoutUtils::TransformPoint(RelativeTo{target}, aRootFrame, point)) {
return target;
}
// Now we basically undo the operations in GetEventCoordinatesRelativeTo, to
// get back the (now-clamped) coordinates in the event's widget's space.
nsView* view = aRootFrame->GetView();
nsView* view = aRootFrame.mFrame->GetView();
if (!view) {
return target;
}
LayoutDeviceIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget(
aRootFrame->PresContext(), view, point, aEvent->mWidget);
aRootFrame.mFrame->PresContext(), view, point, aEvent->mWidget);
if (widgetPoint.x != NS_UNCONSTRAINEDSIZE) {
// If that succeeded, we update the point in the event
aEvent->mRefPoint = widgetPoint;
......
......@@ -9,6 +9,7 @@
#include <stdint.h>
#include "mozilla/EventForwards.h"
#include "nsLayoutUtils.h"
class nsIFrame;
struct nsPoint;
......@@ -22,7 +23,7 @@ enum { INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01 };
* that are suitable targets, to account for inaccurate pointing devices.
*/
nsIFrame* FindFrameTargetedByInputEvent(
WidgetGUIEvent* aEvent, nsIFrame* aRootFrame,
WidgetGUIEvent* aEvent, RelativeTo aRootFrame,
const nsPoint& aPointRelativeToRootFrame, uint32_t aFlags = 0);
class MOZ_RAII EventRetargetSuppression {
......
......@@ -6382,8 +6382,8 @@ void PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent) {
mPresContext, aEvent->mWidget, aEvent->mRefPoint, rootView);
mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
} else {
mMouseLocation =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
mMouseLocation = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{rootFrame});
mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
}
mMouseLocationWasSetBySynthesizedMouseEventForTests =
......@@ -6833,8 +6833,14 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
MOZ_ASSERT(aGUIEvent);
MOZ_ASSERT(aGUIEvent->mClass != eTouchEventClass);
nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aGUIEvent, aRootFrameToHandleEvent);
ViewportType viewportType = ViewportType::Layout;
if (aRootFrameToHandleEvent->Type() == LayoutFrameType::Viewport &&
aRootFrameToHandleEvent->PresContext()->IsRootContentDocument()) {
viewportType = ViewportType::Visual;
}
RelativeTo relativeTo{aRootFrameToHandleEvent, viewportType};
nsPoint eventPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aGUIEvent, relativeTo);
uint32_t flags = 0;
if (aGUIEvent->mClass == eMouseEventClass) {
......@@ -6844,8 +6850,8 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
}
}
nsIFrame* targetFrame = FindFrameTargetedByInputEvent(
aGUIEvent, aRootFrameToHandleEvent, eventPoint, flags);
nsIFrame* targetFrame =
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
if (!targetFrame) {
return aRootFrameToHandleEvent;
}
......@@ -6874,8 +6880,8 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
}
// Finally, we need to recompute the target with the latest layout.
targetFrame = FindFrameTargetedByInputEvent(
aGUIEvent, aRootFrameToHandleEvent, eventPoint, flags);
targetFrame =
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
return targetFrame ? targetFrame : aRootFrameToHandleEvent;
}
......@@ -11093,14 +11099,15 @@ nsIContent* PresShell::EventHandler::GetOverrideClickTarget(
WidgetMouseEvent* mouseEvent = aGUIEvent->AsMouseEvent();
uint32_t flags = 0;
RelativeTo relativeTo{aFrame};
nsPoint eventPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aGUIEvent, aFrame);
nsLayoutUtils::GetEventCoordinatesRelativeTo(aGUIEvent, relativeTo);
if (mouseEvent->mIgnoreRootScrollFrame) {
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
}
nsIFrame* target =
FindFrameTargetedByInputEvent(aGUIEvent, aFrame, eventPoint, flags);
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
if (!target) {
return nullptr;
}
......
......@@ -118,9 +118,10 @@ nsIFrame* TouchManager::SetupTarget(WidgetTouchEvent* aEvent,
int32_t id = touch->Identifier();
if (!TouchManager::HasCapturedTouch(id)) {
// find the target for this touch
RelativeTo relativeTo{aFrame};
nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, touch->mRefPoint, aFrame);
target = FindFrameTargetedByInputEvent(aEvent, aFrame, eventPoint);
aEvent, touch->mRefPoint, relativeTo);
target = FindFrameTargetedByInputEvent(aEvent, relativeTo, eventPoint);
if (target) {
nsCOMPtr<nsIContent> targetContent;
target->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
......
......@@ -34,6 +34,7 @@
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/Unused.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/ViewportUtils.h"
#include "nsCharTraits.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/Document.h"
......@@ -142,6 +143,7 @@
#include "TextDrawTarget.h"
#include "nsDeckFrame.h"
#include "mozilla/dom/InspectorFontFace.h"
#include "ViewportFrame.h"
#ifdef MOZ_XUL
# include "nsXULPopupManager.h"
......@@ -2186,11 +2188,11 @@ nsPoint nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(Event* aDOMEvent,
if (!aDOMEvent) return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
WidgetEvent* event = aDOMEvent->WidgetEventPtr();
if (!event) return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
return GetEventCoordinatesRelativeTo(event, aFrame);
return GetEventCoordinatesRelativeTo(event, RelativeTo{aFrame});
}
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
nsIFrame* aFrame) {
RelativeTo aFrame) {
if (!aEvent || (aEvent->mClass != eMouseEventClass &&
aEvent->mClass != eMouseScrollEventClass &&
aEvent->mClass != eWheelEventClass &&
......@@ -2208,8 +2210,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
const WidgetEvent* aEvent, const LayoutDeviceIntPoint& aPoint,
nsIFrame* aFrame) {
if (!aFrame) {
RelativeTo aFrame) {
if (!aFrame.mFrame) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
......@@ -2222,19 +2224,20 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
}
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame) {
if (!aFrame || !aWidget) {
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, RelativeTo aFrame) {
const nsIFrame* frame = aFrame.mFrame;
if (!frame || !aWidget) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
nsView* view = aFrame->GetView();
nsView* view = fr