Backed out 30 changesets (bug 1556556, bug 1631568) for multiple mochitest failures. CLOSED TREE

Backed out changeset edd529f7a9c5 (bug 1631568)
Backed out changeset 1cc0881e244b (bug 1631568)
Backed out changeset ed3c1e85d5e3 (bug 1556556)
Backed out changeset 38ffc6215bbf (bug 1556556)
Backed out changeset 03c2c25d8023 (bug 1556556)
Backed out changeset 9c717eb067b8 (bug 1556556)
Backed out changeset 98e26bc98b85 (bug 1556556)
Backed out changeset 05a6a581e755 (bug 1556556)
Backed out changeset 867946cf05bb (bug 1556556)
Backed out changeset 20d72a334530 (bug 1556556)
Backed out changeset 2c62e61d9054 (bug 1556556)
Backed out changeset 62a223d057d2 (bug 1556556)
Backed out changeset 2c5d55a1f0b1 (bug 1556556)
Backed out changeset 700447945b4e (bug 1556556)
Backed out changeset 93190ae4f5ff (bug 1556556)
Backed out changeset a7bd34d961bb (bug 1556556)
Backed out changeset fccd1d3c7189 (bug 1556556)
Backed out changeset 24056e47183d (bug 1556556)
Backed out changeset 204881474cc1 (bug 1556556)
Backed out changeset 387320881876 (bug 1556556)
Backed out changeset be8f5eb58460 (bug 1556556)
Backed out changeset 629c58a9166b (bug 1556556)
Backed out changeset 4312b2b5dda8 (bug 1556556)
Backed out changeset d11dbf6403a5 (bug 1556556)
Backed out changeset 95c54c023779 (bug 1556556)
Backed out changeset 80fcb7e71188 (bug 1556556)
Backed out changeset d75a4ecb0d47 (bug 1556556)
Backed out changeset 903c4de34e7a (bug 1556556)
Backed out changeset f15334a3e803 (bug 1556556)
Backed out changeset 9553e99137ea (bug 1556556)
This commit is contained in:
Csoregi Natalia 2020-04-28 12:43:11 +03:00
parent 879ef8e0a4
commit b073baab86
70 changed files with 566 additions and 871 deletions

View File

@ -99,7 +99,7 @@ void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
nsRect scrollPort = sf ? sf->GetScrollPortRect() : rootFrame->GetRect();
nsLayoutUtils::GetFramesForArea(
RelativeTo{presShell->GetRootFrame()}, scrollPort, frames,
presShell->GetRootFrame(), scrollPort, frames,
nsLayoutUtils::FrameForPointOption::OnlyVisible);
AccessibleHashtable inViewAccs;
for (size_t i = 0; i < frames.Length(); i++) {

View File

@ -527,8 +527,26 @@ Accessible* Accessible::ChildAtPoint(int32_t aX, int32_t aY,
nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.X(),
presContext->DevPixelsToAppUnits(aY) - screenRect.Y());
nsIFrame* foundFrame = nsLayoutUtils::GetFrameForPoint(
RelativeTo{startFrame, ViewportType::Visual}, offset);
// We need to take into account a non-1 resolution set on the presshell.
// This happens in mobile platforms with async pinch zooming.
offset = offset.RemoveResolution(presContext->PresShell()->GetResolution());
// We need to translate with the offset of the edge of the visual
// viewport from top edge of the layout viewport.
offset += presContext->PresShell()->GetVisualViewportOffset() -
presContext->PresShell()->GetLayoutViewportOffset();
EnumSet<nsLayoutUtils::FrameForPointOption> options = {
#ifdef MOZ_WIDGET_ANDROID
// This is needed in Android to ignore the clipping of the scroll frame
// when zoomed in. May regress something on other platforms, so
// keeping it Android-exclusive for now.
nsLayoutUtils::FrameForPointOption::IgnoreRootScrollFrame
#endif
};
nsIFrame* foundFrame =
nsLayoutUtils::GetFrameForPoint(startFrame, offset, options);
nsIContent* content = nullptr;
if (!foundFrame || !(content = foundFrame->GetContent()))

View File

@ -12322,7 +12322,7 @@ already_AddRefed<nsDOMCaretPosition> Document::CaretPositionFromPoint(
}
nsIFrame* ptFrame = nsLayoutUtils::GetFrameForPoint(
RelativeTo{rootFrame}, pt,
rootFrame, pt,
{FrameForPointOption::IgnorePaintSuppression,
FrameForPointOption::IgnoreCrossDoc});
if (!ptFrame) {
@ -12334,8 +12334,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, RelativeTo{ptFrame});
nsPoint adjustedPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, refPoint, ptFrame);
nsFrame::ContentOffsets offsets =
ptFrame->GetContentOffsetsFromPoint(adjustedPoint);

View File

