Commit fc0e35e1 authored by Botond Ballo's avatar Botond Ballo
Browse files

Bug 1638594 - Handle layout coordinates relative to the RCD viewport frame...

Bug 1638594 - Handle layout coordinates relative to the RCD viewport frame correctly in the GetECRT slow-path. r=tnikkel, a=jcristau

Asking for layout coordinates relative to the RCD viewport frame
is a special case because the RCD viewport frame is outside the
zoom boundary, and so should technically always use visual
coordinates.

Nonetheless, we need to use layout coordinates relative to the
RCD viewport frame in several places, as we don't have a frame
that's inside the zoom boundary and sized to the initial
containing block (bug 1641279 may introduce such a frame in the
future).

This means GetEventCoordinatesRelativeTo needs special handling
to apply the visual-to-layout transform when converting from
visual coordinates relative to the root document's viewport
frame, to layout coordinates relative to the RCD viewport frame.

If the RCD is the root document, we take the fast-path which
handled this with an explicit check, but if the RCD is not the
root document, we take the slow-path which does not handle this.
This patch refactors GetECRT so it always checks for this
special case at the end.

Depends on D79589

Differential Revision: https://phabricator.services.mozilla.com/D79590
parent 4dee2ef8
...@@ -2219,8 +2219,9 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2219,8 +2219,9 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
return GetEventCoordinatesRelativeTo(widget, aPoint, aFrame); return GetEventCoordinatesRelativeTo(widget, aPoint, aFrame);
} }
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, RelativeTo aFrame) { const LayoutDeviceIntPoint& aPoint,
RelativeTo aFrame) {
const nsIFrame* frame = aFrame.mFrame; const nsIFrame* frame = aFrame.mFrame;
if (!frame || !aWidget) { if (!frame || !aWidget) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
...@@ -2236,11 +2237,7 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2236,11 +2237,7 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
nsPresContext* presContext = frame->PresContext(); nsPresContext* presContext = frame->PresContext();
nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x), nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x),
presContext->DevPixelsToAppUnits(aPoint.y)); presContext->DevPixelsToAppUnits(aPoint.y));
pt = pt - view->ViewToWidgetOffset(); return pt - view->ViewToWidgetOffset();
if (aFrame.mViewportType == ViewportType::Layout) {
pt = ViewportUtils::VisualToLayout(pt, frame->PresShell());
}
return pt;
} }
} }
...@@ -2250,7 +2247,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2250,7 +2247,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
*/ */
const nsIFrame* rootFrame = frame; const nsIFrame* rootFrame = frame;
bool transformFound = false; bool transformFound = false;
for (const nsIFrame* f = frame; f; f = GetCrossDocParentFrame(f)) { for (const nsIFrame* f = frame; f;
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
if (f->IsTransformed() || ViewportUtils::IsZoomedContentRoot(f)) { if (f->IsTransformed() || ViewportUtils::IsZoomedContentRoot(f)) {
transformFound = true; transformFound = true;
} }
...@@ -2263,8 +2261,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2263,8 +2261,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
} }
nsPoint widgetToView = TranslateWidgetToView(rootFrame->PresContext(), nsPoint widgetToView = nsLayoutUtils::TranslateWidgetToView(
aWidget, aPoint, rootView); rootFrame->PresContext(), aWidget, aPoint, rootView);
if (widgetToView == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) { if (widgetToView == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
...@@ -2280,8 +2278,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2280,8 +2278,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
* out how to convert back to aFrame's coordinates and must use the CTM. * out how to convert back to aFrame's coordinates and must use the CTM.
*/ */
if (transformFound || nsSVGUtils::IsInSVGTextSubtree(frame)) { if (transformFound || nsSVGUtils::IsInSVGTextSubtree(frame)) {
return TransformRootPointToFrame(ViewportType::Visual, aFrame, return nsLayoutUtils::TransformRootPointToFrame(ViewportType::Visual,
widgetToView); aFrame, widgetToView);
} }
/* Otherwise, all coordinate systems are translations of one another, /* Otherwise, all coordinate systems are translations of one another,
...@@ -2290,6 +2288,17 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo( ...@@ -2290,6 +2288,17 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
return widgetToView - frame->GetOffsetToCrossDoc(rootFrame); return widgetToView - frame->GetOffsetToCrossDoc(rootFrame);
} }
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, RelativeTo aFrame) {
nsPoint result = ::GetEventCoordinatesRelativeTo(aWidget, aPoint, aFrame);
if (aFrame.mViewportType == ViewportType::Layout && aFrame.mFrame &&
aFrame.mFrame->Type() == LayoutFrameType::Viewport &&
aFrame.mFrame->PresContext()->IsRootContentDocumentCrossProcess()) {
result = ViewportUtils::VisualToLayout(result, aFrame.mFrame->PresShell());
}
return result;
}
nsIFrame* nsLayoutUtils::GetPopupFrameForEventCoordinates( nsIFrame* nsLayoutUtils::GetPopupFrameForEventCoordinates(
nsPresContext* aPresContext, const WidgetEvent* aEvent) { nsPresContext* aPresContext, const WidgetEvent* aEvent) {
#ifdef MOZ_XUL #ifdef MOZ_XUL
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment