mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1684795 - Account for desktop zooming when opening content popups. r=tnikkel
In OOP iframes, we don't have desktop zoom value specifically in each iframe documents, instead we have a transform matrix, nsIWidget::WidgetToTopLevelWidgetTransform(), on each the __top__ level OOP iframe document that the matrix includes the desktop zoom scale value along with translations by ancestor scroll containers, ancestor CSS transforms, etc. Note that if the document is not in OOP iframes, i.e. it's in the top level content subtree, the transform, nsIWidget::WidgetToTopLevelWidgetTransform() doesn't include the destktop zoom value, so for documents in the top level content document subtree, ViewportUtils::DocumentRelativeLayoutToVisual applies the desktop zoom value via PresShell::GetResolution(). Differential Revision: https://phabricator.services.mozilla.com/D102219
This commit is contained in:
parent
0abab2be63
commit
0507ed1cd2
@ -1607,6 +1607,53 @@ nsDOMWindowUtils::TransformRectLayoutToVisual(float aX, float aY, float aWidth,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ToScreenRect(float aX, float aY, float aWidth, float aHeight,
|
||||
DOMRect** aResult) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
PresShell* presShell = GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
NS_ENSURE_TRUE(widget, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Note that if the document is NOT in OOP iframes, i.e. it's in the top level
|
||||
// content subtree in the same process,
|
||||
// nsIWidget::WidgetToTopLevelWidgetTransform() doesn't include the desktop
|
||||
// zoom value, so for documents in the top level content document subtree,
|
||||
// this ViewportUtils::DocumentRelativeLayoutToVisual call applies the desktop
|
||||
// zoom value via PresShell::GetResolution() in the function.
|
||||
CSSRect rect(aX, aY, aWidth, aHeight);
|
||||
rect = ViewportUtils::DocumentRelativeLayoutToVisual(rect, presShell);
|
||||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
MOZ_ASSERT(presContext);
|
||||
|
||||
// For OOP iframe documents, we don't have desktop zoom value specifically in
|
||||
// each iframe documents (i.e. the in-process root presshell's resolution is
|
||||
// 1.0), instead nsIWidget::WidgetToTopLevelWidgetTransform() includes the
|
||||
// desktop zoom scale value along with translations by ancestor scroll
|
||||
// containers, ancestor CSS transforms, etc.
|
||||
nsRect appUnitsRect = CSSPixel::ToAppUnits(rect);
|
||||
LayoutDeviceRect devPixelsRect = LayoutDeviceRect::FromAppUnits(
|
||||
appUnitsRect, presContext->AppUnitsPerDevPixel());
|
||||
devPixelsRect =
|
||||
widget->WidgetToTopLevelWidgetTransform().TransformBounds(devPixelsRect) +
|
||||
widget->TopLevelWidgetToScreenOffset();
|
||||
|
||||
appUnitsRect = LayoutDeviceRect::ToAppUnits(
|
||||
devPixelsRect,
|
||||
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
|
||||
rect = CSSRect::FromAppUnits(appUnitsRect);
|
||||
|
||||
RefPtr<DOMRect> outRect = new DOMRect(window);
|
||||
outRect->SetRect(rect.x, rect.y, rect.width, rect.height);
|
||||
outRect.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetDynamicToolbarMaxHeight(uint32_t aHeightInScreen) {
|
||||
if (aHeightInScreen > INT32_MAX) {
|
||||
|
@ -916,6 +916,13 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
DOMRect transformRectLayoutToVisual(in float aX, in float aY,
|
||||
in float aWidth, in float aHeight);
|
||||
|
||||
/**
|
||||
* Transform a rectangle given in coordinates relative to this document
|
||||
* into CSS coordinates relative to the screen.
|
||||
*/
|
||||
DOMRect toScreenRect(in float aX, in float aY,
|
||||
in float aWidth, in float aHeight);
|
||||
|
||||
/**
|
||||
* Sets the maximum height of the dynamic toolbar in Screen pixel units.
|
||||
*/
|
||||
|
@ -10,29 +10,17 @@ var EXPORTED_SYMBOLS = ["LayoutUtils"];
|
||||
var LayoutUtils = {
|
||||
/**
|
||||
* For a given DOM element, returns its position in "screen"
|
||||
* coordinates. In a content process, the coordinates returned will
|
||||
* be relative to the left/top of the tab. In the chrome process,
|
||||
* the coordinates are relative to the user's screen.
|
||||
* coordinates.
|
||||
*/
|
||||
getElementBoundingScreenRect(aElement) {
|
||||
return this.getElementBoundingRect(aElement, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* For a given DOM element, returns its position as an offset from the topmost
|
||||
* window. In a content process, the coordinates returned will be relative to
|
||||
* the left/top of the topmost content area. If aInScreenCoords is true,
|
||||
* screen coordinates will be returned instead.
|
||||
*/
|
||||
getElementBoundingRect(aElement, aInScreenCoords) {
|
||||
let rect = aElement.getBoundingClientRect();
|
||||
let win = aElement.ownerGlobal;
|
||||
|
||||
let x = rect.left;
|
||||
let y = rect.top;
|
||||
|
||||
// We need to compensate for any iframes that might shift things
|
||||
// over. We also need to compensate for zooming.
|
||||
// We need to compensate for ancestor iframes in the same process
|
||||
// that might shift things over.
|
||||
let parentFrame = win.frameElement;
|
||||
while (parentFrame) {
|
||||
win = parentFrame.ownerGlobal;
|
||||
@ -51,36 +39,11 @@ var LayoutUtils = {
|
||||
parentFrame = win.frameElement;
|
||||
}
|
||||
|
||||
rect = {
|
||||
left: x,
|
||||
top: y,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
};
|
||||
rect = win.windowUtils.transformRectLayoutToVisual(
|
||||
rect.left,
|
||||
rect.top,
|
||||
return aElement.ownerGlobal.windowUtils.toScreenRect(
|
||||
x,
|
||||
y,
|
||||
rect.width,
|
||||
rect.height
|
||||
);
|
||||
|
||||
if (aInScreenCoords) {
|
||||
rect = {
|
||||
left: rect.left + win.mozInnerScreenX,
|
||||
top: rect.top + win.mozInnerScreenY,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
};
|
||||
}
|
||||
|
||||
let fullZoom = win.windowUtils.fullZoom;
|
||||
rect = {
|
||||
left: rect.left * fullZoom,
|
||||
top: rect.top * fullZoom,
|
||||
width: rect.width * fullZoom,
|
||||
height: rect.height * fullZoom,
|
||||
};
|
||||
|
||||
return rect;
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user