@ -363,7 +363,7 @@ template <typename NodeOrElement>
static void QueryNodesFromRect(DocumentOrShadowRoot& aRoot, const nsRect& aRect,
EnumSet<FrameForPointOption> aOptions,
FlushLayout aShouldFlushLayout,
Multiple aMultiple, ViewportType aViewportType,
Multiple aMultiple,
nsTArray<RefPtr<NodeOrElement>>& aNodes) {
static_assert(std::is_same<nsINode, NodeOrElement>::value ||
std::is_same<Element, NodeOrElement>::value,
@ -395,8 +395,7 @@ static void QueryNodesFromRect(DocumentOrShadowRoot& aRoot, const nsRect& aRect,
aOptions += FrameForPointOption::IgnoreCrossDoc;
AutoTArray<nsIFrame*, 8> frames;
nsLayoutUtils::GetFramesForArea({rootFrame, aViewportType}, aRect, frames,
aOptions);
nsLayoutUtils::GetFramesForArea(rootFrame, aRect, frames, aOptions);
for (nsIFrame* frame : frames) {
nsIContent* content = doc->GetContentInThisDocument(frame);
@ -440,7 +439,7 @@ template <typename NodeOrElement>
static void QueryNodesFromPoint(DocumentOrShadowRoot& aRoot, float aX, float aY,
EnumSet<FrameForPointOption> aOptions,
FlushLayout aShouldFlushLayout,
Multiple aMultiple, ViewportType aViewportType,
Multiple aMultiple,
nsTArray<RefPtr<NodeOrElement>>& aNodes) {
// As per the spec, we return null if either coord is negative.
if (!aOptions.contains(FrameForPointOption::IgnoreRootScrollFrame) &&
@ -452,37 +451,35 @@ static void QueryNodesFromPoint(DocumentOrShadowRoot& aRoot, float aX, float aY,
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
QueryNodesFromRect(aRoot, nsRect(pt, nsSize(1, 1)), aOptions,
aShouldFlushLayout, aMultiple, aViewportType, aNodes);
aShouldFlushLayout, aMultiple, aNodes);
}
} // namespace
Element* DocumentOrShadowRoot::ElementFromPoint(float aX, float aY) {
return ElementFromPointHelper(aX, aY, false, true, ViewportType::Layout);
return ElementFromPointHelper(aX, aY, false, true);
}
void DocumentOrShadowRoot::ElementsFromPoint(
float aX, float aY, nsTArray<RefPtr<Element>>& aElements) {
QueryNodesFromPoint(*this, aX, aY, {}, FlushLayout::Yes, Multiple::Yes,
ViewportType::Layout, aElements);
aElements);
}
void DocumentOrShadowRoot::NodesFromPoint(float aX, float aY,
nsTArray<RefPtr<nsINode>>& aNodes) {
QueryNodesFromPoint(*this, aX, aY, {}, FlushLayout::Yes, Multiple::Yes,
ViewportType::Layout, aNodes);
aNodes);
}
nsINode* DocumentOrShadowRoot::NodeFromPoint(float aX, float aY) {
AutoTArray<RefPtr<nsINode>, 1> nodes;
QueryNodesFromPoint(*this, aX, aY, {}, FlushLayout::Yes, Multiple::No,
ViewportType::Layout, nodes);
QueryNodesFromPoint(*this, aX, aY, {}, FlushLayout::Yes, Multiple::No, nodes);
return nodes.SafeElementAt(0);
}
Element* DocumentOrShadowRoot::ElementFromPointHelper(
float aX, float aY, bool aIgnoreRootScrollFrame, bool aFlushLayout,
ViewportType aViewportType) {
float aX, float aY, bool aIgnoreRootScrollFrame, bool aFlushLayout) {
EnumSet<FrameForPointOption> options;
if (aIgnoreRootScrollFrame) {
options += FrameForPointOption::IgnoreRootScrollFrame;
@ -491,8 +488,7 @@ Element* DocumentOrShadowRoot::ElementFromPointHelper(
auto flush = aFlushLayout ? FlushLayout::Yes : FlushLayout::No;
AutoTArray<RefPtr<Element>, 1> elements;
QueryNodesFromPoint(*this, aX, aY, options, flush, Multiple::No,
aViewportType, elements);
QueryNodesFromPoint(*this, aX, aY, options, flush, Multiple::No, elements);
return elements.SafeElementAt(0);
}
@ -524,8 +520,7 @@ void DocumentOrShadowRoot::NodesFromRect(float aX, float aY, float aTopSize,
}
auto flush = aFlushLayout ? FlushLayout::Yes : FlushLayout::No;
QueryNodesFromRect(*this, rect, options, flush, Multiple::Yes,
ViewportType::Layout, aReturn);
QueryNodesFromRect(*this, rect, options, flush, Multiple::Yes, aReturn);
}
Element* DocumentOrShadowRoot::AddIDTargetObserver(nsAtom* aID,

View File

@ -9,7 +9,6 @@
#include "mozilla/dom/NameSpaceConstants.h"
#include "mozilla/IdentifierMapEntry.h"
#include "mozilla/RelativeTo.h"
#include "nsClassHashtable.h"
#include "nsContentListDeclarations.h"
#include "nsTArray.h"
@ -136,8 +135,7 @@ class DocumentOrShadowRoot {
*/
Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout,
ViewportType aViewportType);
bool aFlushLayout);
void NodesFromRect(float aX, float aY, float aTopSize, float aRightSize,
float aBottomSize, float aLeftSize,

View File

@ -3227,9 +3227,8 @@ 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(RelativeTo{primaryFrame},
RelativeTo{ancestorFrame},
nsIFrame::IN_CSS_UNITS)
transform = nsLayoutUtils::GetTransformToAncestor(
primaryFrame, ancestorFrame, nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}
@ -3244,8 +3243,7 @@ already_AddRefed<DOMMatrixReadOnly> Element::GetTransformToParent() {
Matrix4x4 transform;
if (primaryFrame) {
nsIFrame* parentFrame = primaryFrame->GetParent();
transform = nsLayoutUtils::GetTransformToAncestor(RelativeTo{primaryFrame},
RelativeTo{parentFrame},
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame, parentFrame,
nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}
@ -3261,8 +3259,7 @@ already_AddRefed<DOMMatrixReadOnly> Element::GetTransformToViewport() {
if (primaryFrame) {
transform =
nsLayoutUtils::GetTransformToAncestor(
RelativeTo{primaryFrame},
RelativeTo{nsLayoutUtils::GetDisplayRootFrame(primaryFrame)},
primaryFrame, nsLayoutUtils::GetDisplayRootFrame(primaryFrame),
nsIFrame::IN_CSS_UNITS)
.GetMatrix();
}

View File

@ -115,7 +115,6 @@
#include "mozilla/TextControlState.h"
#include "mozilla/TextEditor.h"
#include "mozilla/TextEvents.h"
#include "mozilla/ViewportUtils.h"
#include "nsArrayUtils.h"
#include "nsAString.h"
#include "nsAttrName.h"
@ -7866,11 +7865,11 @@ int16_t nsContentUtils::GetButtonsFlagForButton(int32_t aButton) {
LayoutDeviceIntPoint nsContentUtils::ToWidgetPoint(
const CSSPoint& aPoint, const nsPoint& aOffset,
nsPresContext* aPresContext) {
nsPoint layoutRelative = CSSPoint::ToAppUnits(aPoint) + aOffset;
nsPoint visualRelative =
ViewportUtils::LayoutToVisual(layoutRelative, aPresContext->PresShell());
return LayoutDeviceIntPoint::FromAppUnitsRounded(
visualRelative, aPresContext->AppUnitsPerDevPixel());
(CSSPoint::ToAppUnits(aPoint) + aOffset)
.ApplyResolution(nsLayoutUtils::GetCurrentAPZResolutionScale(
aPresContext->PresShell())),
aPresContext->AppUnitsPerDevPixel());
}
nsView* nsContentUtils::GetViewToDispatchEvent(nsPresContext* aPresContext,

View File

@ -1155,8 +1155,8 @@ nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
nsCOMPtr<Document> doc = GetDocument();
NS_ENSURE_STATE(doc);
RefPtr<Element> el = doc->ElementFromPointHelper(
aX, aY, aIgnoreRootScrollFrame, aFlushLayout, ViewportType::Layout);
RefPtr<Element> el =
doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
el.forget(aReturn);
return NS_OK;
}
@ -3231,10 +3231,9 @@ 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, RelativeTo{rootFrame});
nsIFrame* targetFrame =
nsLayoutUtils::GetFrameForPoint(RelativeTo{rootFrame}, ptInRoot);
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, 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.
if (!targetFrame) {
@ -3243,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, RelativeTo{targetFrame});
nsPoint relPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
nsresult rv = static_cast<nsFrame*>(targetFrame)
->SelectByTypeAtPoint(GetPresContext(), relPoint, amount,

View File

@ -2549,11 +2549,10 @@ nsresult ContentEventHandler::OnQueryCharacterAtPoint(
eventOnRoot.mRefPoint += aEvent->mWidget->WidgetToScreenOffset() -
rootWidget->WidgetToScreenOffset();
}
nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(
&eventOnRoot, RelativeTo{rootFrame});
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame);
nsIFrame* targetFrame =
nsLayoutUtils::GetFrameForPoint(RelativeTo{rootFrame}, ptInRoot);
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
if (!targetFrame || !targetFrame->GetContent() ||
!targetFrame->GetContent()->IsInclusiveDescendantOf(mRootContent)) {
// There is no character at the point.
@ -2649,7 +2648,7 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
docFrameRect.y);
Element* contentUnderMouse = mDocument->ElementFromPointHelper(
eventLocCSS.x, eventLocCSS.y, false, false, ViewportType::Visual);
eventLocCSS.x, eventLocCSS.y, false, false);
if (contentUnderMouse) {
nsIWidget* targetWidget = nullptr;
nsIFrame* targetFrame = contentUnderMouse->GetPrimaryFrame();

View File

@ -21,7 +21,6 @@
#include "mozilla/PresShell.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/dom/Event.h"
@ -550,8 +549,9 @@ CSSIntPoint Event::GetScreenCoords(nsPresContext* aPresContext,
rounded,
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
if (PresShell* shell = aPresContext->GetPresShell()) {
pt = ViewportUtils::VisualToLayout(pt, shell);
if (PresShell* presShell = aPresContext->GetPresShell()) {
pt = pt.RemoveResolution(
nsLayoutUtils::GetCurrentAPZResolutionScale(presShell));
}
pt += LayoutDevicePixel::ToAppUnits(
@ -612,8 +612,8 @@ CSSIntPoint Event::GetClientCoords(nsPresContext* aPresContext,
if (!rootFrame) {
return CSSIntPoint(0, 0);
}
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, aPoint, RelativeTo{rootFrame});
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, 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(RelativeTo{rootFrame}, RelativeTo{frame},
pt) == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
if (nsLayoutUtils::TransformPoint(rootFrame, frame, pt) ==
nsLayoutUtils::TRANSFORM_SUCCEEDED) {
pt -= frame->GetPaddingRectRelativeToSelf().TopLeft();
return CSSPixel::FromAppUnitsRounded(pt);
}

View File

@ -3809,7 +3809,7 @@ static bool ShouldBlockCustomCursor(nsPresContext* aPresContext,
}
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{topLevel->PresShell()->GetRootFrame()});
aEvent, topLevel->PresShell()->GetRootFrame());
nsSize size(CSSPixel::ToAppUnits(width), CSSPixel::ToAppUnits(height));
nsPoint hotspot(CSSPixel::ToAppUnits(aCursor.mHotspot.x),
@ -3904,8 +3904,8 @@ void EventStateManager::UpdateCursor(nsPresContext* aPresContext,
}
// If not locked, look for correct cursor
else if (aTargetFrame) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{aTargetFrame});
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aTargetFrame);
Maybe<nsIFrame::Cursor> framecursor = aTargetFrame->GetCursor(pt);
// Avoid setting cursor when the mouse is over a windowless plugin.
if (!framecursor) {

View File

@ -181,8 +181,7 @@ nsIntPoint UIEvent::GetLayerPoint() const {
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
if (!targetFrame) return mLayerPoint;
nsIFrame* layer = nsLayoutUtils::GetClosestLayer(targetFrame);
nsPoint pt(
nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, RelativeTo{layer}));
nsPoint pt(nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, layer));
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
}

View File

@ -563,7 +563,7 @@ void HTMLCanvasElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
return;
}
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(evt, RelativeTo{frame});
nsLayoutUtils::GetEventCoordinatesRelativeTo(evt, frame);
nsRect paddingRect = frame->GetContentRectRelativeToSelf();
Point hitpoint;
hitpoint.x = (ptInRoot.x - paddingRect.x) / AppUnitsPerCSSPixel();

View File

@ -1339,13 +1339,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvHandleTap(
}
CSSToLayoutDeviceScale scale(
presShell->GetPresContext()->CSSToDevPixelScale());
CSSPoint point = aPoint / scale;
// Stash the guid in InputAPZContext so that when the visual-to-layout
// transform is applied to the event's coordinates, we use the right transform
// based on the scroll frame being targeted.
// The other values don't really matter.
InputAPZContext context(aGuid, aInputBlockId, nsEventStatus_eSentinel);
CSSPoint point =
APZCCallbackHelper::ApplyCallbackTransform(aPoint / scale, aGuid);
switch (aType) {
case GeckoContentController::TapType::eSingleTap:
@ -1640,16 +1635,6 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseButtonEvent(
void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) {
WidgetMouseEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
// We need one InputAPZContext here to propagate |aGuid| to places in
// SendSetTargetAPZCNotification() which apply the visual-to-layout transform,
// and another below to propagate the |postLayerization| flag (whose value
// we don't know until SendSetTargetAPZCNotification() returns) into
// the event dispatch code.
InputAPZContext context1(aGuid, aInputBlockId, nsEventStatus_eSentinel);
// Mouse events like eMouseEnterIntoWidget, that are created in the parent
// process EventStateManager code, have an input block id which they get from
// the InputAPZContext in the parent process stack. However, they did not
@ -1657,19 +1642,23 @@ void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
// Since thos events didn't go through APZ, we don't need to send
// notifications for them.
UniquePtr<DisplayportSetListener> postLayerization;
if (aInputBlockId && localEvent.mFlags.mHandledByAPZ) {
if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
nsCOMPtr<Document> document(GetTopLevelDocument());
postLayerization = APZCCallbackHelper::SendSetTargetAPZCNotification(
mPuppetWidget, document, localEvent, aGuid.mLayersId, aInputBlockId);
mPuppetWidget, document, aEvent, aGuid.mLayersId, aInputBlockId);
}
InputAPZContext context2(aGuid, aInputBlockId, nsEventStatus_eSentinel,
postLayerization != nullptr);
InputAPZContext context(aGuid, aInputBlockId, nsEventStatus_eIgnore,
postLayerization != nullptr);
WidgetMouseEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
DispatchWidgetEventViaAPZ(localEvent);
if (aInputBlockId && localEvent.mFlags.mHandledByAPZ) {
mAPZEventState->ProcessMouseEvent(localEvent, aInputBlockId);
if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
mAPZEventState->ProcessMouseEvent(aEvent, aInputBlockId);
}
// Do this after the DispatchWidgetEventViaAPZ call above, so that if the
@ -1756,13 +1745,8 @@ void BrowserChild::DispatchWheelEvent(const WidgetWheelEvent& aEvent,
}
localEvent.mWidget = mPuppetWidget;
// Stash the guid in InputAPZContext so that when the visual-to-layout
// transform is applied to the event's coordinates, we use the right transform
// based on the scroll frame being targeted.
// The other values don't really matter.
InputAPZContext context(aGuid, aInputBlockId, nsEventStatus_eSentinel);
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
DispatchWidgetEventViaAPZ(localEvent);
if (localEvent.mCanTriggerSwipe) {
@ -1816,11 +1800,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchEvent(
WidgetTouchEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
// Stash the guid in InputAPZContext so that when the visual-to-layout
// transform is applied to the event's coordinates, we use the right transform
// based on the scroll frame being targeted.
// The other values don't really matter.
InputAPZContext context(aGuid, aInputBlockId, aApzResponse);
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
nsCOMPtr<Document> document = GetTopLevelDocument();

View File

@ -2452,14 +2452,9 @@ LayoutDeviceIntPoint BrowserParent::GetChildProcessOffset() {
// any events we send to the child, and reverse them for any screen
// coordinates that we retrieve from the child.
// TODO: Once we take into account transforms here, set viewportType
// correctly. For now we use Visual as this means we don't apply
// the layout-to-visual transform in TranslateViewToWidget().
ViewportType viewportType = ViewportType::Visual;
nsPoint pt = targetFrame->GetOffsetTo(rootFrame);
return -nsLayoutUtils::TranslateViewToWidget(presContext, rootView, pt,
viewportType, widget);
widget);
}
LayoutDeviceIntPoint BrowserParent::GetClientOffset() {

View File

@ -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, RelativeTo{aObjectFrame}) -
aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(anEvent, 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, RelativeTo{mPluginFrame}) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, 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, RelativeTo{mPluginFrame}) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();

View File

@ -62,6 +62,17 @@ APZEventResult APZInputBridge::ReceiveInputEvent(WidgetInputEvent& aEvent) {
UpdateWheelTransaction(mouseEvent.mRefPoint, mouseEvent.mMessage);
}
// If zooming is enabled, mark the mouse event as "ignore root
// scroll frame". This ensures that the main-thread hit test the
// mouse event undergoes (in PositionedEventTargeting.cpp) uses
// the IGNORE_ROOT_SCROLL_FRAME flag, which is needed for correct
// hit testing in a zoomed-in or zoomed-out state.
// FIXME: bug 1525793 -- this may need to handle zooming or not on a
// per-document basis.
if (StaticPrefs::apz_allow_zooming()) {
mouseEvent.mIgnoreRootScrollFrame = true;
}
if (WillHandleMouseEvent(mouseEvent)) {
MouseInput input(mouseEvent);
input.mOrigin =

View File

@ -19,8 +19,9 @@ var subtests = [
// Test for dragging on the scrollbar of the root scrollable element works.
// This takes different codepaths with async zooming support enabled and
// disabled, and so needs to be tested separately for both.
// TODO(bug 1556556): Once we get this working with zooming enabled,
// add an entry to run this with apz.allow_zooming=true as well.
{"file": "helper_drag_root_scrollbar.html", "prefs": [["apz.allow_zooming", false]]},
{"file": "helper_drag_root_scrollbar.html", "prefs": [["apz.allow_zooming", true]]},
// Test for dragging on a fake-scrollbar element that scrolls the page
{"file": "helper_drag_scroll.html"},
// Test for dragging the scrollbar with a fixed-pos element overlaying it

View File

@ -20,7 +20,6 @@
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/PresShell.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/ViewportUtils.h"
#include "nsContainerFrame.h"
#include "nsContentUtils.h"
#include "nsIContent.h"
@ -452,6 +451,89 @@ PresShell* APZCCallbackHelper::GetRootContentDocumentPresShellForContent(
return context->PresShell();
}
static PresShell* GetRootDocumentPresShell(nsIContent* aContent) {
dom::Document* doc = aContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
PresShell* presShell = doc->GetPresShell();
if (!presShell) {
return nullptr;
}
nsPresContext* context = presShell->GetPresContext();
if (!context) {
return nullptr;
}
context = context->GetRootPresContext();
if (!context) {
return nullptr;
}
return context->PresShell();
}
CSSPoint APZCCallbackHelper::ApplyCallbackTransform(
const CSSPoint& aInput, const ScrollableLayerGuid& aGuid) {
CSSPoint input = aInput;
if (aGuid.mScrollId == ScrollableLayerGuid::NULL_SCROLL_ID) {
return input;
}
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
if (!content) {
return input;
}
// First, scale inversely by the root content document's pres shell
// resolution to cancel the scale-to-resolution transform that the
// compositor adds to the layer with the pres shell resolution. The points
// sent to Gecko by APZ don't have this transform unapplied (unlike other
// compositor-side transforms) because APZ doesn't know about it.
if (PresShell* presShell = GetRootDocumentPresShell(content)) {
input = input / presShell->GetResolution();
}
// This represents any resolution on the Root Content Document (RCD)
// that's not on the Root Document (RD). That is, on platforms where
// RCD == RD, it's 1, and on platforms where RCD != RD, it's the RCD
// resolution. 'input' has this resolution applied, but the scroll
// delta retrieved below do not, so we need to apply them to the
// delta before adding the delta to 'input'. (Technically, deltas
// from scroll frames outside the RCD would already have this
// resolution applied, but we don't have such scroll frames in
// practice.)
float nonRootResolution = 1.0f;
if (PresShell* presShell =
GetRootContentDocumentPresShellForContent(content)) {
nonRootResolution = presShell->GetCumulativeNonRootScaleResolution();
}
// Now apply the callback-transform. This is only approximately correct,
// see the comment on GetCumulativeApzCallbackTransform for details.
CSSPoint transform = nsLayoutUtils::GetCumulativeApzCallbackTransform(
content->GetPrimaryFrame());
return input + transform * nonRootResolution;
}
LayoutDeviceIntPoint APZCCallbackHelper::ApplyCallbackTransform(
const LayoutDeviceIntPoint& aPoint, const ScrollableLayerGuid& aGuid,
const CSSToLayoutDeviceScale& aScale) {
LayoutDevicePoint point = LayoutDevicePoint(aPoint.x, aPoint.y);
point = ApplyCallbackTransform(point / aScale, aGuid) * aScale;
return LayoutDeviceIntPoint::Round(point);
}
void APZCCallbackHelper::ApplyCallbackTransform(
WidgetEvent& aEvent, const ScrollableLayerGuid& aGuid,
const CSSToLayoutDeviceScale& aScale) {
if (aEvent.AsTouchEvent()) {
WidgetTouchEvent& event = *(aEvent.AsTouchEvent());
for (size_t i = 0; i < event.mTouches.Length(); i++) {
event.mTouches[i]->mRefPoint =
ApplyCallbackTransform(event.mTouches[i]->mRefPoint, aGuid, aScale);
}
} else {
aEvent.mRefPoint = ApplyCallbackTransform(aEvent.mRefPoint, aGuid, aScale);
}
}
nsEventStatus APZCCallbackHelper::DispatchWidgetEvent(WidgetGUIEvent& aEvent) {
nsEventStatus status = nsEventStatus_eConsumeNoDefault;
if (aEvent.mWidget) {
@ -475,6 +557,7 @@ nsEventStatus APZCCallbackHelper::DispatchSynthesizedMouseEvent(
if (aMsg == eMouseLongTap) {
event.mFlags.mOnlyChromeDispatch = true;
}
event.mIgnoreRootScrollFrame = true;
if (aMsg != eMouseMove) {
event.mClickCount = aClickCount;
}
@ -550,6 +633,24 @@ static dom::Element* GetRootDocumentElementFor(nsIWidget* aWidget) {
return nullptr;
}
static nsIFrame* UpdateRootFrameForTouchTargetDocument(nsIFrame* aRootFrame) {
#if defined(MOZ_WIDGET_ANDROID)
// Re-target so that the hit test is performed relative to the frame for the
// Root Content Document instead of the Root Document which are different in
// Android. See bug 1229752 comment 16 for an explanation of why this is
// necessary.
if (dom::Document* doc =
aRootFrame->PresShell()->GetPrimaryContentDocument()) {
if (PresShell* presShell = doc->GetPresShell()) {
if (nsIFrame* frame = presShell->GetRootFrame()) {
return frame;
}
}
}
#endif
return aRootFrame;
}
namespace {
using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
@ -565,10 +666,19 @@ static bool PrepareForSetTargetAPZCNotification(
const LayoutDeviceIntPoint& aRefPoint,
nsTArray<ScrollableLayerGuid>* aTargets) {
ScrollableLayerGuid guid(aLayersId, 0, ScrollableLayerGuid::NULL_SCROLL_ID);
RelativeTo relativeTo{aRootFrame, ViewportType::Visual};
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aWidget, aRefPoint, relativeTo);
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(relativeTo, point);
aWidget, aRefPoint, aRootFrame);
EnumSet<FrameForPointOption> options;
if (nsLayoutUtils::AllowZoomingForDocument(
aRootFrame->PresShell()->GetDocument())) {
// If zooming is enabled, we need IgnoreRootScrollFrame for correct
// hit testing. Otherwise, don't use it because it interferes with
// hit testing for some purposes such as scrollbar dragging (this will
// need to be fixed before enabling zooming by default on desktop).
options += FrameForPointOption::IgnoreRootScrollFrame;
}
nsIFrame* target =
nsLayoutUtils::GetFrameForPoint(aRootFrame, point, options);
nsIScrollableFrame* scrollAncestor =
target ? nsLayoutUtils::GetAsyncScrollableAncestorFrame(target)
: aRootFrame->PresShell()->GetRootScrollFrameAsScrollable();
@ -726,6 +836,8 @@ APZCCallbackHelper::SendSetTargetAPZCNotification(nsIWidget* aWidget,
sLastTargetAPZCNotificationInputBlock = aInputBlockId;
if (PresShell* presShell = aDocument->GetPresShell()) {
if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
bool waitForRefresh = false;
nsTArray<ScrollableLayerGuid> targets;
@ -770,11 +882,12 @@ void APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
}
if (PresShell* presShell = aDocument->GetPresShell()) {
if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
nsTArray<TouchBehaviorFlags> flags;
for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
flags.AppendElement(TouchActionHelper::GetAllowedTouchBehavior(
aWidget, RelativeTo{rootFrame, ViewportType::Visual},
aEvent.mTouches[i]->mRefPoint));
aWidget, rootFrame, aEvent.mTouches[i]->mRefPoint));
}
aCallback(aInputBlockId, std::move(flags));
}

View File

@ -8,7 +8,6 @@
#include "InputData.h"
#include "LayersTypes.h"
#include "Units.h"
#include "mozilla/EventForwards.h"
#include "mozilla/layers/APZUtils.h"
#include "mozilla/layers/MatrixMessage.h"
@ -98,6 +97,29 @@ class APZCCallbackHelper {
static PresShell* GetRootContentDocumentPresShellForContent(
nsIContent* aContent);
/* Apply an "input transform" to the given |aInput| and return the transformed
value. The input transform applied is the one for the content element
corresponding to |aGuid|; this is populated in a previous call to
UpdateCallbackTransform. See that method's documentations for details. This
method additionally adjusts |aInput| by inversely scaling by the provided
pres shell resolution, to cancel out a compositor-side transform (added in
bug 1076241) that APZ doesn't unapply. */
static CSSPoint ApplyCallbackTransform(const CSSPoint& aInput,
const ScrollableLayerGuid& aGuid);
/* Same as above, but operates on LayoutDeviceIntPoint.
Requires an additonal |aScale| parameter to convert between CSS and
LayoutDevice space. */
static mozilla::LayoutDeviceIntPoint ApplyCallbackTransform(
const LayoutDeviceIntPoint& aPoint, const ScrollableLayerGuid& aGuid,
const CSSToLayoutDeviceScale& aScale);
/* Convenience function for applying a callback transform to all refpoints
* in the input event. */
static void ApplyCallbackTransform(WidgetEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const CSSToLayoutDeviceScale& aScale);
/* Dispatch a widget event via the widget stored in the event, if any.
* In a child process, allows the BrowserParent event-capture mechanism to
* intercept the event. */

View File

@ -15,7 +15,6 @@
#include "mozilla/layers/APZEventState.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/IAPZCTreeManager.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/DoubleTapToZoom.h"
#include "mozilla/dom/Document.h"
#include "nsIInterfaceRequestorUtils.h"
@ -140,7 +139,14 @@ void ChromeProcessController::HandleDoubleTap(
return;
}
CSSRect zoomToRect = CalculateRectToZoomTo(document, aPoint);
// CalculateRectToZoomTo performs a hit test on the frame associated with the
// Root Content Document. Unfortunately that frame does not know about the
// resolution of the document and so we must remove it before calculating
// the zoomToRect.
PresShell* presShell = document->GetPresShell();
const float resolution = presShell->GetResolution();
CSSPoint point(aPoint.x / resolution, aPoint.y / resolution);
CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
uint32_t presShellId;
ScrollableLayerGuid::ViewID viewId;
@ -185,14 +191,8 @@ void ChromeProcessController::HandleTap(
}
CSSToLayoutDeviceScale scale(
presShell->GetPresContext()->CSSToDevPixelScale());
CSSPoint point = aPoint / scale;
// Stash the guid in InputAPZContext so that when the visual-to-layout
// transform is applied to the event's coordinates, we use the right transform
// based on the scroll frame being targeted.
// The other values don't really matter.
InputAPZContext context(aGuid, aInputBlockId, nsEventStatus_eSentinel);
CSSPoint point =
APZCCallbackHelper::ApplyCallbackTransform(aPoint / scale, aGuid);
switch (aType) {
case TapType::eSingleTap:

View File

@ -27,12 +27,13 @@ namespace {
using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
// Returns the DOM element found at |aPoint|, interpreted as being relative to
// the root frame of |aPresShell| in visual coordinates. If the point is inside
// a subdocument, returns an element inside the subdocument, rather than the
// subdocument element (and does so recursively). The implementation was adapted
// from DocumentOrShadowRoot::ElementFromPoint(), with the notable exception
// that we don't pass nsLayoutUtils::IGNORE_CROSS_DOC to GetFrameForPoint(), so
// as to get the behaviour described above in the presence of subdocuments.
// the root frame of |aPresShell|. If the point is inside a subdocument, returns
// an element inside the subdocument, rather than the subdocument element
// (and does so recursively).
// The implementation was adapted from DocumentOrShadowRoot::ElementFromPoint(),
// with the notable exception that we don't pass nsLayoutUtils::IGNORE_CROSS_DOC
// to GetFrameForPoint(), so as to get the behaviour described above in the
// presence of subdocuments.
static already_AddRefed<dom::Element> ElementFromPoint(
const RefPtr<PresShell>& aPresShell, const CSSPoint& aPoint) {
nsIFrame* rootFrame = aPresShell->GetRootFrame();
@ -40,8 +41,9 @@ static already_AddRefed<dom::Element> ElementFromPoint(
return nullptr;
}
nsIFrame* frame = nsLayoutUtils::GetFrameForPoint(
RelativeTo{rootFrame, ViewportType::Visual}, CSSPoint::ToAppUnits(aPoint),
{FrameForPointOption::IgnorePaintSuppression});
rootFrame, CSSPoint::ToAppUnits(aPoint),
{FrameForPointOption::IgnorePaintSuppression,
FrameForPointOption::IgnoreRootScrollFrame});
while (frame && (!frame->GetContent() ||
frame->GetContent()->IsInAnonymousSubtree())) {
frame = nsLayoutUtils::GetParentOrPlaceholderFor(frame);

View File

@ -11,7 +11,7 @@ namespace layers {
ScrollableLayerGuid InputAPZContext::sGuid;
uint64_t InputAPZContext::sBlockId = 0;
nsEventStatus InputAPZContext::sApzResponse = nsEventStatus_eSentinel;
nsEventStatus InputAPZContext::sApzResponse = nsEventStatus_eIgnore;
bool InputAPZContext::sPendingLayerization = false;
bool InputAPZContext::sRoutedToChildProcess = false;

View File

@ -47,7 +47,7 @@ static void UpdateAllowedBehavior(StyleTouchAction aTouchActionValue,
}
TouchBehaviorFlags TouchActionHelper::GetAllowedTouchBehavior(
nsIWidget* aWidget, RelativeTo aRootFrame,
nsIWidget* aWidget, nsIFrame* aRootFrame,
const LayoutDeviceIntPoint& aPoint) {
TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN |
AllowedTouchBehavior::HORIZONTAL_PAN |
@ -57,7 +57,9 @@ TouchBehaviorFlags TouchActionHelper::GetAllowedTouchBehavior(
nsPoint relativePoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, aRootFrame);
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(aRootFrame, relativePoint);
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(
aRootFrame, relativePoint,
nsLayoutUtils::FrameForPointOption::IgnoreRootScrollFrame);
if (!target) {
return behavior;
}

View File

@ -8,7 +8,6 @@
#define __mozilla_layers_TouchActionHelper_h__
#include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
#include "nsLayoutUtils.h" // for RelativeTo
class nsIFrame;
class nsIWidget;
@ -29,7 +28,7 @@ class TouchActionHelper {
* http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
*/
static TouchBehaviorFlags GetAllowedTouchBehavior(
nsIWidget* aWidget, RelativeTo aRootFrame,
nsIWidget* aWidget, nsIFrame* aRootFrame,
const LayoutDeviceIntPoint& aPoint);
};

View File

@ -698,8 +698,8 @@ nsPoint AccessibleCaretEventHub::GetTouchEventPosition(
// Get event coordinate relative to root frame.
nsIFrame* rootFrame = mPresShell->GetRootFrame();
return nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, touchIntPoint, RelativeTo{rootFrame});
return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint,
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,
RelativeTo{rootFrame});
rootFrame);
}
} // namespace mozilla

View File

@ -519,6 +519,11 @@ static EnumSet<nsLayoutUtils::FrameForPointOption> GetHitTestOptions() {
EnumSet<nsLayoutUtils::FrameForPointOption> options = {
nsLayoutUtils::FrameForPointOption::IgnorePaintSuppression,
nsLayoutUtils::FrameForPointOption::IgnoreCrossDoc};
#ifdef MOZ_WIDGET_ANDROID
// On Android, we need IgnoreRootScrollFrame for correct hit testing when
// zoomed in or out.
options += nsLayoutUtils::FrameForPointOption::IgnoreRootScrollFrame;
#endif
return options;
}
@ -544,8 +549,8 @@ nsresult AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) {
}
// Find the frame under point.
AutoWeakFrame ptFrame = nsLayoutUtils::GetFrameForPoint(
RelativeTo{rootFrame}, aPoint, GetHitTestOptions());
AutoWeakFrame ptFrame =
nsLayoutUtils::GetFrameForPoint(rootFrame, aPoint, GetHitTestOptions());
if (!ptFrame.GetFrame()) {
return NS_ERROR_FAILURE;
}
@ -565,8 +570,7 @@ 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(RelativeTo{rootFrame}, RelativeTo{ptFrame},
ptInFrame);
nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame);
// Firstly check long press on an empty editable content.
Element* newFocusEditingHost = GetEditingHostForFrame(ptFrame);
@ -1217,8 +1221,8 @@ nsresult AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint) {
// Find out which content we point to
nsIFrame* ptFrame = nsLayoutUtils::GetFrameForPoint(
RelativeTo{rootFrame}, point, GetHitTestOptions());
nsIFrame* ptFrame =
nsLayoutUtils::GetFrameForPoint(rootFrame, point, GetHitTestOptions());
if (!ptFrame) {
return NS_ERROR_FAILURE;
}
@ -1230,8 +1234,7 @@ nsresult AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint) {
nsIFrame* newFrame = nullptr;
nsPoint newPoint;
nsPoint ptInFrame = point;
nsLayoutUtils::TransformPoint(RelativeTo{rootFrame}, RelativeTo{ptFrame},
ptInFrame);
nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame);
result = fs->ConstrainFrameAndPointToAnchorSubtree(ptFrame, ptInFrame,
&newFrame, newPoint);
if (NS_FAILED(result) || !newFrame) {
@ -1380,8 +1383,7 @@ void AccessibleCaretManager::StartSelectionAutoScrollTimer(
nsIFrame* rootFrame = mPresShell->GetRootFrame();
MOZ_ASSERT(rootFrame);
nsPoint ptInScrolled = aPoint;
nsLayoutUtils::TransformPoint(RelativeTo{rootFrame},
RelativeTo{capturingFrame}, ptInScrolled);
nsLayoutUtils::TransformPoint(rootFrame, capturingFrame, ptInScrolled);
RefPtr<nsFrameSelection> fs = GetFrameSelection();
MOZ_ASSERT(fs);

View File

@ -242,14 +242,12 @@ static nsIContent* GetClickableAncestor(
return nullptr;
}
static nscoord AppUnitsFromMM(RelativeTo aFrame, uint32_t aMM) {
nsPresContext* pc = aFrame.mFrame->PresContext();
static nscoord AppUnitsFromMM(nsIFrame* aFrame, uint32_t aMM) {
nsPresContext* pc = aFrame->PresContext();
PresShell* presShell = pc->PresShell();
float result = float(aMM) * (pc->DeviceContext()->AppUnitsPerPhysicalInch() /
MM_PER_INCH_FLOAT);
if (aFrame.mViewportType == ViewportType::Layout) {
PresShell* presShell = pc->PresShell();
result = result / presShell->GetResolution();
}
result = result / presShell->GetResolution();
return NSToCoordRound(result);
}
@ -257,18 +255,17 @@ static nscoord AppUnitsFromMM(RelativeTo 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(const nsIFrame* aRootFrame, const nsIFrame* aFrame,
static nsRect ClipToFrame(nsIFrame* aRootFrame, nsIFrame* aFrame,
nsRect& aRect) {
nsRect bound = nsLayoutUtils::TransformFrameRectToAncestor(
aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()),
RelativeTo{aRootFrame, ViewportType::Visual});
aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()), aRootFrame);
nsRect result = bound.Intersect(aRect);
return result;
}
static nsRect GetTargetRect(RelativeTo aRootFrame,
static nsRect GetTargetRect(nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame,
const nsIFrame* aRestrictToDescendants,
nsIFrame* aRestrictToDescendants,
const EventRadiusPrefs* aPrefs, uint32_t aFlags) {
nsMargin m(AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[0]),
AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[1]),
@ -280,7 +277,7 @@ static nsRect GetTargetRect(RelativeTo 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.mFrame, aRestrictToDescendants, r);
r = ClipToFrame(aRootFrame, aRestrictToDescendants, r);
}
return r;
}
@ -324,11 +321,11 @@ static void SubtractFromExposedRegion(nsRegion* aExposedRegion,
}
}
static nsIFrame* GetClosest(const nsIFrame* aRoot,
static nsIFrame* GetClosest(nsIFrame* aRoot,
const nsPoint& aPointRelativeToRootFrame,
const nsRect& aTargetRect,
const EventRadiusPrefs* aPrefs,
const nsIFrame* aRestrictToDescendants,
nsIFrame* aRestrictToDescendants,
nsIContent* aClickableAncestor,
nsTArray<nsIFrame*>& aCandidates) {
nsIFrame* bestTarget = nullptr;
@ -340,8 +337,7 @@ static nsIFrame* GetClosest(const nsIFrame* aRoot,
bool preservesAxisAlignedRectangles = false;
nsRect borderBox = nsLayoutUtils::TransformFrameRectToAncestor(
f, nsRect(nsPoint(0, 0), f->GetSize()),
RelativeTo{aRoot, ViewportType::Visual},
f, nsRect(nsPoint(0, 0), f->GetSize()), aRoot,
&preservesAxisAlignedRectangles);
PET_LOG("Checking candidate %p with border box %s\n", f,
mozilla::layers::Stringify(borderBox).c_str());
@ -404,7 +400,7 @@ static nsIFrame* GetClosest(const nsIFrame* aRoot,
}
nsIFrame* FindFrameTargetedByInputEvent(
WidgetGUIEvent* aEvent, RelativeTo aRootFrame,
WidgetGUIEvent* aEvent, nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame, uint32_t aFlags) {
using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
EnumSet<FrameForPointOption> options;
@ -418,7 +414,7 @@ nsIFrame* FindFrameTargetedByInputEvent(
"relative to root frame %p\n",
target, ToChar(aEvent->mClass), ToChar(aEvent->mMessage),
mozilla::layers::Stringify(aPointRelativeToRootFrame).c_str(),
aRootFrame.mFrame);
aRootFrame);
const EventRadiusPrefs* prefs = GetPrefsFor(aEvent->mClass);
if (!prefs || !prefs->mEnabled || EventRetargetSuppression::IsActive()) {
@ -452,8 +448,8 @@ 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.
const nsIFrame* restrictToDescendants =
target ? target->PresShell()->GetRootFrame() : aRootFrame.mFrame;
nsIFrame* restrictToDescendants =
target ? target->PresShell()->GetRootFrame() : aRootFrame;
nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
restrictToDescendants, prefs, aFlags);
@ -467,8 +463,8 @@ nsIFrame* FindFrameTargetedByInputEvent(
}
nsIFrame* closestClickable =
GetClosest(aRootFrame.mFrame, aPointRelativeToRootFrame, targetRect,
prefs, restrictToDescendants, clickableAncestor, candidates);
GetClosest(aRootFrame, aPointRelativeToRootFrame, targetRect, prefs,
restrictToDescendants, clickableAncestor, candidates);
if (closestClickable) {
target = closestClickable;
}
@ -479,7 +475,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.mFrame->DumpFrameTree();
aRootFrame->DumpFrameTree();
}
#endif
@ -492,23 +488,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, RelativeTo{target}, point)) {
nsLayoutUtils::TransformPoint(aRootFrame, target, point)) {
return target;
}
point = target->GetRectRelativeToSelf().ClampPoint(point);
if (nsLayoutUtils::TRANSFORM_SUCCEEDED !=
nsLayoutUtils::TransformPoint(RelativeTo{target}, aRootFrame, point)) {
nsLayoutUtils::TransformPoint(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.mFrame->GetView();
nsView* view = aRootFrame->GetView();
if (!view) {
return target;
}
LayoutDeviceIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget(
aRootFrame.mFrame->PresContext(), view, point, aRootFrame.mViewportType,
aEvent->mWidget);
aRootFrame->PresContext(), view, point, aEvent->mWidget);
if (widgetPoint.x != NS_UNCONSTRAINEDSIZE) {
// If that succeeded, we update the point in the event
aEvent->mRefPoint = widgetPoint;

View File

@ -9,7 +9,6 @@
#include <stdint.h>
#include "mozilla/EventForwards.h"
#include "nsLayoutUtils.h"
class nsIFrame;
struct nsPoint;
@ -23,7 +22,7 @@ enum { INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01 };
* that are suitable targets, to account for inaccurate pointing devices.
*/
nsIFrame* FindFrameTargetedByInputEvent(
WidgetGUIEvent* aEvent, RelativeTo aRootFrame,
WidgetGUIEvent* aEvent, nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame, uint32_t aFlags = 0);
class MOZ_RAII EventRetargetSuppression {

View File

@ -8,7 +8,6 @@
#include "mozilla/PresShell.h"
#include "Units.h"
#include "mozilla/dom/FontFaceSet.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
@ -37,7 +36,6 @@
#include "mozilla/TouchEvents.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "mozilla/ViewportUtils.h"
#include <algorithm>
#ifdef XP_WIN
@ -3654,8 +3652,7 @@ bool PresShell::ScrollFrameRectIntoView(nsIFrame* aFrame, const nsRect& aRect,
}
nsIFrame* parent;
if (container->IsTransformed()) {
container->GetTransformMatrix(ViewportType::Layout, RelativeTo{nullptr},
&parent);
container->GetTransformMatrix(nullptr, &parent);
rect =
nsLayoutUtils::TransformFrameRectToAncestor(container, rect, parent);
} else {
@ -5300,6 +5297,24 @@ float PresShell::GetCumulativeResolution() {
return resolution;
}
float PresShell::GetCumulativeNonRootScaleResolution() {
float resolution = 1.0;
PresShell* currentPresShell = this;
while (currentPresShell) {
nsPresContext* currentCtx = currentPresShell->GetPresContext();
if (currentCtx != currentCtx->GetRootPresContext()) {
resolution *= currentPresShell->GetResolution();
}
nsPresContext* parentCtx = currentCtx->GetParentPresContext();
if (parentCtx) {
currentPresShell = parentCtx->PresShell();
} else {
currentPresShell = nullptr;
}
}
return resolution;
}
void PresShell::SetRestoreResolution(float aResolution,
LayoutDeviceIntSize aDisplaySize) {
if (mMobileViewportManager) {
@ -6403,8 +6418,8 @@ void PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent) {
mPresContext, aEvent->mWidget, aEvent->mRefPoint, rootView);
mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
} else {
mMouseLocation = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{rootFrame, ViewportType::Visual});
mMouseLocation =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
}
mMouseLocationWasSetBySynthesizedMouseEventForTests =
@ -6854,14 +6869,8 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
MOZ_ASSERT(aGUIEvent);
MOZ_ASSERT(aGUIEvent->mClass != eTouchEventClass);
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);
nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aGUIEvent, aRootFrameToHandleEvent);
uint32_t flags = 0;
if (aGUIEvent->mClass == eMouseEventClass) {
@ -6871,8 +6880,8 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
}
}
nsIFrame* targetFrame =
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
nsIFrame* targetFrame = FindFrameTargetedByInputEvent(
aGUIEvent, aRootFrameToHandleEvent, eventPoint, flags);
if (!targetFrame) {
return aRootFrameToHandleEvent;
}
@ -6901,8 +6910,8 @@ nsIFrame* PresShell::EventHandler::GetFrameToHandleNonTouchEvent(
}
// Finally, we need to recompute the target with the latest layout.
targetFrame =
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
targetFrame = FindFrameTargetedByInputEvent(
aGUIEvent, aRootFrameToHandleEvent, eventPoint, flags);
return targetFrame ? targetFrame : aRootFrameToHandleEvent;
}
@ -8605,12 +8614,6 @@ bool PresShell::EventHandler::AdjustContextMenuKeyEvent(
if (PrepareToUseCaretPosition(MOZ_KnownLive(aMouseEvent->mWidget),
caretPoint)) {
// caret position is good
int32_t devPixelRatio = GetPresContext()->AppUnitsPerDevPixel();
caretPoint = LayoutDeviceIntPoint::FromAppUnitsToNearest(
ViewportUtils::LayoutToVisual(
LayoutDeviceIntPoint::ToAppUnits(caretPoint, devPixelRatio),
GetPresContext()->PresShell()),
devPixelRatio);
aMouseEvent->mRefPoint = caretPoint;
return true;
}
@ -11126,15 +11129,14 @@ nsIContent* PresShell::EventHandler::GetOverrideClickTarget(
WidgetMouseEvent* mouseEvent = aGUIEvent->AsMouseEvent();
uint32_t flags = 0;
RelativeTo relativeTo{aFrame};
nsPoint eventPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aGUIEvent, relativeTo);
nsLayoutUtils::GetEventCoordinatesRelativeTo(aGUIEvent, aFrame);
if (mouseEvent->mIgnoreRootScrollFrame) {
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
}
nsIFrame* target =
FindFrameTargetedByInputEvent(aGUIEvent, relativeTo, eventPoint, flags);
FindFrameTargetedByInputEvent(aGUIEvent, aFrame, eventPoint, flags);
if (!target) {
return nullptr;
}

View File

@ -974,6 +974,12 @@ class PresShell final : public nsStubDocumentObserver,
*/
bool IsResolutionUpdatedByApz() const { return mResolutionUpdatedByApz; }
/**
* Calculate the cumulative scale resolution from this document up to
* but not including the root document.
*/
float GetCumulativeNonRootScaleResolution();
/**
* Used by session restore code to restore a resolution before the first
* paint.
@ -2950,10 +2956,10 @@ class PresShell final : public nsStubDocumentObserver,
// the mouse pointer may have changed without the mouse moving (eg scrolling,
// change to the document contents).
// It is set only on a presshell for a root document, this value represents
// the last observed location of the mouse relative to that root document,
// in visual coordinates. It is set to (NS_UNCONSTRAINEDSIZE,
// NS_UNCONSTRAINEDSIZE) if the mouse isn't over our window or there is no
// last observed mouse location for some reason.
// the last observed location of the mouse relative to that root document. It
// is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
// over our window or there is no last observed mouse location for some
// reason.
nsPoint mMouseLocation;
// This is an APZ state variable that tracks the target guid for the last
// mouse event that was processed (corresponding to mMouseLocation). This is

View File

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_RelativeTo_h
#define mozilla_RelativeTo_h
#include <ostream>
class nsIFrame;
namespace mozilla {
// A flag that can be used to annotate a frame to distinguish coordinates
// relative to the viewport frame as being in layout or visual coordinates.
enum class ViewportType { Layout, Visual };
// A struct that combines a frame with a ViewportType annotation. The
// combination completely describes what a set of coordinates is "relative to".
// Notes on expected usage:
// - The boundary between visual and layout coordinates is approximately
// at the root content document (RCD)'s ViewportFrame, which we'll
// call "RCD-VF".
// - Coordinates relative to the RCD-VF's descendants (other than the
// RCD's viewport scrollbar frames) should be in layout coordinates.
// - Coordinates relative to the RCD-VF's ancestors should be in visual
// coordinates (note that in an e10s setup, the RCD-VF doesn't
// typically have in-process ancestors).
// - Coordinates relative to the RCD-VF itself can be in either layout
// or visual coordinates.
struct RelativeTo {
const nsIFrame* mFrame = nullptr;
// Choose ViewportType::Layout as the default as this is what the vast
// majority of layout code deals with.
ViewportType mViewportType = ViewportType::Layout;
bool operator==(const RelativeTo& aOther) const {
return mFrame == aOther.mFrame && mViewportType == aOther.mViewportType;
}
friend std::ostream& operator<<(std::ostream& aOs, const RelativeTo& aR) {
return aOs << "{" << aR.mFrame << ", "
<< (aR.mViewportType == ViewportType::Visual ? "visual"
: "layout")
<< "}";
}
};
} // namespace mozilla
#endif // mozilla_RelativeTo_h

View File

@ -109,6 +109,15 @@ nsIFrame* TouchManager::SetupTarget(WidgetTouchEvent* aEvent,
return aFrame;
}
uint32_t flags = 0;
// Setting this flag will skip the scrollbars on the root frame from
// participating in hit-testing, and we only want that to happen on
// zoomable platforms (for now).
dom::Document* doc = aFrame->PresContext()->Document();
if (nsLayoutUtils::AllowZoomingForDocument(doc)) {
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
}
nsIFrame* target = aFrame;
for (int32_t i = aEvent->mTouches.Length(); i;) {
--i;
@ -117,10 +126,9 @@ 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, relativeTo);
target = FindFrameTargetedByInputEvent(aEvent, relativeTo, eventPoint);
aEvent, touch->mRefPoint, aFrame);
target = FindFrameTargetedByInputEvent(aEvent, aFrame, eventPoint, flags);
if (target) {
nsCOMPtr<nsIContent> targetContent;
target->GetContentForEvent(aEvent, getter_AddRefs(targetContent));

View File

@ -224,7 +224,6 @@ typedef gfx::ScaleFactors2D<ParentLayerPixel, ScreenPixel>
typedef gfx::ScaleFactors2D<ParentLayerPixel, ParentLayerPixel>
ParentLayerToParentLayerScale2D;
typedef gfx::Matrix4x4Typed<CSSPixel, CSSPixel> CSSToCSSMatrix4x4;
typedef gfx::Matrix4x4Typed<LayoutDevicePixel, LayoutDevicePixel>
LayoutDeviceToLayoutDeviceMatrix4x4;
typedef gfx::Matrix4x4Typed<LayoutDevicePixel, ParentLayerPixel>

View File

@ -1,146 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/PresShell.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/ScrollableLayerGuid.h"
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsIScrollableFrame.h"
#include "nsLayoutUtils.h"
#include "nsQueryFrame.h"
#include "nsStyleStruct.h"
namespace mozilla {
using layers::APZCCallbackHelper;
using layers::InputAPZContext;
using layers::ScrollableLayerGuid;
template <typename Units>
gfx::Matrix4x4Typed<Units, Units> ViewportUtils::GetVisualToLayoutTransform(
ScrollableLayerGuid::ViewID aScrollId) {
static_assert(
std::is_same_v<Units, CSSPixel> ||
std::is_same_v<Units, LayoutDevicePixel>,
"GetCallbackTransform() may only be used with CSS or LayoutDevice units");
if (aScrollId == ScrollableLayerGuid::NULL_SCROLL_ID) {
return {};
}
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aScrollId);
if (!content) {
return {};
}
// First, scale inversely by the root content document's pres shell
// resolution to cancel the scale-to-resolution transform that the
// compositor adds to the layer with the pres shell resolution. The points
// sent to Gecko by APZ don't have this transform unapplied (unlike other
// compositor-side transforms) because Gecko needs it applied when hit
// testing against content that's conceptually outside the resolution,
// such as scrollbars.
float resolution = 1.0f;
if (PresShell* presShell =
APZCCallbackHelper::GetRootContentDocumentPresShellForContent(
content)) {
resolution = presShell->GetResolution();
}
// Now apply the callback-transform. This is only approximately correct,
// see the comment on GetCumulativeApzCallbackTransform for details.
gfx::PointTyped<Units> transform;
CSSPoint transformCSS = nsLayoutUtils::GetCumulativeApzCallbackTransform(
content->GetPrimaryFrame());
if constexpr (std::is_same_v<Units, CSSPixel>) {
transform = transformCSS;
} else { // Units == LayoutDevicePixel
transform = transformCSS *
content->GetPrimaryFrame()->PresContext()->CSSToDevPixelScale();
}
return gfx::Matrix4x4Typed<Units, Units>::Scaling(1 / resolution,
1 / resolution, 1)
.PostTranslate(transform.x, transform.y, 0);
}
CSSToCSSMatrix4x4 GetVisualToLayoutTransform(PresShell* aContext) {
ScrollableLayerGuid::ViewID targetScrollId =
InputAPZContext::GetTargetLayerGuid().mScrollId;
if (targetScrollId == ScrollableLayerGuid::NULL_SCROLL_ID) {
if (nsIFrame* rootScrollFrame = aContext->GetRootScrollFrame()) {
targetScrollId =
nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent());
}
}
return ViewportUtils::GetVisualToLayoutTransform(targetScrollId);
}
nsPoint ViewportUtils::VisualToLayout(const nsPoint& aPt, PresShell* aContext) {
auto visualToLayout = mozilla::GetVisualToLayoutTransform(aContext);
CSSPoint cssPt = CSSPoint::FromAppUnits(aPt);
cssPt = visualToLayout.TransformPoint(cssPt);
return CSSPoint::ToAppUnits(cssPt);
}
nsRect ViewportUtils::VisualToLayout(const nsRect& aRect, PresShell* aContext) {
auto visualToLayout = mozilla::GetVisualToLayoutTransform(aContext);
CSSRect cssRect = CSSRect::FromAppUnits(aRect);
cssRect = visualToLayout.TransformBounds(cssRect);
nsRect result = CSSRect::ToAppUnits(cssRect);
// In hit testing codepaths, the input rect often has dimensions of one app
// units. If we are zoomed in enough, the rounded size of the output rect
// can be zero app units, which will fail to Intersect() with anything, and
// therefore cause hit testing to fail. To avoid this, we expand the output
// rect to one app units.
if (!aRect.IsEmpty() && result.IsEmpty()) {
result.width = 1;
result.height = 1;
}
return result;
}
nsPoint ViewportUtils::LayoutToVisual(const nsPoint& aPt, PresShell* aContext) {
auto visualToLayout = mozilla::GetVisualToLayoutTransform(aContext);
CSSPoint cssPt = CSSPoint::FromAppUnits(aPt);
auto transformed = visualToLayout.Inverse().TransformPoint(cssPt);
return CSSPoint::ToAppUnits(transformed);
}
// Definitions of the two explicit instantiations forward declared in the header
// file. This causes code for these instantiations to be emitted into the object
// file for ViewportUtils.cpp.
template CSSToCSSMatrix4x4 ViewportUtils::GetVisualToLayoutTransform<CSSPixel>(
ScrollableLayerGuid::ViewID);
template LayoutDeviceToLayoutDeviceMatrix4x4
ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(
ScrollableLayerGuid::ViewID);
const nsIFrame* ViewportUtils::IsZoomedContentRoot(const nsIFrame* aFrame) {
if (!aFrame) {
return nullptr;
}
if (aFrame->Type() == LayoutFrameType::Canvas) {
nsIScrollableFrame* sf = do_QueryFrame(aFrame->GetParent());
if (sf && sf->IsRootScrollFrameOfDocument() &&
aFrame->PresContext()->IsRootContentDocumentCrossProcess()) {
return aFrame->GetParent();
}
} else if (aFrame->StyleDisplay()->mPosition ==
StylePositionProperty::Fixed) {
if (ViewportFrame* viewportFrame = do_QueryFrame(aFrame->GetParent())) {
if (viewportFrame->PresContext()->IsRootContentDocumentCrossProcess()) {
return viewportFrame->PresShell()->GetRootScrollFrame();
}
}
}
return nullptr;
}
} // namespace mozilla

View File

@ -1,80 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ViewportUtils_h
#define mozilla_ViewportUtils_h
#include "Units.h"
#include "mozilla/layers/ScrollableLayerGuid.h"
class nsIFrame;
namespace mozilla {
class PresShell;
class ViewportUtils {
public:
/* Return a transform to be applied to the coordinates of input events
targeting content inside the scroll frame identified by |aScrollId|, which
converts from "visual coordinates" (which are the coordinates events have
when they arrive from APZ) to "layout coordinates" (which are the
coordinates used in most places by layout code). The transform has two
components:
1. The pres shell resolution, representing the pinch-zoom scale
(if the scroll frame |aScrollId| is inside the resolution, which
is most of the time).
2. A translation representing async scrolling. This can contain:
- For any scroll frame, a scroll component resulting from the main
thread incompletely applying an APZ-requested scroll position.
- For the RCD-RSF only, a persistent component representing the
offset of the visual viewport relative to the layout viewport.
The translation is accumulated for all scroll frames form |aScrollId|
up to the root, using values populated in
APZCCallbackHelper::UpdateCallbackTransform. See that method's
documentation for additional details. */
template <typename Units = CSSPixel>
static gfx::Matrix4x4Typed<Units, Units> GetVisualToLayoutTransform(
layers::ScrollableLayerGuid::ViewID aScrollId);
/* The functions below apply GetVisualToLayoutTransform() or its inverse
* to various quantities.
*
* To determine the appropriate scroll id to pass into
* GetVisualToLayoutTransform(), these functions prefer to use the one
* from InputAPZContext::GetTargetLayerGuid() if one is available.
* If one is not available, they use the scroll id of the root scroll
* frame of the pres shell passed in as |aContext| as a fallback.
*/
static nsPoint VisualToLayout(const nsPoint& aPt, PresShell* aContext);
static nsRect VisualToLayout(const nsRect& aRect, PresShell* aContext);
static nsPoint LayoutToVisual(const nsPoint& aPt, PresShell* aContext);
/**
* Returns non-null if |aFrame| is inside the async zoom container but its
* parent frame is not, thereby making |aFrame| a root of a subtree of
* frames representing content that is zoomed in. The value returned in such
* cases is the root scroll frame inside the async zoom container.
* Callers use this to identify points during frame tree traversal where the
* visual-to-layout transform needs to be applied.
*/
static const nsIFrame* IsZoomedContentRoot(const nsIFrame* aFrame);
};
// Forward declare explicit instantiations of GetVisualToLayoutTransform() for
// CSSPixel and LayoutDevicePixel, the only two types it gets used with.
// These declarations promise to callers in any translation unit that _some_
// translation unit (in this case, ViewportUtils.cpp) will contain the
// definitions of these instantiations. This allows us to keep the definition
// out-of-line in the source.
extern template CSSToCSSMatrix4x4 ViewportUtils::GetVisualToLayoutTransform<
CSSPixel>(layers::ScrollableLayerGuid::ViewID);
extern template LayoutDeviceToLayoutDeviceMatrix4x4
ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(
layers::ScrollableLayerGuid::ViewID);
} // namespace mozilla
#endif /* mozilla_ViewportUtils_h */

View File

@ -82,13 +82,11 @@ EXPORTS.mozilla += [
'PresShell.h',
'PresShellForwards.h',
'PresShellInlines.h',
'RelativeTo.h',
'RestyleManager.h',
'ScrollStyles.h',
'ScrollTypes.h',
'ShapeUtils.h',
'StaticPresData.h',
'ViewportUtils.h',
]
EXPORTS.mozilla.layout += [
@ -131,7 +129,6 @@ UNIFIED_SOURCES += [
'StackArena.cpp',
'StaticPresData.cpp',
'TouchManager.cpp',
'ViewportUtils.cpp',
'ZoomConstraintsClient.cpp',
]

View File

@ -19,7 +19,6 @@
#include "nsIContent.h"
#include "nsIContentViewer.h"
#include "nsIDocumentViewerPrint.h"
#include "nsIScreen.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/BeforeUnloadEvent.h"
#include "mozilla/dom/PopupBlocker.h"

View File

@ -34,7 +34,6 @@
#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"
@ -143,7 +142,6 @@
#include "TextDrawTarget.h"
#include "nsDeckFrame.h"
#include "mozilla/dom/InspectorFontFace.h"
#include "ViewportFrame.h"
#ifdef MOZ_XUL
# include "nsXULPopupManager.h"
@ -710,7 +708,7 @@ bool nsLayoutUtils::AllowZoomingForDocument(
}
float nsLayoutUtils::GetCurrentAPZResolutionScale(PresShell* aPresShell) {
return aPresShell ? aPresShell->GetCumulativeResolution() : 1.0;
return aPresShell ? aPresShell->GetCumulativeNonRootScaleResolution() : 1.0;
}
// Return the maximum displayport size, based on the LayerManager's maximum
@ -2185,11 +2183,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, RelativeTo{aFrame});
return GetEventCoordinatesRelativeTo(event, aFrame);
}
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
RelativeTo aFrame) {
nsIFrame* aFrame) {
if (!aEvent || (aEvent->mClass != eMouseEventClass &&
aEvent->mClass != eMouseScrollEventClass &&
aEvent->mClass != eWheelEventClass &&
@ -2207,8 +2205,8 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
const WidgetEvent* aEvent, const LayoutDeviceIntPoint& aPoint,
RelativeTo aFrame) {
if (!aFrame.mFrame) {
nsIFrame* aFrame) {
if (!aFrame) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
@ -2221,26 +2219,24 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
}
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, RelativeTo aFrame) {
const nsIFrame* frame = aFrame.mFrame;
if (!frame || !aWidget) {
nsIWidget* aWidget, const LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame) {
if (!aFrame || !aWidget) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
nsView* view = frame->GetView();
nsView* view = aFrame->GetView();
if (view) {
nsIWidget* frameWidget = view->GetWidget();
if (frameWidget && frameWidget == aWidget) {
// Special case this cause it happens a lot.
// This also fixes bug 664707, events in the extra-special case of select
// dropdown popups that are transformed.
nsPresContext* presContext = frame->PresContext();
nsPresContext* presContext = aFrame->PresContext();
nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x),
presContext->DevPixelsToAppUnits(aPoint.y));
pt = pt - view->ViewToWidgetOffset();
if (aFrame.mViewportType == ViewportType::Layout) {
pt = ViewportUtils::VisualToLayout(pt, frame->PresShell());
}
pt = pt.RemoveResolution(
GetCurrentAPZResolutionScale(presContext->PresShell()));
return pt;
}
}
@ -2249,10 +2245,10 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
* transformed, we need to do extra work to convert from the global
* space to the local space.
*/
const nsIFrame* rootFrame = frame;
nsIFrame* rootFrame = aFrame;
bool transformFound = false;
for (const nsIFrame* f = frame; f; f = GetCrossDocParentFrame(f)) {
if (f->IsTransformed() || ViewportUtils::IsZoomedContentRoot(f)) {
for (nsIFrame* f = aFrame; f; f = GetCrossDocParentFrame(f)) {
if (f->IsTransformed()) {
transformFound = true;
}
@ -2274,21 +2270,26 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
// Convert from root document app units to app units of the document aFrame
// is in.
int32_t rootAPD = rootFrame->PresContext()->AppUnitsPerDevPixel();
int32_t localAPD = frame->PresContext()->AppUnitsPerDevPixel();
int32_t localAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
widgetToView = widgetToView.ScaleToOtherAppUnits(rootAPD, localAPD);
PresShell* presShell = aFrame->PresShell();
// XXX Bug 1224748 - Update nsLayoutUtils functions to correctly handle
// PresShell resolution
widgetToView =
widgetToView.RemoveResolution(GetCurrentAPZResolutionScale(presShell));
/* If we encountered a transform, we can't do simple arithmetic to figure
* out how to convert back to aFrame's coordinates and must use the CTM.
*/
if (transformFound || nsSVGUtils::IsInSVGTextSubtree(frame)) {
return TransformRootPointToFrame(ViewportType::Visual, aFrame,
widgetToView);
if (transformFound || nsSVGUtils::IsInSVGTextSubtree(aFrame)) {
return TransformRootPointToFrame(aFrame, widgetToView);
}
/* Otherwise, all coordinate systems are translations of one another,
* so we can just subtract out the difference.
*/
return widgetToView - frame->GetOffsetToCrossDoc(rootFrame);
return widgetToView - aFrame->GetOffsetToCrossDoc(rootFrame);
}
nsIFrame* nsLayoutUtils::GetPopupFrameForEventCoordinates(
@ -2306,7 +2307,7 @@ nsIFrame* nsLayoutUtils::GetPopupFrameForEventCoordinates(
nsIFrame* popup = popups[i];
if (popup->PresContext()->GetRootPresContext() == aPresContext &&
popup->GetScrollableOverflowRect().Contains(
GetEventCoordinatesRelativeTo(aEvent, RelativeTo{popup}))) {
GetEventCoordinatesRelativeTo(aEvent, popup))) {
return popup;
}
}
@ -2343,8 +2344,8 @@ void nsLayoutUtils::GetContainerAndOffsetAtEvent(PresShell* aPresShell,
return;
}
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{targetFrame});
nsPoint point =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
if (aContainer) {
// TODO: This result may be useful to change to Selection. However, this
@ -2607,28 +2608,22 @@ bool nsLayoutUtils::FrameHasDisplayPort(nsIFrame* aFrame,
}
Matrix4x4Flagged nsLayoutUtils::GetTransformToAncestor(
RelativeTo aFrame, RelativeTo aAncestor, uint32_t aFlags,
const nsIFrame* aFrame, const nsIFrame* aAncestor, uint32_t aFlags,
nsIFrame** aOutAncestor) {
nsIFrame* parent;
Matrix4x4Flagged ctm;
// Make sure we don't get an invalid combination of source and destination
// RelativeTo values.
MOZ_ASSERT(!(aFrame.mViewportType == ViewportType::Visual &&
aAncestor.mViewportType == ViewportType::Layout));
if (aFrame == aAncestor) {
return ctm;
}
ctm = aFrame.mFrame->GetTransformMatrix(aFrame.mViewportType, aAncestor,
&parent, aFlags);
while (parent && parent != aAncestor.mFrame &&
ctm = aFrame->GetTransformMatrix(aAncestor, &parent, aFlags);
while (parent && parent != aAncestor &&
(!(aFlags & nsIFrame::STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT) ||
(!parent->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) &&
!parent->IsStackingContext() && !FrameHasDisplayPort(parent)))) {
if (!parent->Extend3DContext()) {
ctm.ProjectTo2D();
}
ctm = ctm * parent->GetTransformMatrix(aFrame.mViewportType, aAncestor,
&parent, aFlags);
ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent, aFlags);
}
if (aOutAncestor) {
*aOutAncestor = parent;
@ -2638,8 +2633,7 @@ Matrix4x4Flagged nsLayoutUtils::GetTransformToAncestor(
gfxSize nsLayoutUtils::GetTransformToAncestorScale(nsIFrame* aFrame) {
Matrix4x4Flagged transform = GetTransformToAncestor(
RelativeTo{aFrame},
RelativeTo{nsLayoutUtils::GetDisplayRootFrame(aFrame)});
aFrame, nsLayoutUtils::GetDisplayRootFrame(aFrame));
Matrix transform2D;
if (transform.Is2D(&transform2D)) {
return ThebesMatrix(transform2D).ScaleFactors(true);
@ -2657,8 +2651,7 @@ static Matrix4x4Flagged GetTransformToAncestorExcludingAnimated(
if (ActiveLayerTracker::IsScaleSubjectToAnimation(aFrame)) {
return ctm;
}
ctm = aFrame->GetTransformMatrix(ViewportType::Layout, RelativeTo{aAncestor},
&parent);
ctm = aFrame->GetTransformMatrix(aAncestor, &parent);
while (parent && parent != aAncestor) {
if (ActiveLayerTracker::IsScaleSubjectToAnimation(parent)) {
return Matrix4x4Flagged();
@ -2666,8 +2659,7 @@ static Matrix4x4Flagged GetTransformToAncestorExcludingAnimated(
if (!parent->Extend3DContext()) {
ctm.ProjectTo2D();
}
ctm = ctm * parent->GetTransformMatrix(ViewportType::Layout,
RelativeTo{aAncestor}, &parent);
ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent);
}
return ctm;
}
@ -2719,14 +2711,14 @@ nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoints(
if (!nearestCommonAncestor) {
return NO_COMMON_ANCESTOR;
}
Matrix4x4Flagged downToDest = GetTransformToAncestor(
RelativeTo{aToFrame}, RelativeTo{nearestCommonAncestor});
Matrix4x4Flagged downToDest =
GetTransformToAncestor(aToFrame, nearestCommonAncestor);
if (downToDest.IsSingular()) {
return NONINVERTIBLE_TRANSFORM;
}
downToDest.Invert();
Matrix4x4Flagged upToAncestor = GetTransformToAncestor(
RelativeTo{aFromFrame}, RelativeTo{nearestCommonAncestor});
Matrix4x4Flagged upToAncestor =
GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame =
aFromFrame->PresContext()->CSSToDevPixelScale();
CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame =
@ -2750,17 +2742,10 @@ nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoints(
}
nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoint(
RelativeTo aFromFrame, RelativeTo aToFrame, nsPoint& aPoint) {
// Conceptually, {ViewportFrame, Visual} is an ancestor of
// {ViewportFrame, Layout}, so factor that into the nearest ancestor
// computation.
RelativeTo nearestCommonAncestor{
FindNearestCommonAncestorFrame(aFromFrame.mFrame, aToFrame.mFrame),
aFromFrame.mViewportType == ViewportType::Visual ||
aToFrame.mViewportType == ViewportType::Visual
? ViewportType::Visual
: ViewportType::Layout};
if (!nearestCommonAncestor.mFrame) {
const nsIFrame* aFromFrame, const nsIFrame* aToFrame, nsPoint& aPoint) {
const nsIFrame* nearestCommonAncestor =
FindNearestCommonAncestorFrame(aFromFrame, aToFrame);
if (!nearestCommonAncestor) {
return NO_COMMON_ANCESTOR;
}
Matrix4x4Flagged downToDest =
@ -2773,9 +2758,9 @@ nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoint(
GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
float devPixelsPerAppUnitFromFrame =
1.0f / aFromFrame.mFrame->PresContext()->AppUnitsPerDevPixel();
1.0f / aFromFrame->PresContext()->AppUnitsPerDevPixel();
float devPixelsPerAppUnitToFrame =
1.0f / aToFrame.mFrame->PresContext()->AppUnitsPerDevPixel();
1.0f / aToFrame->PresContext()->AppUnitsPerDevPixel();
Point4D toDevPixels = downToDest.ProjectPoint(upToAncestor.TransformPoint(
Point(aPoint.x * devPixelsPerAppUnitFromFrame,
aPoint.y * devPixelsPerAppUnitFromFrame)));
@ -2796,14 +2781,14 @@ nsLayoutUtils::TransformResult nsLayoutUtils::TransformRect(
if (!nearestCommonAncestor) {
return NO_COMMON_ANCESTOR;
}
Matrix4x4Flagged downToDest = GetTransformToAncestor(
RelativeTo{aToFrame}, RelativeTo{nearestCommonAncestor});
Matrix4x4Flagged downToDest =
GetTransformToAncestor(aToFrame, nearestCommonAncestor);
if (downToDest.IsSingular()) {
return NONINVERTIBLE_TRANSFORM;
}
downToDest.Invert();
Matrix4x4Flagged upToAncestor = GetTransformToAncestor(
RelativeTo{aFromFrame}, RelativeTo{nearestCommonAncestor});
Matrix4x4Flagged upToAncestor =
GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
float devPixelsPerAppUnitFromFrame =
1.0f / aFromFrame->PresContext()->AppUnitsPerDevPixel();
@ -2926,9 +2911,8 @@ bool nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
return true;
}
static bool TransformGfxPointFromAncestor(RelativeTo aFrame,
const Point& aPoint,
RelativeTo aAncestor, Point* aOut) {
static bool TransformGfxPointFromAncestor(nsIFrame* aFrame, const Point& aPoint,
nsIFrame* aAncestor, Point* aOut) {
Matrix4x4Flagged ctm =
nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
ctm.Invert();
@ -2941,7 +2925,7 @@ static bool TransformGfxPointFromAncestor(RelativeTo aFrame,
}
static Rect TransformGfxRectToAncestor(
RelativeTo aFrame, const Rect& aRect, RelativeTo aAncestor,
const nsIFrame* aFrame, const Rect& aRect, const nsIFrame* aAncestor,
bool* aPreservesAxisAlignedRectangles = nullptr,
Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
@ -2969,7 +2953,7 @@ static Rect TransformGfxRectToAncestor(
*aPreservesAxisAlignedRectangles =
ctm.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles();
}
const nsIFrame* ancestor = aOutAncestor ? *aOutAncestor : aAncestor.mFrame;
const nsIFrame* ancestor = aOutAncestor ? *aOutAncestor : aAncestor;
float factor = ancestor->PresContext()->AppUnitsPerDevPixel();
Rect maxBounds =
Rect(float(nscoord_MIN) / factor * 0.5, float(nscoord_MIN) / factor * 0.5,
@ -2986,23 +2970,22 @@ static SVGTextFrame* GetContainingSVGTextFrame(const nsIFrame* aFrame) {
aFrame->GetParent(), LayoutFrameType::SVGText));
}
nsPoint nsLayoutUtils::TransformAncestorPointToFrame(RelativeTo aFrame,
nsPoint nsLayoutUtils::TransformAncestorPointToFrame(nsIFrame* aFrame,
const nsPoint& aPoint,
RelativeTo aAncestor) {
SVGTextFrame* text = GetContainingSVGTextFrame(aFrame.mFrame);
nsIFrame* aAncestor) {
SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
float factor = aFrame.mFrame->PresContext()->AppUnitsPerDevPixel();
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
Point result(NSAppUnitsToFloatPixels(aPoint.x, factor),
NSAppUnitsToFloatPixels(aPoint.y, factor));
if (!TransformGfxPointFromAncestor(
text ? RelativeTo{text, aFrame.mViewportType} : aFrame, result,
aAncestor, &result)) {
if (!TransformGfxPointFromAncestor(text ? text : aFrame, result, aAncestor,
&result)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
if (text) {
result = text->TransformFramePointToTextChild(result, aFrame.mFrame);
result = text->TransformFramePointToTextChild(result, aFrame);
}
return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
@ -3010,7 +2993,7 @@ nsPoint nsLayoutUtils::TransformAncestorPointToFrame(RelativeTo aFrame,
}
nsRect nsLayoutUtils::TransformFrameRectToAncestor(
const nsIFrame* aFrame, const nsRect& aRect, RelativeTo aAncestor,
const nsIFrame* aFrame, const nsRect& aRect, const nsIFrame* aAncestor,
bool* aPreservesAxisAlignedRectangles /* = nullptr */,
Maybe<Matrix4x4Flagged>* aMatrixCache /* = nullptr */,
bool aStopAtStackingContextAndDisplayPortAndOOFFrame /* = false */,
@ -3030,7 +3013,7 @@ nsRect nsLayoutUtils::TransformFrameRectToAncestor(
result.Scale(devPixelPerCSSPixel);
result = TransformGfxRectToAncestor(
RelativeTo{text}, result, aAncestor, nullptr, aMatrixCache,
text, result, aAncestor, nullptr, aMatrixCache,
aStopAtStackingContextAndDisplayPortAndOOFFrame, aOutAncestor);
// TransformFrameRectFromTextChild could involve any kind of transform, we
// could drill down into it to get an answer out of it but we don't yet.
@ -3043,13 +3026,13 @@ nsRect nsLayoutUtils::TransformFrameRectToAncestor(
NSAppUnitsToFloatPixels(aRect.width, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.height, srcAppUnitsPerDevPixel));
result = TransformGfxRectToAncestor(
RelativeTo{aFrame}, result, aAncestor, aPreservesAxisAlignedRectangles,
aFrame, result, aAncestor, aPreservesAxisAlignedRectangles,
aMatrixCache, aStopAtStackingContextAndDisplayPortAndOOFFrame,
aOutAncestor);
}
float destAppUnitsPerDevPixel =
aAncestor.mFrame->PresContext()->AppUnitsPerDevPixel();
aAncestor->PresContext()->AppUnitsPerDevPixel();
return nsRect(
NSFloatPixelsToAppUnits(float(result.x), destAppUnitsPerDevPixel),
NSFloatPixelsToAppUnits(float(result.y), destAppUnitsPerDevPixel),
@ -3105,19 +3088,16 @@ nsPoint nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext,
LayoutDeviceIntPoint nsLayoutUtils::TranslateViewToWidget(
nsPresContext* aPresContext, nsView* aView, nsPoint aPt,
ViewportType aViewportType, nsIWidget* aWidget) {
nsIWidget* aWidget) {
nsPoint viewOffset;
nsIWidget* viewWidget = aView->GetNearestWidget(&viewOffset);
if (!viewWidget) {
return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
nsPoint pt = (aPt + viewOffset);
// The target coordinates are visual, so perform a layout-to-visual
// conversion if the incoming coordinates are layout.
if (aViewportType == ViewportType::Layout && aPresContext->GetPresShell()) {
pt = ViewportUtils::LayoutToVisual(pt, aPresContext->GetPresShell());
}
nsPoint pt = (aPt + viewOffset)
.ApplyResolution(
GetCurrentAPZResolutionScale(aPresContext->PresShell()));
LayoutDeviceIntPoint relativeToViewWidget(
aPresContext->AppUnitsToDevPixels(pt.x),
aPresContext->AppUnitsToDevPixels(pt.y));
@ -3172,24 +3152,23 @@ struct AutoNestedPaintCount {
#endif
nsIFrame* nsLayoutUtils::GetFrameForPoint(
RelativeTo aRelativeTo, nsPoint aPt,
const nsIFrame* aFrame, nsPoint aPt,
EnumSet<FrameForPointOption> aOptions) {
AUTO_PROFILER_LABEL("nsLayoutUtils::GetFrameForPoint", LAYOUT);
nsresult rv;
AutoTArray<nsIFrame*, 8> outFrames;
rv = GetFramesForArea(aRelativeTo, nsRect(aPt, nsSize(1, 1)), outFrames,
aOptions);
rv = GetFramesForArea(aFrame, nsRect(aPt, nsSize(1, 1)), outFrames, aOptions);
NS_ENSURE_SUCCESS(rv, nullptr);
return outFrames.Length() ? outFrames.ElementAt(0) : nullptr;
}
nsresult nsLayoutUtils::GetFramesForArea(
RelativeTo aRelativeTo, const nsRect& aRect,
const nsIFrame* aFrame, const nsRect& aRect,
nsTArray<nsIFrame*>& aOutFrames, EnumSet<FrameForPointOption> aOptions) {
AUTO_PROFILER_LABEL("nsLayoutUtils::GetFramesForArea", LAYOUT);
nsIFrame* frame = const_cast<nsIFrame*>(aRelativeTo.mFrame);
nsIFrame* frame = const_cast<nsIFrame*>(aFrame);
nsDisplayListBuilder builder(frame, nsDisplayListBuilderMode::EventDelivery,
false);
@ -3200,14 +3179,11 @@ nsresult nsLayoutUtils::GetFramesForArea(
builder.IgnorePaintSuppression();
}
if (aOptions.contains(FrameForPointOption::IgnoreRootScrollFrame)) {
nsIFrame* rootScrollFrame = frame->PresShell()->GetRootScrollFrame();
nsIFrame* rootScrollFrame = aFrame->PresShell()->GetRootScrollFrame();
if (rootScrollFrame) {
builder.SetIgnoreScrollFrame(rootScrollFrame);
}
}
if (aRelativeTo.mViewportType == ViewportType::Layout) {
builder.SetIsRelativeToLayoutViewport();
}
if (aOptions.contains(FrameForPointOption::IgnoreCrossDoc)) {
builder.SetDescendIntoSubdocuments(false);
}

View File

@ -12,7 +12,6 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/Maybe.h"
#include "mozilla/RelativeTo.h"
#include "mozilla/StaticPrefs_nglayout.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/UniquePtr.h"
@ -148,8 +147,6 @@ class nsLayoutUtils {
typedef mozilla::layers::StackingContextHelper StackingContextHelper;
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
typedef mozilla::IntrinsicSize IntrinsicSize;
typedef mozilla::RelativeTo RelativeTo;
typedef mozilla::ViewportType ViewportType;
typedef mozilla::gfx::SourceSurface SourceSurface;
typedef mozilla::gfx::sRGBColor sRGBColor;
typedef mozilla::gfx::DrawTarget DrawTarget;
@ -772,7 +769,7 @@ class nsLayoutUtils {
* the event is not a GUI event).
*/
static nsPoint GetEventCoordinatesRelativeTo(
const mozilla::WidgetEvent* aEvent, RelativeTo aFrame);
const mozilla::WidgetEvent* aEvent, nsIFrame* aFrame);
/**
* Get the coordinates of a given point relative to an event and a
@ -786,7 +783,7 @@ class nsLayoutUtils {
*/
static nsPoint GetEventCoordinatesRelativeTo(
const mozilla::WidgetEvent* aEvent,
const mozilla::LayoutDeviceIntPoint& aPoint, RelativeTo aFrame);
const mozilla::LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame);
/**
* Get the coordinates of a given point relative to a widget and a
@ -800,7 +797,7 @@ class nsLayoutUtils {
*/
static nsPoint GetEventCoordinatesRelativeTo(
nsIWidget* aWidget, const mozilla::LayoutDeviceIntPoint& aPoint,
RelativeTo aFrame);
nsIFrame* aFrame);
/**
* Get the popup frame of a given native mouse event.
@ -846,13 +843,12 @@ class nsLayoutUtils {
* @param aPresContext the PresContext for the view
* @param aView the view
* @param aPt the point relative to the view
* @param aViewportType whether the point is in visual or layout coordinates
* @param aWidget the widget to which returned coordinates are relative
* @return the point in the view's coordinates
*/
static mozilla::LayoutDeviceIntPoint TranslateViewToWidget(
nsPresContext* aPresContext, nsView* aView, nsPoint aPt,
ViewportType aViewportType, nsIWidget* aWidget);
nsIWidget* aWidget);
static mozilla::LayoutDeviceIntPoint WidgetToWidgetOffset(
nsIWidget* aFromWidget, nsIWidget* aToWidget);
@ -882,23 +878,21 @@ class nsLayoutUtils {
* Given aFrame, the root frame of a stacking context, find its descendant
* frame under the point aPt that receives a mouse event at that location,
* or nullptr if there is no such frame.
* @param aPt the point, relative to the frame origin, in either visual
* or layout coordinates depending on aRelativeTo.mViewportType
* @param aPt the point, relative to the frame origin
* @param aFlags some combination of FrameForPointOption.
*/
static nsIFrame* GetFrameForPoint(RelativeTo aRelativeTo, nsPoint aPt,
static nsIFrame* GetFrameForPoint(const nsIFrame* aFrame, nsPoint aPt,
mozilla::EnumSet<FrameForPointOption> = {});
/**
* Given aFrame, the root frame of a stacking context, find all descendant
* frames under the area of a rectangle that receives a mouse event,
* or nullptr if there is no such frame.
* @param aRect the rect, relative to the frame origin, in either visual
* or layout coordinates depending on aRelativeTo.mViewportType
* @param aRect the rect, relative to the frame origin
* @param aOutFrames an array to add all the frames found
* @param aFlags some combination of FrameForPointOption.
*/
static nsresult GetFramesForArea(RelativeTo aRelativeTo, const nsRect& aRect,
static nsresult GetFramesForArea(const nsIFrame* aFrame, const nsRect& aRect,
nsTArray<nsIFrame*>& aOutFrames,
mozilla::EnumSet<FrameForPointOption> = {});
@ -927,17 +921,6 @@ class nsLayoutUtils {
bool* aPreservesAxisAlignedRectangles = nullptr,
mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
nsIFrame** aOutAncestor = nullptr) {
return TransformFrameRectToAncestor(
aFrame, aRect, RelativeTo{aAncestor}, aPreservesAxisAlignedRectangles,
aMatrixCache, aStopAtStackingContextAndDisplayPortAndOOFFrame,
aOutAncestor);
}
static nsRect TransformFrameRectToAncestor(
const nsIFrame* aFrame, const nsRect& aRect, RelativeTo aAncestor,
bool* aPreservesAxisAlignedRectangles = nullptr,
mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
nsIFrame** aOutAncestor = nullptr);
/**
@ -946,41 +929,9 @@ class nsLayoutUtils {
* flag in aFlags will return CSS pixels, by default it returns device
* pixels.
* More info can be found in nsIFrame::GetTransformMatrix.
*
* Some notes on the possible combinations of |aFrame.mViewportType| and
* |aAncestor.mViewportType|:
*
* | aFrame. | aAncestor. | Notes
* | mViewportType | mViewportType |
* ==========================================================================
* | Layout | Layout | Commonplace, when both source and target
* | | | are inside zoom boundary.
* | | |
* | | | Could also happen in non-e10s setups
* | | | when both source and target are outside
* | | | the zoom boundary and the code is
* | | | oblivious to the existence of a zoom
* | | | boundary.
* ==========================================================================
* | Layout | Visual | Commonplace, used when hit testing visual
* | | | coordinates (e.g. coming from user input
* | | | events). We expected to encounter a
* | | | zoomed content root during traversal and
* | | | apply a layout-to-visual transform.
* ==========================================================================
* | Visual | Layout | Should never happen, will assert.
* ==========================================================================
* | Visual | Visual | In e10s setups, should only happen if
* | | | aFrame and aAncestor are both the
* | | | RCD viewport frame.
* | | |
* | | | In non-e10s setups, could happen with
* | | | different frames if they are both
* | | | outside the zoom boundary.
* ==========================================================================
*/
static Matrix4x4Flagged GetTransformToAncestor(
RelativeTo aFrame, RelativeTo aAncestor, uint32_t aFlags = 0,
const nsIFrame* aFrame, const nsIFrame* aAncestor, uint32_t aFlags = 0,
nsIFrame** aOutAncestor = nullptr);
/**
@ -1028,8 +979,9 @@ class nsLayoutUtils {
* Same as above function, but transform points in app units and
* handle 1 point per call.
*/
static TransformResult TransformPoint(RelativeTo aFromFrame,
RelativeTo aToFrame, nsPoint& aPoint);
static TransformResult TransformPoint(const nsIFrame* aFromFrame,
const nsIFrame* aToFrame,
nsPoint& aPoint);
/**
* Transforms a rect from aFromFrame to aToFrame. In app units.
@ -1080,27 +1032,23 @@ class nsLayoutUtils {
* in the coordinate system of aFrame. This effectively inverts all
* transforms between this point and the root frame.
*
* @param aFromType Specifies whether |aPoint| is in layout or visual
* coordinates.
* @param aFrame The frame that acts as the coordinate space container.
* @param aPoint The point, in global layout or visual coordinates (as per
* |aFromType|, to get in the frame-local space.
* @param aPoint The point, in the global space, to get in the frame-local
* space.
* @return aPoint, expressed in aFrame's canonical coordinate space.
*/
static nsPoint TransformRootPointToFrame(ViewportType aFromType,
RelativeTo aFrame,
static nsPoint TransformRootPointToFrame(nsIFrame* aFrame,
const nsPoint& aPoint) {
return TransformAncestorPointToFrame(aFrame, aPoint,
RelativeTo{nullptr, aFromType});
return TransformAncestorPointToFrame(aFrame, aPoint, nullptr);
}
/**
* Transform aPoint relative to aAncestor down to the coordinate system of
* aFrame.
*/
static nsPoint TransformAncestorPointToFrame(RelativeTo aFrame,
static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame,
const nsPoint& aPoint,
RelativeTo aAncestor);
nsIFrame* aAncestor);
/**
* Helper function that, given a rectangle and a matrix, returns the smallest

View File

@ -466,8 +466,7 @@ nsPoint nsComboboxControlFrame::GetCSSTransformTranslation() {
Matrix transform;
while (frame) {
nsIFrame* parent;
Matrix4x4Flagged ctm = frame->GetTransformMatrix(
ViewportType::Layout, RelativeTo{nullptr}, &parent);
Matrix4x4Flagged ctm = frame->GetTransformMatrix(nullptr, &parent);
Matrix matrix;
if (ctm.Is2D(&matrix)) {
transform = transform * matrix;

View File

@ -140,8 +140,7 @@ nsresult nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
mContent->GetProperty(nsGkAtoms::imageClickedPoint));
if (lastClickPoint) {
// normally lastClickedPoint is not null, as it's allocated in Init()
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
TranslateEventCoords(pt, *lastClickPoint);
}
}

View File

@ -196,7 +196,7 @@ int32_t nsNumberControlFrame::GetSpinButtonForPointerEvent(
// default UA style sheet. See the comment in forms.css for why.
LayoutDeviceIntPoint absPoint = aEvent->mRefPoint;
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, absPoint, RelativeTo{mSpinBox->GetPrimaryFrame()});
aEvent, absPoint, mSpinBox->GetPrimaryFrame());
if (point != nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
if (point.y < mSpinBox->GetPrimaryFrame()->GetSize().height / 2) {
return eSpinButtonUp;

View File

@ -497,8 +497,8 @@ Decimal nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) {
} else {
absPoint = aEvent->mRefPoint;
}
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, absPoint, RelativeTo{this});
nsPoint point =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, absPoint, this);
if (point == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
// We don't want to change the current value for this error state.

View File

@ -27,7 +27,6 @@
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/ToString.h"
#include "mozilla/ViewportUtils.h"
#include "nsCOMPtr.h"
#include "nsFlexContainerFrame.h"
@ -4735,7 +4734,7 @@ nsFrame::HandlePress(nsPresContext* aPresContext, WidgetGUIEvent* aEvent,
// coordinate stuff is the fix for bug #55921
if ((mRect - GetPosition())
.Contains(nsLayoutUtils::GetEventCoordinatesRelativeTo(
mouseEvent, RelativeTo{this}))) {
mouseEvent, this))) {
return NS_OK;
}
}
@ -4796,8 +4795,7 @@ nsFrame::HandlePress(nsPresContext* aPresContext, WidgetGUIEvent* aEvent,
return HandleMultiplePress(aPresContext, mouseEvent, aEventStatus, control);
}
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent,
RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
ContentOffsets offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
if (!offsets.content) return NS_ERROR_FAILURE;
@ -4978,8 +4976,8 @@ nsFrame::HandleMultiplePress(nsPresContext* aPresContext,
return NS_OK;
}
nsPoint relPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
mouseEvent, RelativeTo{this});
nsPoint relPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
return SelectByTypeAtPoint(aPresContext, relPoint, beginAmount, endAmount,
(aControlHeld ? SELECT_ACCUMULATE : 0));
}
@ -5092,8 +5090,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPresContext* aPresContext,
return result;
}
} else {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent,
RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
frameselection->HandleDrag(this, pt);
}
@ -5111,8 +5108,8 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPresContext* aPresContext,
if (scrollFrame) {
nsIFrame* capturingFrame = scrollFrame->GetScrolledFrame();
if (capturingFrame) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
mouseEvent, RelativeTo{capturingFrame});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent,
capturingFrame);
frameselection->StartAutoScrollTimer(capturingFrame, pt, 30);
}
}
@ -5216,8 +5213,7 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsPresContext* aPresContext,
// Place the caret before continuing!
if (frameselection->MouseDownRecorded()) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
handleTableSelection = false;
} else {
@ -5691,8 +5687,8 @@ nsIFrame::ContentOffsets nsIFrame::GetContentOffsetsFromPoint(
nsPoint pt;
if (closest.frame != this) {
if (nsSVGUtils::IsInSVGTextSubtree(closest.frame)) {
pt = nsLayoutUtils::TransformAncestorPointToFrame(
RelativeTo{closest.frame}, aPoint, RelativeTo{this});
pt = nsLayoutUtils::TransformAncestorPointToFrame(closest.frame, aPoint,
this);
} else {
pt = aPoint - closest.frame->GetOffsetTo(this);
}
@ -7248,8 +7244,7 @@ nsIWidget* nsIFrame::GetNearestWidget(nsPoint& aOffset) const {
return widget;
}
Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
RelativeTo aStopAtAncestor,
Matrix4x4Flagged nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
nsIFrame** aOutAncestor,
uint32_t aFlags) const {
MOZ_ASSERT(aOutAncestor, "Need a place to put the ancestor!");
@ -7258,53 +7253,20 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
* transform/translate matrix that will apply our current transform, then
* shift us to our parent.
*/
bool isTransformed = IsTransformed();
const nsIFrame* zoomedContentRoot = nullptr;
if (aStopAtAncestor.mViewportType == ViewportType::Visual) {
zoomedContentRoot = ViewportUtils::IsZoomedContentRoot(this);
if (zoomedContentRoot) {
MOZ_ASSERT(aViewportType != ViewportType::Visual);
}
}
if (isTransformed || zoomedContentRoot) {
Matrix4x4 result;
if (IsTransformed()) {
/* Compute the delta to the parent, which we need because we are converting
* coordinates to our parent.
*/
NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this),
"Cannot transform the viewport frame!");
int32_t scaleFactor =
((aFlags & IN_CSS_UNITS) ? AppUnitsPerCSSPixel()
: PresContext()->AppUnitsPerDevPixel());
/* Compute the delta to the parent, which we need because we are converting
* coordinates to our parent.
*/
if (isTransformed) {
NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this),
"Cannot transform the viewport frame!");
result = result * nsDisplayTransform::GetResultingTransformMatrix(
this, nsPoint(0, 0), scaleFactor,
nsDisplayTransform::INCLUDE_PERSPECTIVE |
nsDisplayTransform::OFFSET_BY_ORIGIN);
}
if (zoomedContentRoot) {
Matrix4x4 layoutToVisual;
ScrollableLayerGuid::ViewID targetScrollId =
nsLayoutUtils::FindOrCreateIDFor(zoomedContentRoot->GetContent());
if (aFlags & nsIFrame::IN_CSS_UNITS) {
layoutToVisual =
ViewportUtils::GetVisualToLayoutTransform(targetScrollId)
.Inverse()
.ToUnknownMatrix();
} else {
layoutToVisual =
ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(
targetScrollId)
.Inverse()
.ToUnknownMatrix();
}
result = result * layoutToVisual;
}
Matrix4x4 result = nsDisplayTransform::GetResultingTransformMatrix(
this, nsPoint(0, 0), scaleFactor,
nsDisplayTransform::INCLUDE_PERSPECTIVE |
nsDisplayTransform::OFFSET_BY_ORIGIN);
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(this);
nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
/* Combine the raw transform with a translation to our parent. */
@ -7341,8 +7303,7 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
*aOutAncestor = docRootFrame;
Matrix4x4 docRootTransformToTop =
nsLayoutUtils::GetTransformToAncestor(RelativeTo{docRootFrame},
RelativeTo{nullptr})
nsLayoutUtils::GetTransformToAncestor(docRootFrame, nullptr)
.GetMatrix();
if (docRootTransformToTop.IsSingular()) {
NS_WARNING(
@ -7370,16 +7331,12 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
/* Keep iterating while the frame can't possibly be transformed. */
const nsIFrame* current = this;
auto shouldStopAt = [](const nsIFrame* aCurrent, nsIFrame* aAncestor,
uint32_t aFlags) {
return aAncestor->IsTransformed() || nsLayoutUtils::IsPopup(aAncestor) ||
ViewportUtils::IsZoomedContentRoot(aAncestor) ||
((aFlags & STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT) &&
(aAncestor->IsStackingContext() ||
nsLayoutUtils::FrameHasDisplayPort(aAncestor, aCurrent)));
};
while (*aOutAncestor != aStopAtAncestor.mFrame &&
!shouldStopAt(current, *aOutAncestor, aFlags)) {
while (!(*aOutAncestor)->IsTransformed() &&
!nsLayoutUtils::IsPopup(*aOutAncestor) &&
*aOutAncestor != aStopAtAncestor &&
(!(aFlags & STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT) ||
(!(*aOutAncestor)->IsStackingContext() &&
!nsLayoutUtils::FrameHasDisplayPort(*aOutAncestor, current)))) {
/* If no parent, stop iterating. Otherwise, update the ancestor. */
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(*aOutAncestor);
if (!parent) break;

View File

@ -521,7 +521,7 @@ nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(
nsIFrame* rootFrame = mPresShell->GetRootFrame();
nsPoint ptInRoot = aPoint + aFrame->GetOffsetTo(rootFrame);
nsIFrame* cursorFrame =
nsLayoutUtils::GetFrameForPoint(RelativeTo{rootFrame}, ptInRoot);
nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
// If the mouse cursor in on a frame which is descendant of same
// selection root, we can expand the selection to the frame.

View File

@ -44,7 +44,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/ScrollbarPreferences.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
@ -3559,7 +3558,7 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool haveRadii = mOuter->GetPaddingBoxBorderRadii(radii);
if (mIsRoot) {
clipRect.SizeTo(nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
if (aBuilder->IsRelativeToLayoutViewport() &&
if (!aBuilder->IsPaintingToWindow() &&
mOuter->PresContext()->IsRootContentDocument()) {
double res = mOuter->PresShell()->GetResolution();
clipRect.width = NSToCoordRound(clipRect.width / res);
@ -3668,22 +3667,8 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
scrolledRectClipState.SetClippedToDisplayPort();
}
nsRect visibleRectForChildren = visibleRect;
nsRect dirtyRectForChildren = dirtyRect;
// If we are entering the RCD-RSF, we are crossing the async zoom
// container boundary, and need to convert from visual to layout
// coordinates.
if (willBuildAsyncZoomContainer && aBuilder->IsForEventDelivery()) {
MOZ_ASSERT(ViewportUtils::IsZoomedContentRoot(mScrolledFrame));
visibleRectForChildren = ViewportUtils::VisualToLayout(
visibleRectForChildren, mOuter->PresShell());
dirtyRectForChildren = ViewportUtils::VisualToLayout(
dirtyRectForChildren, mOuter->PresShell());
}
nsDisplayListBuilder::AutoBuildingDisplayList building(
aBuilder, mOuter, visibleRectForChildren, dirtyRectForChildren);
aBuilder, mOuter, visibleRect, dirtyRect);
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, set);
@ -7055,8 +7040,7 @@ bool ScrollFrameHelper::DragScroll(WidgetEvent* aEvent) {
// far as it can go in both directions. Return false so that an ancestor
// scrollframe can scroll instead.
bool willScroll = false;
nsPoint pnt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, RelativeTo{mOuter});
nsPoint pnt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mOuter);
nsPoint scrollPoint = GetScrollPosition();
nsRect rangeRect = GetLayoutScrollRange();

View File

@ -2935,8 +2935,6 @@ class nsIFrame : public nsQueryFrame {
* The frame decides which ancestor it will use as a reference point.
* If this frame has no ancestor, aOutAncestor will be set to null.
*
* @param aViewportType specifies whether the starting point is layout
* or visual coordinates
* @param aStopAtAncestor don't look further than aStopAtAncestor. If null,
* all ancestors (including across documents) will be traversed.
* @param aOutAncestor [out] The ancestor frame the frame has chosen. If
@ -2945,16 +2943,14 @@ class nsIFrame : public nsQueryFrame {
* document as this frame. If this frame IsTransformed(), then *aOutAncestor
* will be the parent frame (if not preserve-3d) or the nearest
* non-transformed ancestor (if preserve-3d).
* @return A Matrix4x4 that converts points in the coordinate space
* RelativeTo{this, aViewportType} into points in aOutAncestor's
* coordinate space.
* @return A Matrix4x4 that converts points in this frame's coordinate space
* into points in aOutAncestor's coordinate space.
*/
enum {
IN_CSS_UNITS = 1 << 0,
STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT = 1 << 1
};
Matrix4x4Flagged GetTransformMatrix(mozilla::ViewportType aViewportType,
mozilla::RelativeTo aStopAtAncestor,
Matrix4x4Flagged GetTransformMatrix(const nsIFrame* aStopAtAncestor,
nsIFrame** aOutAncestor,
uint32_t aFlags = 0) const;

View File

@ -2261,8 +2261,7 @@ nsresult nsImageFrame::GetContentForEvent(WidgetEvent* aEvent,
if (nsImageMap* map = GetImageMap()) {
nsIntPoint p;
TranslateEventCoords(
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, RelativeTo{this}),
p);
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
nsCOMPtr<nsIContent> area = map->GetArea(p.x, p.y);
if (area) {
area.forget(aContent);
@ -2288,9 +2287,8 @@ nsresult nsImageFrame::HandleEvent(nsPresContext* aPresContext,
bool isServerMap = IsServerImageMap();
if (map || isServerMap) {
nsIntPoint p;
TranslateEventCoords(nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{this}),
p);
TranslateEventCoords(
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
bool inside = false;
// Even though client-side image map triggering happens
// through content, we need to make sure we're not inside

View File

@ -394,6 +394,7 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsRect visible;
nsRect dirty;
bool ignoreViewportScrolling = false;
nsIFrame* savedIgnoreScrollFrame = nullptr;
if (subdocRootFrame) {
// get the dirty rect relative to the root frame of the subdoc
visible = aBuilder->GetVisibleRect() + GetOffsetToCrossDoc(subdocRootFrame);
@ -402,8 +403,10 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
visible = visible.ScaleToOtherAppUnitsRoundOut(parentAPD, subdocAPD);
dirty = dirty.ScaleToOtherAppUnitsRoundOut(parentAPD, subdocAPD);
if (nsIScrollableFrame* rootScrollableFrame =
presShell->GetRootScrollFrameAsScrollable()) {
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
nsIScrollableFrame* rootScrollableFrame =
presShell->GetRootScrollFrameAsScrollable();
MOZ_ASSERT(rootScrollableFrame);
// Use a copy, so the rects don't get modified.
nsRect copyOfDirty = dirty;
nsRect copyOfVisible = visible;
@ -413,6 +416,10 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
/* aSetBase = */ true);
ignoreViewportScrolling = presShell->IgnoringViewportScrolling();
if (ignoreViewportScrolling) {
savedIgnoreScrollFrame = aBuilder->GetIgnoreScrollFrame();
aBuilder->SetIgnoreScrollFrame(rootScrollFrame);
}
}
aBuilder->EnterPresShell(subdocRootFrame, pointerEventsNone);
@ -507,6 +514,10 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (subdocRootFrame) {
aBuilder->LeavePresShell(subdocRootFrame, &childItems);
if (ignoreViewportScrolling) {
aBuilder->SetIgnoreScrollFrame(savedIgnoreScrollFrame);
}
}
// Generate a resolution and/or zoom item if needed. If one or both of those

View File

@ -6503,9 +6503,7 @@ gfxSize FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame) {
Matrix4x4Flagged transform = Matrix4x4::Scaling(resolution, resolution, 1.0);
if (aFrame != root) {
// aTransform is applied first, then the scale is applied to the result
transform = nsLayoutUtils::GetTransformToAncestor(RelativeTo{aFrame},
RelativeTo{root}) *
transform;
transform = nsLayoutUtils::GetTransformToAncestor(aFrame, root) * transform;
}
Matrix transform2d;

View File

@ -34,7 +34,6 @@
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/ViewportUtils.h"
#include "nsCSSRendering.h"
#include "nsCSSRenderingGradients.h"
#include "nsRegion.h"
@ -102,7 +101,6 @@
#include "nsFocusManager.h"
#include "ClientLayerManager.h"
#include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TreeTraversal.h"
@ -1228,7 +1226,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mIsInActiveDocShell(false),
mBuildAsyncZoomContainer(false),
mContainsBackdropFilter(false),
mIsRelativeToLayoutViewport(false),
mHitTestArea(),
mHitTestInfo(CompositorHitTestInvisibleToHit) {
MOZ_COUNT_CTOR(nsDisplayListBuilder);
@ -1451,15 +1448,9 @@ AnimatedGeometryRoot* nsDisplayListBuilder::FindAnimatedGeometryRootFor(
return FindAnimatedGeometryRootFor(aItem->Frame());
}
void nsDisplayListBuilder::SetIsRelativeToLayoutViewport() {
mIsRelativeToLayoutViewport = true;
UpdateShouldBuildAsyncZoomContainer();
}
void nsDisplayListBuilder::UpdateShouldBuildAsyncZoomContainer() {
Document* document = mReferenceFrame->PresContext()->Document();
mBuildAsyncZoomContainer = !mIsRelativeToLayoutViewport &&
nsLayoutUtils::AllowZoomingForDocument(document);
mBuildAsyncZoomContainer = nsLayoutUtils::AllowZoomingForDocument(document);
}
// Certain prefs may cause display list items to be added or removed when they
@ -1847,29 +1838,8 @@ void nsDisplayListBuilder::MarkFramesForDisplayList(
const DisplayItemClipChain* combinedClipChain =
mClipState.GetCurrentCombinedClipChain(this);
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
nsRect visibleRect = GetVisibleRect();
nsRect dirtyRect = GetDirtyRect();
// If we are entering content that is fixed to the RCD-RSF, we are
// crossing the async zoom container boundary, and need to convert from
// visual to layout coordinates.
if (ViewportFrame* viewportFrame = do_QueryFrame(aDirtyFrame)) {
if (IsForEventDelivery() && ShouldBuildAsyncZoomContainer() &&
viewportFrame->PresContext()->IsRootContentDocument()) {
#ifdef DEBUG
for (nsIFrame* f : aFrames) {
MOZ_ASSERT(ViewportUtils::IsZoomedContentRoot(f));
}
#endif
visibleRect = ViewportUtils::VisualToLayout(visibleRect,
viewportFrame->PresShell());
dirtyRect = ViewportUtils::VisualToLayout(dirtyRect,
viewportFrame->PresShell());
}
}
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(
clipChain, combinedClipChain, asr, visibleRect, dirtyRect);
clipChain, combinedClipChain, asr, GetVisibleRect(), GetDirtyRect());
aDirtyFrame->SetProperty(
nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
mFramesWithOOFData.AppendElement(aDirtyFrame);
@ -2246,8 +2216,8 @@ void nsDisplayListBuilder::AdjustWindowDraggingRegion(nsIFrame* aFrame) {
// RTL mode - it should be able to exclude itself from the draggable region.
referenceFrameToRootReferenceFrame =
ViewAs<LayoutDeviceToLayoutDeviceMatrix4x4>(
nsLayoutUtils::GetTransformToAncestor(RelativeTo{referenceFrame},
RelativeTo{mReferenceFrame})
nsLayoutUtils::GetTransformToAncestor(referenceFrame,
mReferenceFrame)
.GetMatrix());
Matrix referenceFrameToRootReferenceFrame2d;
if (!referenceFrameToRootReferenceFrame.Is2D(
@ -7178,6 +7148,14 @@ nsDisplayResolution::nsDisplayResolution(nsDisplayListBuilder* aBuilder,
MOZ_COUNT_CTOR(nsDisplayResolution);
}
void nsDisplayResolution::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect, HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) {
PresShell* presShell = mFrame->PresShell();
nsRect rect = aRect.RemoveResolution(presShell->GetResolution());
mList.HitTest(aBuilder, rect, aState, aOutFrames);
}
already_AddRefed<Layer> nsDisplayResolution::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
@ -7912,18 +7890,6 @@ nsDisplayAsyncZoom::~nsDisplayAsyncZoom() {
}
#endif
void nsDisplayAsyncZoom::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect, HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) {
#ifdef DEBUG
nsIScrollableFrame* scrollFrame = do_QueryFrame(mFrame);
MOZ_ASSERT(scrollFrame && ViewportUtils::IsZoomedContentRoot(
scrollFrame->GetScrolledFrame()));
#endif
nsRect rect = ViewportUtils::VisualToLayout(aRect, mFrame->PresShell());
mList.HitTest(aBuilder, rect, aState, aOutFrames);
}
already_AddRefed<Layer> nsDisplayAsyncZoom::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
@ -8437,8 +8403,7 @@ auto nsDisplayTransform::ShouldPrerenderTransformedContent(
nsSize maxSize = Min(relativeLimit, absoluteLimit);
const auto transform = nsLayoutUtils::GetTransformToAncestor(
RelativeTo{aFrame},
RelativeTo{nsLayoutUtils::GetDisplayRootFrame(aFrame)});
aFrame, nsLayoutUtils::GetDisplayRootFrame(aFrame));
const gfxRect transformedBounds = transform.TransformAndClipBounds(
gfxRect(overflow.x, overflow.y, overflow.width, overflow.height),
gfxRect::MaxIntRect());

View File

@ -585,10 +585,6 @@ class nsDisplayListBuilder {
* Get the scrollframe to ignore, if any.
*/
nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
void SetIsRelativeToLayoutViewport();
bool IsRelativeToLayoutViewport() const {
return mIsRelativeToLayoutViewport;
}
/**
* Get the ViewID of the nearest scrolling ancestor frame.
*/
@ -1521,12 +1517,6 @@ class nsDisplayListBuilder {
const DisplayItemClipChain*
mCombinedClipChain; // only necessary for the special case of top layer
const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
// If this OutOfFlowDisplayData is associated with the ViewportFrame
// of a document that has a resolution (creating separate visual and
// layout viewports with their own coordinate spaces), these rects
// are in layout coordinates. Similarly, GetVisibleRectForFrame() in
// such a case returns a quantity in layout coordinates.
nsRect mVisibleRect;
nsRect mDirtyRect;
@ -2034,7 +2024,6 @@ class nsDisplayListBuilder {
bool mIsInActiveDocShell;
bool mBuildAsyncZoomContainer;
bool mContainsBackdropFilter;
bool mIsRelativeToLayoutViewport;
nsRect mHitTestArea;
CompositorHitTestInfo mHitTestInfo;
@ -6186,6 +6175,8 @@ class nsDisplayResolution : public nsDisplaySubDocument {
NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
@ -6513,12 +6504,10 @@ class nsDisplayAsyncZoom : public nsDisplayOwnLayer {
NS_DISPLAY_DECL_NAME("AsyncZoom", TYPE_ASYNC_ZOOM)
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
already_AddRefed<Layer> BuildLayer(
virtual already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
LayerState GetLayerState(
virtual LayerState GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) override {
return mozilla::LayerState::LAYER_ACTIVE_FORCE;

View File

@ -5234,8 +5234,8 @@ double SVGTextFrame::GetFontSizeScaleFactor() const {
* it to the appropriate frame user space of aChildFrame according to
* which rendered run the point hits.
*/
Point SVGTextFrame::TransformFramePointToTextChild(
const Point& aPoint, const nsIFrame* aChildFrame) {
Point SVGTextFrame::TransformFramePointToTextChild(const Point& aPoint,
nsIFrame* aChildFrame) {
NS_ASSERTION(aChildFrame && nsLayoutUtils::GetClosestFrameOfType(
aChildFrame->GetParent(),
LayoutFrameType::SVGText) == this,

View File

@ -317,7 +317,7 @@ class SVGTextFrame final : public nsSVGDisplayContainerFrame {
* according to which rendered run the point hits.
*/
Point TransformFramePointToTextChild(const Point& aPoint,
const nsIFrame* aChildFrame);
nsIFrame* aChildFrame);
/**
* Takes an app unit rectangle in the coordinate space of a given descendant

View File

@ -308,7 +308,7 @@ nsIFrame* nsSVGForeignObjectFrame::GetFrameForPoint(const gfxPoint& aPoint) {
gfxPoint pt = (aPoint + gfxPoint(x, y)) * AppUnitsPerCSSPixel();
nsPoint point = nsPoint(NSToIntRound(pt.x), NSToIntRound(pt.y));
return nsLayoutUtils::GetFrameForPoint(RelativeTo{kid}, point);
return nsLayoutUtils::GetFrameForPoint(kid, point);
}
void nsSVGForeignObjectFrame::ReflowSVG() {

View File

@ -310,8 +310,7 @@ nsIFrame* nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame,
nsSVGUtils::eForGetClientRects | nsSVGUtils::eBBoxIncludeFill |
nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeMarkers;
auto ctm = nsLayoutUtils::GetTransformToAncestor(RelativeTo{aFrame},
RelativeTo{outer});
auto ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, outer);
float initPositionX = NSAppUnitsToFloatPixels(aFrame->GetPosition().x,
AppUnitsPerCSSPixel()),

View File

@ -1195,8 +1195,7 @@ void nsBoxFrame::WrapListsInRedirector(nsDisplayListBuilder* aBuilder,
bool nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsPoint& aPoint) {
LayoutDeviceIntPoint refPoint;
bool res = GetEventPoint(aEvent, refPoint);
aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, refPoint,
RelativeTo{this});
aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, refPoint, this);
return res;
}

View File

@ -68,8 +68,8 @@ nsresult nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
mCursorOnThis = false;
break;
case eMouseMove: {
nsPoint cursor = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{this});
nsPoint cursor =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
nsRect frameRect(nsPoint(0, 0), GetSize());
mCursorOnThis = frameRect.Contains(cursor);
break;

View File

@ -385,8 +385,8 @@ void nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext,
bool isHorizontal = !mOuter->IsXULHorizontal();
// convert coord to pixels
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
aEvent, RelativeTo{mParentBox});
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mParentBox);
nscoord pos = isHorizontal ? pt.x : pt.y;
// mDragStart is in frame coordinates

View File

@ -616,7 +616,7 @@ void nsXULPopupManager::InitTriggerEvent(Event* aEvent, nsIContent* aPopup,
thisDocToRootDocOffset.y);
} else if (rootDocumentRootFrame) {
nsPoint pnt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
event, RelativeTo{rootDocumentRootFrame});
event, rootDocumentRootFrame);
mCachedMousePoint = LayoutDeviceIntPoint(
rootDocPresContext->AppUnitsToDevPixels(pnt.x),
rootDocPresContext->AppUnitsToDevPixels(pnt.y));

View File

@ -2273,8 +2273,7 @@ nsresult nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
WidgetGUIEvent* aEvent,
nsEventStatus* aEventStatus) {
if (aEvent->mMessage == eMouseOver || aEvent->mMessage == eMouseMove) {
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
int32_t xTwips = pt.x - mInnerBox.x;
int32_t yTwips = pt.y - mInnerBox.y;
int32_t newrow = GetRowAtInternal(xTwips, yTwips);
@ -4036,8 +4035,7 @@ void nsTreeBodyFrame::ComputeDropPosition(WidgetGUIEvent* aEvent, int32_t* aRow,
// Convert the event's point to our coordinates. We want it in
// the coordinates of our inner box's coordinates.
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, RelativeTo{this});
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
int32_t xTwips = pt.x - mInnerBox.x;
int32_t yTwips = pt.y - mInnerBox.y;

View File

@ -1,6 +1,6 @@
[Event-dispatch-redispatch.html]
[Redispatching mouseup event whose default action dispatches a click event]
expected:
if (os == "mac") or (os == "android"): PASS
if os == "mac": PASS
FAIL

View File

@ -1,6 +1,6 @@
[elementTiming.html]
[TestDriver actions: element timing]
expected:
if os == "android": FAIL
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1627365
if os == "android" and not e10s: FAIL
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1499957

View File

@ -1186,7 +1186,7 @@ bool nsTypeAheadFind::IsRangeRendered(nsRange* aRange) {
nsPresContext::CSSPixelsToAppUnits((float)rect->Height()));
// Append visible frames to frames array.
nsLayoutUtils::GetFramesForArea(
RelativeTo{rootFrame}, r, frames,
rootFrame, r, frames,
{FrameForPointOption::IgnorePaintSuppression,
FrameForPointOption::IgnoreRootScrollFrame,
FrameForPointOption::OnlyVisible});

View File

@ -559,9 +559,6 @@ class WidgetEvent : public WidgetEventTime {
EventMessage mMessage;
// Relative to the widget of the event, or if there is no widget then it is
// in screen coordinates. Not modified by layout code.
// This is in visual coordinates, i.e. the correct RelativeTo value that
// expresses what this is relative to is `{viewportFrame, Visual}`, where
// `viewportFrame` is the viewport frame of the widget's root document.
LayoutDeviceIntPoint mRefPoint;
// The previous mRefPoint, if known, used to calculate mouse movement deltas.
LayoutDeviceIntPoint mLastRefPoint;

View File

@ -421,6 +421,7 @@ WidgetMouseEvent MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const {
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
event.mClickCount = clickCount;
event.mInputSource = mInputSource;
event.mIgnoreRootScrollFrame = true;
event.mFocusSequenceNumber = mFocusSequenceNumber;
return event;

View File

@ -395,6 +395,15 @@ nsEventStatus PuppetWidget::DispatchInputEvent(WidgetInputEvent* aEvent) {
return nsEventStatus_eIgnore;
}
if (PresShell* presShell = mBrowserChild->GetTopLevelPresShell()) {
// Because the root resolution is conceptually at the parent/child process
// boundary, we need to apply that resolution here because we're sending
// the event from the child to the parent process.
LayoutDevicePoint pt(aEvent->mRefPoint);
pt = pt * presShell->GetResolution();
aEvent->mRefPoint = LayoutDeviceIntPoint::Round(pt);
}
switch (aEvent->mClass) {
case eWheelEventClass:
Unused << mBrowserChild->SendDispatchWheelEvent(*aEvent->AsWheelEvent());

View File

@ -2097,6 +2097,7 @@ void nsWindow::DispatchHitTest(const WidgetTouchEvent& aEvent) {
WidgetMouseEvent hittest(true, eMouseHitTest, this,
WidgetMouseEvent::eReal);
hittest.mRefPoint = aEvent.mTouches[0]->mRefPoint;
hittest.mIgnoreRootScrollFrame = true;
hittest.mInputSource = MouseEvent_Binding::MOZ_SOURCE_TOUCH;
nsEventStatus status;
DispatchEvent(&hittest, status);

View File

@ -968,6 +968,17 @@ nsEventStatus nsBaseWidget::ProcessUntransformedAPZEvent(
InputAPZContext context(aApzResult.mTargetGuid, inputBlockId,
aApzResult.mStatus);
// If this is an event that the APZ has targeted to an APZC in the root
// process, apply that APZC's callback-transform before dispatching the
// event. If the event is instead targeted to an APZC in the child process,
// the transform will be applied in the child process before dispatching
// the event there (see e.g. BrowserChild::RecvRealTouchEvent()).
if (aApzResult.mTargetGuid.mLayersId ==
mCompositorSession->RootLayerTreeId()) {
APZCCallbackHelper::ApplyCallbackTransform(*aEvent, targetGuid,
GetDefaultScale());
}
// Make a copy of the original event for the APZCCallbackHelper helpers that
// we call later, because the event passed to DispatchEvent can get mutated in
// ways that we don't want (i.e. touch points can get stripped out).