зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1773813 - Incorporate OS zoom factor in window sizing calculations. r=tnikkel
In bug 1773342 I made OS text scale factor behave like a full zoom factor which applies to all pages (including the browser chrome). That's generally straight forward but it makes some callsites that use unzoomed CSS coordinates misbehave (or behave correctly accidentally actually in some other cases). The main fix here is making nsIBaseWindow::UnscaledDevicePixelsPerCSSPixel() and nsIScreen::GetDefaultCSSScaleFactor() account for OS zoom as necessary. However, I also went through the relevant code and cleaned it up to use typed units and operations when possible. The setup means: * nsIWidget::GetDefaultScale() doesn't account for OS full zoom. * nsIBaseWindow and nsIScreen does. These are the places where this should matter and stuff can get confused, but this works surprisingly well for all callers (except one nsDeviceContext one which we use only for PuppetWidget and we can remove by falling back to 1.0 like all other widgets until the update comes). Differential Revision: https://phabricator.services.mozilla.com/D149033
This commit is contained in:
Родитель
e779b145d6
Коммит
ee23efc9b5
|
@ -4641,20 +4641,14 @@ nsDocShell::Destroy() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
|
||||
double nsDocShell::GetWidgetCSSToDeviceScale() {
|
||||
if (mParentWidget) {
|
||||
*aScale = mParentWidget->GetDefaultScale().scale;
|
||||
return NS_OK;
|
||||
return mParentWidget->GetDefaultScale().scale;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> ownerWindow(do_QueryInterface(mTreeOwner));
|
||||
if (ownerWindow) {
|
||||
return ownerWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||
if (nsCOMPtr<nsIBaseWindow> ownerWindow = do_QueryInterface(mTreeOwner)) {
|
||||
return ownerWindow->GetWidgetCSSToDeviceScale();
|
||||
}
|
||||
|
||||
*aScale = 1.0;
|
||||
return NS_OK;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -552,14 +552,8 @@ nsDocShellTreeOwner::Destroy() {
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
|
||||
if (mWebBrowser) {
|
||||
return mWebBrowser->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||
}
|
||||
|
||||
*aScale = 1.0;
|
||||
return NS_OK;
|
||||
double nsDocShellTreeOwner::GetWidgetCSSToDeviceScale() {
|
||||
return mWebBrowser ? mWebBrowser->GetWidgetCSSToDeviceScale() : 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -7518,53 +7518,37 @@ void nsGlobalWindowInner::SetReplaceableWindowCoord(
|
|||
if (innerWidthSpecified || innerHeightSpecified || outerWidthSpecified ||
|
||||
outerHeightSpecified) {
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = outer->GetTreeOwnerWindow();
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
nsCOMPtr<nsIScreenManager> screenMgr(
|
||||
do_GetService("@mozilla.org/gfx/screenmanager;1"));
|
||||
int32_t winLeft = 0;
|
||||
int32_t winTop = 0;
|
||||
int32_t winWidth = 0;
|
||||
int32_t winHeight = 0;
|
||||
double scale = 1.0;
|
||||
|
||||
if (treeOwnerAsWin && screenMgr) {
|
||||
// Acquire current window size.
|
||||
treeOwnerAsWin->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
treeOwnerAsWin->GetPositionAndSize(&winLeft, &winTop, &winWidth,
|
||||
&winHeight);
|
||||
winLeft = NSToIntRound(winHeight / scale);
|
||||
winTop = NSToIntRound(winWidth / scale);
|
||||
winWidth = NSToIntRound(winWidth / scale);
|
||||
winHeight = NSToIntRound(winHeight / scale);
|
||||
//
|
||||
// FIXME: This needs to account for full zoom like the outer window code
|
||||
// does! Ideally move there?
|
||||
auto cssScale = treeOwnerAsWin->UnscaledDevicePixelsPerCSSPixel();
|
||||
LayoutDeviceIntRect devWinRect = treeOwnerAsWin->GetPositionAndSize();
|
||||
CSSIntRect cssWinRect = RoundedToInt(devWinRect / cssScale);
|
||||
|
||||
// Acquire content window size.
|
||||
CSSSize contentSize;
|
||||
outer->GetInnerSize(contentSize);
|
||||
|
||||
screenMgr->ScreenForRect(winLeft, winTop, winWidth, winHeight,
|
||||
getter_AddRefs(screen));
|
||||
|
||||
nsCOMPtr<nsIScreen> screen = screenMgr->ScreenForRect(RoundedToInt(
|
||||
devWinRect / treeOwnerAsWin->DevicePixelsPerDesktopPixel()));
|
||||
if (screen) {
|
||||
int32_t roundedValue = std::round(value);
|
||||
int32_t* targetContentWidth = nullptr;
|
||||
int32_t* targetContentHeight = nullptr;
|
||||
int32_t screenWidth = 0;
|
||||
int32_t screenHeight = 0;
|
||||
int32_t chromeWidth = 0;
|
||||
int32_t chromeHeight = 0;
|
||||
int32_t inputWidth = 0;
|
||||
int32_t inputHeight = 0;
|
||||
int32_t unused = 0;
|
||||
|
||||
// Get screen dimensions (in device pixels)
|
||||
screen->GetAvailRect(&unused, &unused, &screenWidth, &screenHeight);
|
||||
// Convert them to CSS pixels
|
||||
screenWidth = NSToIntRound(screenWidth / scale);
|
||||
screenHeight = NSToIntRound(screenHeight / scale);
|
||||
CSSIntSize availScreenSize =
|
||||
RoundedToInt(screen->GetAvailRect().Size() / cssScale);
|
||||
|
||||
// Calculate the chrome UI size.
|
||||
chromeWidth = winWidth - contentSize.width;
|
||||
chromeHeight = winHeight - contentSize.height;
|
||||
CSSIntSize chromeSize = cssWinRect.Size() - RoundedToInt(contentSize);
|
||||
|
||||
if (innerWidthSpecified || outerWidthSpecified) {
|
||||
inputWidth = value;
|
||||
|
@ -7577,9 +7561,10 @@ void nsGlobalWindowInner::SetReplaceableWindowCoord(
|
|||
}
|
||||
|
||||
nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting(
|
||||
chromeWidth, chromeHeight, screenWidth, screenHeight, inputWidth,
|
||||
inputHeight, outerWidthSpecified, outerHeightSpecified,
|
||||
targetContentWidth, targetContentHeight);
|
||||
chromeSize.width, chromeSize.height, availScreenSize.width,
|
||||
availScreenSize.height, inputWidth, inputHeight,
|
||||
outerWidthSpecified, outerHeightSpecified, targetContentWidth,
|
||||
targetContentHeight);
|
||||
value = T(roundedValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3429,56 +3429,20 @@ void nsGlobalWindowOuter::SetNameOuter(const nsAString& aName,
|
|||
}
|
||||
}
|
||||
|
||||
// Helper functions used by many methods below.
|
||||
int32_t nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||
int32_t aDevicePixels, nsIBaseWindow* aWindow) {
|
||||
// NOTE: The idea of this function is that it should return the same as
|
||||
// nsPresContext::CSSToDeviceScale() if it was in aWindow synchronously. For
|
||||
// that, we use the UnscaledDevicePixelsPerCSSPixel() (which contains the device
|
||||
// scale and the OS zoom scale) and then account for the browsing context full
|
||||
// zoom. See the declaration of this function for context about why this is
|
||||
// needed.
|
||||
CSSToLayoutDeviceScale nsGlobalWindowOuter::CSSToDevScaleForBaseWindow(
|
||||
nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
auto scale = aWindow->UnscaledDevicePixelsPerCSSPixel();
|
||||
if (mBrowsingContext) {
|
||||
scale.scale *= mBrowsingContext->FullZoom();
|
||||
}
|
||||
return std::floor(aDevicePixels / scale / zoom + 0.5);
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||
nsIntSize aDeviceSize, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return nsIntSize::Round(
|
||||
static_cast<float>(aDeviceSize.width / scale / zoom),
|
||||
static_cast<float>(aDeviceSize.height / scale / zoom));
|
||||
}
|
||||
|
||||
int32_t nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||
int32_t aCSSPixels, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return std::floor(aCSSPixels * scale * zoom + 0.5);
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||
nsIntSize aCSSSize, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return nsIntSize::Round(static_cast<float>(aCSSSize.width * scale * zoom),
|
||||
static_cast<float>(aCSSSize.height * scale * zoom));
|
||||
return scale;
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowOuter::GetInnerSize(CSSSize& aSize) {
|
||||
|
@ -3556,14 +3520,12 @@ void nsGlobalWindowOuter::SetInnerWidthOuter(double aInnerWidth,
|
|||
return;
|
||||
}
|
||||
|
||||
// Nothing has been overriden, so change the docshell itself.
|
||||
int32_t height = 0;
|
||||
int32_t unused = 0;
|
||||
|
||||
// Nothing has been overridden, so change the docshell itself.
|
||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||
docShellAsWin->GetSize(&unused, &height);
|
||||
aError = SetDocShellWidthAndHeight(
|
||||
CSSToDevIntPixelsForBaseWindow(value, docShellAsWin), height);
|
||||
LayoutDeviceIntSize size = docShellAsWin->GetSize();
|
||||
size.width =
|
||||
(CSSCoord(value) * CSSToDevScaleForBaseWindow(docShellAsWin)).Rounded();
|
||||
aError = SetDocShellSize(size);
|
||||
}
|
||||
|
||||
double nsGlobalWindowOuter::GetInnerHeightOuter(ErrorResult& aError) {
|
||||
|
@ -3603,21 +3565,19 @@ void nsGlobalWindowOuter::SetInnerHeightOuter(double aInnerHeight,
|
|||
}
|
||||
|
||||
// Nothing has been overriden, so change the docshell itself.
|
||||
int32_t height = 0;
|
||||
int32_t width = 0;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||
docShellAsWin->GetSize(&width, &height);
|
||||
aError = SetDocShellWidthAndHeight(
|
||||
width, CSSToDevIntPixelsForBaseWindow(value, docShellAsWin));
|
||||
LayoutDeviceIntSize size = docShellAsWin->GetSize();
|
||||
size.height =
|
||||
(CSSCoord(value) * CSSToDevScaleForBaseWindow(docShellAsWin)).Rounded();
|
||||
aError = SetDocShellSize(size);
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||
ErrorResult& aError) {
|
||||
CSSIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||
ErrorResult& aError) {
|
||||
if (nsContentUtils::ResistFingerprinting(aCallerType)) {
|
||||
CSSSize size;
|
||||
aError = GetInnerSize(size);
|
||||
return nsIntSize::Round(size.width, size.height);
|
||||
return RoundedToInt(size);
|
||||
}
|
||||
|
||||
// Windows showing documents in RDM panes and any subframes within them
|
||||
|
@ -3625,24 +3585,18 @@ nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
|||
if (mDoc) {
|
||||
Maybe<CSSIntSize> deviceSize = GetRDMDeviceSize(*mDoc);
|
||||
if (deviceSize.isSome()) {
|
||||
const CSSIntSize& size = deviceSize.value();
|
||||
return nsIntSize(size.width, size.height);
|
||||
return *deviceSize;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
||||
if (!treeOwnerAsWin) {
|
||||
aError.Throw(NS_ERROR_FAILURE);
|
||||
return nsIntSize(0, 0);
|
||||
return {};
|
||||
}
|
||||
|
||||
nsIntSize sizeDevPixels;
|
||||
aError = treeOwnerAsWin->GetSize(&sizeDevPixels.width, &sizeDevPixels.height);
|
||||
if (aError.Failed()) {
|
||||
return nsIntSize();
|
||||
}
|
||||
|
||||
return DevToCSSIntPixelsForBaseWindow(sizeDevPixels, treeOwnerAsWin);
|
||||
return RoundedToInt(treeOwnerAsWin->GetSize() /
|
||||
CSSToDevScaleForBaseWindow(treeOwnerAsWin));
|
||||
}
|
||||
|
||||
int32_t nsGlobalWindowOuter::GetOuterWidthOuter(CallerType aCallerType,
|
||||
|
@ -3668,20 +3622,11 @@ void nsGlobalWindowOuter::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
|
|||
aIsWidth ? nullptr : &aLengthCSSPixels,
|
||||
aCallerType);
|
||||
|
||||
int32_t width, height;
|
||||
aError = treeOwnerAsWin->GetSize(&width, &height);
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t lengthDevPixels =
|
||||
CSSToDevIntPixelsForBaseWindow(aLengthCSSPixels, treeOwnerAsWin);
|
||||
if (aIsWidth) {
|
||||
width = lengthDevPixels;
|
||||
} else {
|
||||
height = lengthDevPixels;
|
||||
}
|
||||
aError = treeOwnerAsWin->SetSize(width, height, true);
|
||||
LayoutDeviceIntSize size = treeOwnerAsWin->GetSize();
|
||||
auto scale = CSSToDevScaleForBaseWindow(treeOwnerAsWin);
|
||||
(aIsWidth ? size.width : size.height) =
|
||||
(CSSCoord(aLengthCSSPixels) * scale).Rounded();
|
||||
aError = treeOwnerAsWin->SetSize(size.width, size.height, true);
|
||||
|
||||
CheckForDPIChange();
|
||||
}
|
||||
|
@ -3821,16 +3766,14 @@ void nsGlobalWindowOuter::SetScreenXOuter(int32_t aScreenX,
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t x, y;
|
||||
aError = treeOwnerAsWin->GetPosition(&x, &y);
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
LayoutDeviceIntPoint pos = treeOwnerAsWin->GetPosition();
|
||||
|
||||
CheckSecurityLeftAndTop(&aScreenX, nullptr, aCallerType);
|
||||
x = CSSToDevIntPixelsForBaseWindow(aScreenX, treeOwnerAsWin);
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||
pos.x = (CSSCoord(aScreenX) * CSSToDevScaleForBaseWindow(treeOwnerAsWin))
|
||||
.Rounded();
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(pos.x, pos.y);
|
||||
|
||||
CheckForDPIChange();
|
||||
}
|
||||
|
@ -3849,16 +3792,11 @@ void nsGlobalWindowOuter::SetScreenYOuter(int32_t aScreenY,
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t x, y;
|
||||
aError = treeOwnerAsWin->GetPosition(&x, &y);
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutDeviceIntPoint pos = treeOwnerAsWin->GetPosition();
|
||||
CheckSecurityLeftAndTop(nullptr, &aScreenY, aCallerType);
|
||||
y = CSSToDevIntPixelsForBaseWindow(aScreenY, treeOwnerAsWin);
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||
pos.y = (CSSCoord(aScreenY) * CSSToDevScaleForBaseWindow(treeOwnerAsWin))
|
||||
.Rounded();
|
||||
aError = treeOwnerAsWin->SetPosition(pos.x, pos.y);
|
||||
|
||||
CheckForDPIChange();
|
||||
}
|
||||
|
@ -3890,8 +3828,8 @@ void nsGlobalWindowOuter::CheckSecurityWidthAndHeight(int32_t* aWidth,
|
|||
}
|
||||
|
||||
// NOTE: Arguments to this function should have values in device pixels
|
||||
nsresult nsGlobalWindowOuter::SetDocShellWidthAndHeight(int32_t aInnerWidth,
|
||||
int32_t aInnerHeight) {
|
||||
nsresult nsGlobalWindowOuter::SetDocShellSize(
|
||||
const LayoutDeviceIntSize& aSize) {
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||
|
@ -3899,7 +3837,7 @@ nsresult nsGlobalWindowOuter::SetDocShellWidthAndHeight(int32_t aInnerWidth,
|
|||
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShell, aInnerWidth, aInnerHeight),
|
||||
NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShell, aSize.width, aSize.height),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -3944,18 +3882,9 @@ void nsGlobalWindowOuter::CheckSecurityLeftAndTop(int32_t* aLeft, int32_t* aTop,
|
|||
RefPtr<nsScreen> screen = GetScreen();
|
||||
|
||||
if (treeOwnerAsWin && screen) {
|
||||
int32_t winLeft, winTop, winWidth, winHeight;
|
||||
|
||||
// Get the window size
|
||||
treeOwnerAsWin->GetPositionAndSize(&winLeft, &winTop, &winWidth,
|
||||
&winHeight);
|
||||
|
||||
// convert those values to CSS pixels
|
||||
// XXX four separate retrievals of the prescontext
|
||||
winLeft = DevToCSSIntPixelsForBaseWindow(winLeft, treeOwnerAsWin);
|
||||
winTop = DevToCSSIntPixelsForBaseWindow(winTop, treeOwnerAsWin);
|
||||
winWidth = DevToCSSIntPixelsForBaseWindow(winWidth, treeOwnerAsWin);
|
||||
winHeight = DevToCSSIntPixelsForBaseWindow(winHeight, treeOwnerAsWin);
|
||||
CSSToLayoutDeviceScale scale = CSSToDevScaleForBaseWindow(treeOwnerAsWin);
|
||||
CSSIntRect winRect =
|
||||
CSSIntRect::Round(treeOwnerAsWin->GetPositionAndSize() / scale);
|
||||
|
||||
// Get the screen dimensions
|
||||
// XXX This should use nsIScreenManager once it's fully fleshed out.
|
||||
|
@ -3976,13 +3905,13 @@ void nsGlobalWindowOuter::CheckSecurityLeftAndTop(int32_t* aLeft, int32_t* aTop,
|
|||
#endif
|
||||
|
||||
if (aLeft) {
|
||||
if (screenLeft + screenWidth < *aLeft + winWidth)
|
||||
*aLeft = screenLeft + screenWidth - winWidth;
|
||||
if (screenLeft + screenWidth < *aLeft + winRect.width)
|
||||
*aLeft = screenLeft + screenWidth - winRect.width;
|
||||
if (screenLeft > *aLeft) *aLeft = screenLeft;
|
||||
}
|
||||
if (aTop) {
|
||||
if (screenTop + screenHeight < *aTop + winHeight)
|
||||
*aTop = screenTop + screenHeight - winHeight;
|
||||
if (screenTop + screenHeight < *aTop + winRect.height)
|
||||
*aTop = screenTop + screenHeight - winRect.height;
|
||||
if (screenTop > *aTop) *aTop = screenTop;
|
||||
}
|
||||
} else {
|
||||
|
@ -5414,18 +5343,16 @@ void nsGlobalWindowOuter::MoveByOuter(int32_t aXDif, int32_t aYDif,
|
|||
return;
|
||||
}
|
||||
|
||||
// mild abuse of a "size" object so we don't need more helper functions
|
||||
nsIntSize cssPos(
|
||||
DevToCSSIntPixelsForBaseWindow(nsIntSize(x, y), treeOwnerAsWin));
|
||||
auto cssScale = CSSToDevScaleForBaseWindow(treeOwnerAsWin);
|
||||
CSSIntPoint cssPos = RoundedToInt(treeOwnerAsWin->GetPosition() / cssScale);
|
||||
|
||||
cssPos.width += aXDif;
|
||||
cssPos.height += aYDif;
|
||||
cssPos.x += aXDif;
|
||||
cssPos.y += aYDif;
|
||||
|
||||
CheckSecurityLeftAndTop(&cssPos.width, &cssPos.height, aCallerType);
|
||||
CheckSecurityLeftAndTop(&cssPos.x, &cssPos.y, aCallerType);
|
||||
|
||||
nsIntSize newDevPos(CSSToDevIntPixelsForBaseWindow(cssPos, treeOwnerAsWin));
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height);
|
||||
LayoutDeviceIntPoint newDevPos = RoundedToInt(cssPos * cssScale);
|
||||
aError = treeOwnerAsWin->SetPosition(newDevPos.x, newDevPos.y);
|
||||
|
||||
CheckForDPIChange();
|
||||
}
|
||||
|
@ -5455,12 +5382,12 @@ void nsGlobalWindowOuter::ResizeToOuter(int32_t aWidth, int32_t aHeight,
|
|||
return;
|
||||
}
|
||||
|
||||
nsIntSize cssSize(aWidth, aHeight);
|
||||
CSSIntSize cssSize(aWidth, aHeight);
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||
|
||||
nsIntSize devSz(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||
|
||||
aError = treeOwnerAsWin->SetSize(devSz.width, devSz.height, true);
|
||||
LayoutDeviceIntSize devSize =
|
||||
RoundedToInt(cssSize * CSSToDevScaleForBaseWindow(treeOwnerAsWin));
|
||||
aError = treeOwnerAsWin->SetSize(devSize.width, devSize.height, true);
|
||||
|
||||
CheckForDPIChange();
|
||||
}
|
||||
|
@ -5483,25 +5410,21 @@ void nsGlobalWindowOuter::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t width, height;
|
||||
aError = treeOwnerAsWin->GetSize(&width, &height);
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
LayoutDeviceIntSize size = treeOwnerAsWin->GetSize();
|
||||
|
||||
// To do this correctly we have to convert what we got from GetSize
|
||||
// into CSS pixels, add the arguments, do the security check, and
|
||||
// then convert back to device pixels for the call to SetSize.
|
||||
|
||||
nsIntSize cssSize(
|
||||
DevToCSSIntPixelsForBaseWindow(nsIntSize(width, height), treeOwnerAsWin));
|
||||
auto scale = CSSToDevScaleForBaseWindow(treeOwnerAsWin);
|
||||
CSSIntSize cssSize = RoundedToInt(size / scale);
|
||||
|
||||
cssSize.width += aWidthDif;
|
||||
cssSize.height += aHeightDif;
|
||||
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||
|
||||
nsIntSize newDevSize(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||
LayoutDeviceIntSize newDevSize = RoundedToInt(cssSize * scale);
|
||||
|
||||
aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true);
|
||||
|
||||
|
|
|
@ -826,7 +826,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
void SetCSSViewportWidthAndHeight(nscoord width, nscoord height);
|
||||
// Arguments to this function should have values in device pixels
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
nsresult SetDocShellWidthAndHeight(int32_t width, int32_t height);
|
||||
nsresult SetDocShellSize(const mozilla::LayoutDeviceIntSize& aInnerSize);
|
||||
|
||||
static bool CanSetProperty(const char* aPrefName);
|
||||
|
||||
|
@ -850,8 +850,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
|
||||
// Outer windows only.
|
||||
nsresult GetInnerSize(mozilla::CSSSize& aSize);
|
||||
nsIntSize GetOuterSize(mozilla::dom::CallerType aCallerType,
|
||||
mozilla::ErrorResult& aError);
|
||||
mozilla::CSSIntSize GetOuterSize(mozilla::dom::CallerType aCallerType,
|
||||
mozilla::ErrorResult& aError);
|
||||
void SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
|
||||
mozilla::dom::CallerType aCallerType,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
@ -871,25 +871,14 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
|
||||
bool IsInModalState();
|
||||
|
||||
// Convenience functions for the many methods that need to scale
|
||||
// from device to CSS pixels. This computes it with cached scale in
|
||||
// PresContext which may be not recent information of the widget.
|
||||
// Note: if PresContext is not available, they will assume a 1:1 ratio.
|
||||
int32_t DevToCSSIntPixels(int32_t px);
|
||||
nsIntSize DevToCSSIntPixels(nsIntSize px);
|
||||
|
||||
// Convenience functions for the methods which call methods of nsIBaseWindow
|
||||
// because it takes/returns device pixels. Unfortunately, mPresContext may
|
||||
// have older scale value for the corresponding widget. Therefore, these
|
||||
// helper methods convert between CSS pixels and device pixels with aWindow.
|
||||
int32_t DevToCSSIntPixelsForBaseWindow(int32_t aDevicePixels,
|
||||
nsIBaseWindow* aWindow);
|
||||
nsIntSize DevToCSSIntPixelsForBaseWindow(nsIntSize aDeviceSize,
|
||||
nsIBaseWindow* aWindow);
|
||||
int32_t CSSToDevIntPixelsForBaseWindow(int32_t aCSSPixels,
|
||||
nsIBaseWindow* aWindow);
|
||||
nsIntSize CSSToDevIntPixelsForBaseWindow(nsIntSize aCSSSize,
|
||||
nsIBaseWindow* aWindow);
|
||||
//
|
||||
// FIXME(emilio): Seems like updating the pres context dpi sync shouldn't be
|
||||
// all that much work and should avoid some hackiness?
|
||||
mozilla::CSSToLayoutDeviceScale CSSToDevScaleForBaseWindow(nsIBaseWindow*);
|
||||
|
||||
void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0,
|
||||
|
|
|
@ -1004,12 +1004,14 @@ mozilla::ipc::IPCResult BrowserParent::RecvSetDimensions(
|
|||
// We only care about the parameters that actually changed, see more details
|
||||
// in `BrowserChild::SetDimensions()`.
|
||||
// Note that `BrowserChild::SetDimensions()` may be called before receiving
|
||||
// our `SendUIResolutionChanged()` call. Therefore, if given each cordinate
|
||||
// our `SendUIResolutionChanged()` call. Therefore, if given each coordinate
|
||||
// shouldn't be ignored, we need to recompute it if DPI has been changed.
|
||||
// And also note that don't use `mDefaultScale.scale` here since it may be
|
||||
// different from the result of `GetUnscaledDevicePixelsPerCSSPixel()`.
|
||||
double currentScale;
|
||||
treeOwnerAsWin->GetUnscaledDevicePixelsPerCSSPixel(¤tScale);
|
||||
// different from the result of `GetWidgetCSSToDeviceScale()`.
|
||||
// NOTE(emilio): We use GetWidgetCSSToDeviceScale() because the old scale is a
|
||||
// widget scale, and we only use the current scale to scale up/down the
|
||||
// relevant values.
|
||||
double currentScale = treeOwnerAsWin->GetWidgetCSSToDeviceScale();
|
||||
|
||||
int32_t x = aX;
|
||||
int32_t y = aY;
|
||||
|
|
|
@ -74,7 +74,7 @@ void nsDeviceContext::SetDPI(double* aScale) {
|
|||
mAppUnitsPerDevPixelAtUnitFullZoom =
|
||||
NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
|
||||
} else {
|
||||
RefPtr<widget::Screen> primaryScreen =
|
||||
RefPtr<const widget::Screen> primaryScreen =
|
||||
ScreenManager::GetSingleton().GetPrimaryScreen();
|
||||
MOZ_ASSERT(primaryScreen);
|
||||
|
||||
|
@ -109,12 +109,8 @@ void nsDeviceContext::SetDPI(double* aScale) {
|
|||
// the caller to pass to child contexts if needed
|
||||
CSSToLayoutDeviceScale scale =
|
||||
mWidget ? mWidget->GetDefaultScale() : CSSToLayoutDeviceScale(1.0);
|
||||
MOZ_ASSERT(scale.scale > 0.0);
|
||||
devPixelsPerCSSPixel = scale.scale;
|
||||
// In case that the widget returns -1, use the primary screen's
|
||||
// value as default.
|
||||
if (devPixelsPerCSSPixel < 0) {
|
||||
primaryScreen->GetDefaultCSSScaleFactor(&devPixelsPerCSSPixel);
|
||||
}
|
||||
if (aScale) {
|
||||
*aScale = devPixelsPerCSSPixel;
|
||||
}
|
||||
|
|
|
@ -860,10 +860,8 @@ nsWebBrowser::Destroy() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
|
||||
*aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
|
||||
return NS_OK;
|
||||
double nsWebBrowser::GetWidgetCSSToDeviceScale() {
|
||||
return mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -539,7 +539,7 @@ nsWindowWatcher::OpenWindowWithRemoteTab(nsIRemoteTab* aRemoteTab,
|
|||
// get various interfaces for aDocShellItem, used throughout this method
|
||||
CSSToDesktopScale cssToDesktopScale(1.0f);
|
||||
if (nsCOMPtr<nsIBaseWindow> win = do_QueryInterface(parentTreeOwner)) {
|
||||
cssToDesktopScale = win->GetCSSToDesktopScale();
|
||||
cssToDesktopScale = win->GetUnscaledCSSToDesktopScale();
|
||||
}
|
||||
SizeSpec sizeSpec = CalcSizeSpec(features, false, cssToDesktopScale);
|
||||
sizeSpec.ScaleBy(aOpenerFullZoom);
|
||||
|
@ -723,7 +723,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
|||
|
||||
CSSToDesktopScale cssToDesktopScale(1.0);
|
||||
if (nsCOMPtr<nsIBaseWindow> win = do_QueryInterface(parentDocShell)) {
|
||||
cssToDesktopScale = win->GetCSSToDesktopScale();
|
||||
cssToDesktopScale = win->GetUnscaledCSSToDesktopScale();
|
||||
}
|
||||
SizeSpec sizeSpec =
|
||||
CalcSizeSpec(features, hasChromeParent, cssToDesktopScale);
|
||||
|
@ -2209,9 +2209,7 @@ static void SizeOpenedWindow(nsIDocShellTreeOwner* aTreeOwner,
|
|||
DesktopToLayoutDeviceScale devToDesktopScale =
|
||||
treeOwnerAsWin->DevicePixelsPerDesktopPixel();
|
||||
|
||||
LayoutDeviceIntRect devPxRect;
|
||||
treeOwnerAsWin->GetPositionAndSize(&devPxRect.x, &devPxRect.y,
|
||||
&devPxRect.width, &devPxRect.height);
|
||||
LayoutDeviceIntRect devPxRect = treeOwnerAsWin->GetPositionAndSize();
|
||||
width = (LayoutDeviceCoord(devPxRect.width) / cssToDevScale).Rounded();
|
||||
height = (LayoutDeviceCoord(devPxRect.height) / cssToDevScale).Rounded();
|
||||
left = (LayoutDeviceCoord(devPxRect.x) / devToDesktopScale).Rounded();
|
||||
|
@ -2287,7 +2285,8 @@ static void SizeOpenedWindow(nsIDocShellTreeOwner* aTreeOwner,
|
|||
CSSIntCoord winWidth = width + extraWidth;
|
||||
CSSIntCoord winHeight = height + extraHeight;
|
||||
|
||||
const auto screenCssToDesktopScale = screen->GetCSSToDesktopScale();
|
||||
auto screenCssToDesktopScale = screen->GetCSSToDesktopScale();
|
||||
|
||||
const DesktopIntRect screenDesktopRect = screen->GetAvailRectDisplayPix();
|
||||
// Get screen dimensions (in CSS pixels)
|
||||
const CSSSize screenCssSize =
|
||||
|
|
|
@ -81,9 +81,6 @@ NS_IMPL_ISUPPORTS_INHERITED(PuppetWidget, nsBaseWidget,
|
|||
PuppetWidget::PuppetWidget(BrowserChild* aBrowserChild)
|
||||
: mBrowserChild(aBrowserChild),
|
||||
mMemoryPressureObserver(nullptr),
|
||||
mDPI(-1),
|
||||
mRounding(1),
|
||||
mDefaultScale(-1),
|
||||
mEnabled(false),
|
||||
mVisible(false),
|
||||
mSizeMode(nsSizeMode_Normal),
|
||||
|
@ -1009,12 +1006,6 @@ bool PuppetWidget::NeedsPaint() {
|
|||
return mVisible;
|
||||
}
|
||||
|
||||
float PuppetWidget::GetDPI() { return mDPI; }
|
||||
|
||||
double PuppetWidget::GetDefaultScaleInternal() { return mDefaultScale; }
|
||||
|
||||
int32_t PuppetWidget::RoundsWidgetCoordinatesTo() { return mRounding; }
|
||||
|
||||
LayoutDeviceIntPoint PuppetWidget::GetChromeOffset() {
|
||||
if (!GetOwningBrowserChild()) {
|
||||
NS_WARNING("PuppetWidget without Tab does not have chrome information.");
|
||||
|
|
|
@ -138,7 +138,7 @@ class PuppetWidget : public nsBaseWidget,
|
|||
return GetWindowPosition();
|
||||
}
|
||||
|
||||
int32_t RoundsWidgetCoordinatesTo() override;
|
||||
int32_t RoundsWidgetCoordinatesTo() override { return mRounding; }
|
||||
|
||||
void InitEvent(WidgetGUIEvent& aEvent,
|
||||
LayoutDeviceIntPoint* aPoint = nullptr);
|
||||
|
@ -201,12 +201,8 @@ class PuppetWidget : public nsBaseWidget,
|
|||
|
||||
virtual void SetCursor(const Cursor&) override;
|
||||
|
||||
// Gets the DPI of the screen corresponding to this widget.
|
||||
// Contacts the parent process which gets the DPI from the
|
||||
// proper widget there. TODO: Handle DPI changes that happen
|
||||
// later on.
|
||||
virtual float GetDPI() override;
|
||||
virtual double GetDefaultScaleInternal() override;
|
||||
float GetDPI() override { return mDPI; }
|
||||
double GetDefaultScaleInternal() override { return mDefaultScale; }
|
||||
|
||||
virtual bool NeedsPaint() override;
|
||||
|
||||
|
@ -385,10 +381,10 @@ class PuppetWidget : public nsBaseWidget,
|
|||
NativeIMEContext mNativeIMEContext;
|
||||
ContentCacheInChild mContentCache;
|
||||
|
||||
// The DPI of the screen corresponding to this widget
|
||||
float mDPI;
|
||||
int32_t mRounding;
|
||||
double mDefaultScale;
|
||||
// The DPI of the parent widget containing this widget.
|
||||
float mDPI = 96;
|
||||
int32_t mRounding = 1;
|
||||
double mDefaultScale = 1.0f;
|
||||
|
||||
ScreenIntMargin mSafeAreaInsets;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
@ -136,6 +137,7 @@ Screen::GetDefaultCSSScaleFactor(double* aOutScale) {
|
|||
} else {
|
||||
*aOutScale = mDefaultCssScale.scale;
|
||||
}
|
||||
*aOutScale *= LookAndFeel::SystemZoomSettings().mFullZoom;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,9 +50,6 @@ class Screen final : public nsIScreen {
|
|||
const DesktopToLayoutDeviceScale& GetContentsScaleFactor() const {
|
||||
return mContentsScale;
|
||||
}
|
||||
const CSSToLayoutDeviceScale& GetDefaultCSSScaleFactor() const {
|
||||
return mDefaultCssScale;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~Screen() = default;
|
||||
|
|
|
@ -225,6 +225,7 @@ UNIFIED_SOURCES += [
|
|||
"nsDragServiceProxy.cpp",
|
||||
"nsFilePickerProxy.cpp",
|
||||
"nsHTMLFormatConverter.cpp",
|
||||
"nsIBaseWindow.cpp",
|
||||
"nsIDeviceContextSpec.cpp",
|
||||
"nsIWidgetListener.cpp",
|
||||
"nsPrimitiveHelpers.cpp",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsIBaseWindow.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
CSSToLayoutDeviceScale nsIBaseWindow::UnscaledDevicePixelsPerCSSPixel() {
|
||||
return CSSToLayoutDeviceScale(GetWidgetCSSToDeviceScale() *
|
||||
LookAndFeel::SystemZoomSettings().mFullZoom);
|
||||
}
|
|
@ -93,6 +93,14 @@ interface nsIBaseWindow : nsISupports
|
|||
*/
|
||||
void getPosition(out long x, out long y);
|
||||
|
||||
%{C++
|
||||
mozilla::LayoutDeviceIntPoint GetPosition() {
|
||||
int32_t x = 0, y = 0;
|
||||
GetPosition(&x, &y);
|
||||
return mozilla::LayoutDeviceIntPoint(x, y);
|
||||
}
|
||||
%}
|
||||
|
||||
/*
|
||||
Sets the width and height of the control.
|
||||
*/
|
||||
|
@ -103,6 +111,14 @@ interface nsIBaseWindow : nsISupports
|
|||
*/
|
||||
void getSize(out long cx, out long cy);
|
||||
|
||||
%{C++
|
||||
mozilla::LayoutDeviceIntSize GetSize() {
|
||||
int32_t w = 0, h = 0;
|
||||
GetSize(&w, &h);
|
||||
return mozilla::LayoutDeviceIntSize(w, h);
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* The 'flags' argument to setPositionAndSize is a set of these bits.
|
||||
*/
|
||||
|
@ -122,6 +138,14 @@ interface nsIBaseWindow : nsISupports
|
|||
*/
|
||||
void getPositionAndSize(out long x, out long y, out long cx, out long cy);
|
||||
|
||||
%{C++
|
||||
mozilla::LayoutDeviceIntRect GetPositionAndSize() {
|
||||
int32_t x = 0, y = 0, w = 0, h = 0;
|
||||
GetPositionAndSize(&x, &y, &w, &h);
|
||||
return mozilla::LayoutDeviceIntRect(x, y, w, h);
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Tell the window to repaint itself
|
||||
* @param aForce - if true, repaint immediately
|
||||
|
@ -172,11 +196,11 @@ interface nsIBaseWindow : nsISupports
|
|||
*/
|
||||
attribute boolean visibility;
|
||||
|
||||
/*
|
||||
a disabled window should accept no user interaction; it's a dead window,
|
||||
like the parent of a modal window.
|
||||
*/
|
||||
attribute boolean enabled;
|
||||
/*
|
||||
a disabled window should accept no user interaction; it's a dead window,
|
||||
like the parent of a modal window.
|
||||
*/
|
||||
attribute boolean enabled;
|
||||
|
||||
/*
|
||||
Allows you to find out what the widget is of a given object. Depending
|
||||
|
@ -186,20 +210,23 @@ interface nsIBaseWindow : nsISupports
|
|||
[noscript] readonly attribute nsIWidget mainWidget;
|
||||
|
||||
/*
|
||||
The number of device pixels per CSS pixel used on this window's current
|
||||
screen at the default zoom level.
|
||||
The number of device pixels per CSS pixel used by this window's widget at the
|
||||
default full zoom level.
|
||||
This is the value returned by GetDefaultScale() of the underlying widget.
|
||||
Note that this may change if the window is moved between screens with
|
||||
differing resolutions.
|
||||
NOTE: This is mostly an implementation detail of
|
||||
UnscaledDevicePixelsPerCSSPixel, which is what you probably want to use.
|
||||
*/
|
||||
readonly attribute double unscaledDevicePixelsPerCSSPixel;
|
||||
[noscript, notxpcom, nostdcall] readonly attribute double widgetCSSToDeviceScale;
|
||||
|
||||
%{C++
|
||||
mozilla::CSSToLayoutDeviceScale UnscaledDevicePixelsPerCSSPixel() {
|
||||
double s = 1.0;
|
||||
GetUnscaledDevicePixelsPerCSSPixel(&s);
|
||||
return mozilla::CSSToLayoutDeviceScale(s);
|
||||
}
|
||||
// The number of device pixels per CSS pixel used on this window's current
|
||||
// screen at the default full zoom level.
|
||||
//
|
||||
// This is the widget scale _plus_ the OS zoom scale if appropriate.
|
||||
// Implemented in AppWindow.cpp
|
||||
mozilla::CSSToLayoutDeviceScale UnscaledDevicePixelsPerCSSPixel();
|
||||
%}
|
||||
|
||||
/*
|
||||
|
@ -223,7 +250,7 @@ interface nsIBaseWindow : nsISupports
|
|||
return mozilla::DesktopToLayoutDeviceScale(s);
|
||||
}
|
||||
|
||||
mozilla::CSSToDesktopScale GetCSSToDesktopScale() {
|
||||
mozilla::CSSToDesktopScale GetUnscaledCSSToDesktopScale() {
|
||||
return UnscaledDevicePixelsPerCSSPixel() / DevicePixelsPerDesktopPixel();
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -244,17 +244,10 @@ LRESULT StatusBarEntry::OnMessage(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
|
|||
return DefWindowProc(hWnd, msg, wp, lp);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = popupFrame->PresContext()->GetDocShell();
|
||||
nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(docShell);
|
||||
MOZ_DIAGNOSTIC_ASSERT(baseWin);
|
||||
if (!baseWin) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
double scale = 1.0;
|
||||
baseWin->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
int32_t x = NSToIntRound(GET_X_LPARAM(wp) / scale);
|
||||
int32_t y = NSToIntRound(GET_Y_LPARAM(wp) / scale);
|
||||
nsPresContext* pc = popupFrame->PresContext();
|
||||
const CSSIntPoint point = gfx::RoundedToInt(
|
||||
LayoutDeviceIntPoint(GET_X_LPARAM(wp), GET_Y_LPARAM(wp)) /
|
||||
pc->CSSToDevPixelScale());
|
||||
|
||||
// The menu that is being opened is a Gecko <xul:menu>, and the popup code
|
||||
// that manages it expects that the window that the <xul:menu> belongs to
|
||||
|
@ -265,7 +258,8 @@ LRESULT StatusBarEntry::OnMessage(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
|
|||
// focuses any window in the parent process).
|
||||
::SetForegroundWindow(win);
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
pm->ShowPopupAtScreen(popupFrame->GetContent(), x, y, false, nullptr);
|
||||
pm->ShowPopupAtScreen(popupFrame->GetContent(), point.x, point.y, false,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wp, lp);
|
||||
|
|
|
@ -180,31 +180,22 @@ nsresult AppWindow::Initialize(nsIAppWindow* aParent, nsIAppWindow* aOpener,
|
|||
|
||||
mIsHiddenWindow = aIsHiddenWindow;
|
||||
|
||||
int32_t initialX = 0, initialY = 0;
|
||||
DesktopIntPoint initialPos;
|
||||
nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aOpener));
|
||||
if (base) {
|
||||
int32_t x, y, width, height;
|
||||
rv = base->GetPositionAndSize(&x, &y, &width, &height);
|
||||
if (NS_FAILED(rv)) {
|
||||
mOpenerScreenRect.SetEmpty();
|
||||
} else {
|
||||
double scale;
|
||||
if (NS_SUCCEEDED(base->GetUnscaledDevicePixelsPerCSSPixel(&scale))) {
|
||||
mOpenerScreenRect.SetRect(
|
||||
NSToIntRound(x / scale), NSToIntRound(y / scale),
|
||||
NSToIntRound(width / scale), NSToIntRound(height / scale));
|
||||
} else {
|
||||
mOpenerScreenRect.SetRect(x, y, width, height);
|
||||
}
|
||||
initialX = mOpenerScreenRect.X();
|
||||
initialY = mOpenerScreenRect.Y();
|
||||
ConstrainToOpenerScreen(&initialX, &initialY);
|
||||
LayoutDeviceIntRect rect = base->GetPositionAndSize();
|
||||
mOpenerScreenRect =
|
||||
DesktopIntRect::Round(rect / base->DevicePixelsPerDesktopPixel());
|
||||
if (!mOpenerScreenRect.IsEmpty()) {
|
||||
initialPos = mOpenerScreenRect.TopLeft();
|
||||
ConstrainToOpenerScreen(&initialPos.x, &initialPos.y);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: need to get the default window size from prefs...
|
||||
// Doesn't come from prefs... will come from CSS/XUL/RDF
|
||||
DesktopIntRect deskRect(initialX, initialY, aInitialWidth, aInitialHeight);
|
||||
DesktopIntRect deskRect(initialPos,
|
||||
DesktopIntSize(aInitialWidth, aInitialHeight));
|
||||
|
||||
// Create top level window
|
||||
if (gfxPlatform::IsHeadless()) {
|
||||
|
@ -688,9 +679,8 @@ NS_IMETHODIMP AppWindow::GetDevicePixelsPerDesktopPixel(double* aScale) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AppWindow::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
|
||||
*aScale = mWindow ? mWindow->GetDefaultScale().scale : 1.0;
|
||||
return NS_OK;
|
||||
double AppWindow::GetWidgetCSSToDeviceScale() {
|
||||
return mWindow ? mWindow->GetDefaultScale().scale : 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AppWindow::SetPositionDesktopPix(int32_t aX, int32_t aY) {
|
||||
|
@ -853,11 +843,7 @@ NS_IMETHODIMP AppWindow::Center(nsIAppWindow* aRelative, bool aScreen,
|
|||
}
|
||||
if (!aRelative) {
|
||||
if (!mOpenerScreenRect.IsEmpty()) {
|
||||
// FIXME - check if these are device or display pixels
|
||||
screenmgr->ScreenForRect(mOpenerScreenRect.X(), mOpenerScreenRect.Y(),
|
||||
mOpenerScreenRect.Width(),
|
||||
mOpenerScreenRect.Height(),
|
||||
getter_AddRefs(screen));
|
||||
screen = screenmgr->ScreenForRect(mOpenerScreenRect);
|
||||
} else {
|
||||
screenmgr->GetPrimaryScreen(getter_AddRefs(screen));
|
||||
}
|
||||
|
@ -1028,9 +1014,7 @@ NS_IMETHODIMP AppWindow::SetEnabled(bool aEnable) {
|
|||
|
||||
NS_IMETHODIMP AppWindow::GetMainWidget(nsIWidget** aMainWidget) {
|
||||
NS_ENSURE_ARG_POINTER(aMainWidget);
|
||||
|
||||
*aMainWidget = mWindow;
|
||||
NS_IF_ADDREF(*aMainWidget);
|
||||
NS_IF_ADDREF(*aMainWidget = mWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1146,9 +1130,7 @@ NS_IMETHODIMP AppWindow::ForceRoundedDimensions() {
|
|||
int32_t contentHeightCSS = 0;
|
||||
int32_t windowWidthCSS = 0;
|
||||
int32_t windowHeightCSS = 0;
|
||||
double devicePerCSSPixels = 1.0;
|
||||
|
||||
GetUnscaledDevicePixelsPerCSSPixel(&devicePerCSSPixels);
|
||||
double devicePerCSSPixels = UnscaledDevicePixelsPerCSSPixel().scale;
|
||||
|
||||
GetAvailScreenSize(&availWidthCSS, &availHeightCSS);
|
||||
|
||||
|
@ -1384,32 +1366,32 @@ bool AppWindow::LoadSizeFromXUL(int32_t& aSpecWidth, int32_t& aSpecHeight) {
|
|||
}
|
||||
|
||||
void AppWindow::SetSpecifiedSize(int32_t aSpecWidth, int32_t aSpecHeight) {
|
||||
// constrain to screen size
|
||||
int32_t screenWidth;
|
||||
int32_t screenHeight;
|
||||
// These are in CSS pixels of the main window.
|
||||
// TODO(emilio): In my testing we usually have a pres context around, can we
|
||||
// just use it? That'd simplify the coordinate calculations.
|
||||
{
|
||||
int32_t screenWidth;
|
||||
int32_t screenHeight;
|
||||
|
||||
if (NS_SUCCEEDED(GetAvailScreenSize(&screenWidth, &screenHeight))) {
|
||||
if (aSpecWidth > screenWidth) {
|
||||
aSpecWidth = screenWidth;
|
||||
}
|
||||
if (aSpecHeight > screenHeight) {
|
||||
aSpecHeight = screenHeight;
|
||||
if (NS_SUCCEEDED(GetAvailScreenSize(&screenWidth, &screenHeight))) {
|
||||
if (aSpecWidth > screenWidth) {
|
||||
aSpecWidth = screenWidth;
|
||||
}
|
||||
if (aSpecHeight > screenHeight) {
|
||||
aSpecHeight = screenHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(mWindow, "we expected to have a window already");
|
||||
|
||||
int32_t currWidth = 0;
|
||||
int32_t currHeight = 0;
|
||||
GetSize(&currWidth, &currHeight); // returns device pixels
|
||||
|
||||
// convert specified values to device pixels, and resize if needed
|
||||
double cssToDevPx = mWindow ? mWindow->GetDefaultScale().scale : 1.0;
|
||||
aSpecWidth = NSToIntRound(aSpecWidth * cssToDevPx);
|
||||
aSpecHeight = NSToIntRound(aSpecHeight * cssToDevPx);
|
||||
mIntrinsicallySized = false;
|
||||
if (aSpecWidth != currWidth || aSpecHeight != currHeight) {
|
||||
SetSize(aSpecWidth, aSpecHeight, false);
|
||||
|
||||
// Convert specified values to device pixels, and resize if needed
|
||||
auto newSize = RoundedToInt(CSSIntSize(aSpecWidth, aSpecHeight) *
|
||||
UnscaledDevicePixelsPerCSSPixel());
|
||||
if (newSize != nsIBaseWindow::GetSize()) {
|
||||
SetSize(newSize.width, newSize.height, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1516,10 +1498,7 @@ void AppWindow::StaggerPosition(int32_t& aRequestedX, int32_t& aRequestedY,
|
|||
nsAutoString windowType;
|
||||
windowElement->GetAttribute(WINDOWTYPE_ATTRIBUTE, windowType);
|
||||
|
||||
int32_t screenTop = 0, // it's pointless to initialize these ...
|
||||
screenRight = 0, // ... but to prevent oversalubrious and ...
|
||||
screenBottom = 0, // ... underbright compilers from ...
|
||||
screenLeft = 0; // ... issuing warnings.
|
||||
DesktopIntRect screenRect;
|
||||
bool gotScreen = false;
|
||||
|
||||
{ // fetch screen coordinates
|
||||
|
@ -1527,26 +1506,21 @@ void AppWindow::StaggerPosition(int32_t& aRequestedX, int32_t& aRequestedY,
|
|||
do_GetService("@mozilla.org/gfx/screenmanager;1"));
|
||||
if (screenMgr) {
|
||||
nsCOMPtr<nsIScreen> ourScreen;
|
||||
// the coordinates here are already display pixels
|
||||
// The coordinates here are already display pixels
|
||||
// XXX aSpecWidth and aSpecHeight are CSS pixels!
|
||||
screenMgr->ScreenForRect(aRequestedX, aRequestedY, aSpecWidth,
|
||||
aSpecHeight, getter_AddRefs(ourScreen));
|
||||
if (ourScreen) {
|
||||
int32_t screenWidth, screenHeight;
|
||||
ourScreen->GetAvailRectDisplayPix(&screenLeft, &screenTop, &screenWidth,
|
||||
&screenHeight);
|
||||
screenBottom = screenTop + screenHeight;
|
||||
screenRight = screenLeft + screenWidth;
|
||||
screenRect = ourScreen->GetAvailRectDisplayPix();
|
||||
|
||||
// Get the screen's scaling factors and convert staggering constants
|
||||
// from CSS px to desktop pixel units
|
||||
double desktopToDeviceScale = 1.0, cssToDeviceScale = 1.0;
|
||||
ourScreen->GetContentsScaleFactor(&desktopToDeviceScale);
|
||||
ourScreen->GetDefaultCSSScaleFactor(&cssToDeviceScale);
|
||||
double cssToDesktopFactor = cssToDeviceScale / desktopToDeviceScale;
|
||||
kOffset = NSToIntRound(kOffset * cssToDesktopFactor);
|
||||
kSlop = NSToIntRound(kSlop * cssToDesktopFactor);
|
||||
auto scale = ourScreen->GetCSSToDesktopScale();
|
||||
kOffset = (CSSCoord(kOffset) * scale).Rounded();
|
||||
kSlop = (CSSCoord(kSlop) * scale).Rounded();
|
||||
// Convert dimensions from CSS to desktop pixels
|
||||
aSpecWidth = NSToIntRound(aSpecWidth * cssToDesktopFactor);
|
||||
aSpecHeight = NSToIntRound(aSpecHeight * cssToDesktopFactor);
|
||||
aSpecWidth = (CSSCoord(aSpecWidth) * scale).Rounded();
|
||||
aSpecHeight = (CSSCoord(aSpecHeight) * scale).Rounded();
|
||||
gotScreen = true;
|
||||
}
|
||||
}
|
||||
|
@ -1595,20 +1569,20 @@ void AppWindow::StaggerPosition(int32_t& aRequestedX, int32_t& aRequestedY,
|
|||
if (gotScreen) {
|
||||
// if we're moving to the right and we need to bounce...
|
||||
if (!(bouncedX & 0x1) &&
|
||||
((aRequestedX + aSpecWidth) > screenRight)) {
|
||||
aRequestedX = screenRight - aSpecWidth;
|
||||
((aRequestedX + aSpecWidth) > screenRect.XMost())) {
|
||||
aRequestedX = screenRect.XMost() - aSpecWidth;
|
||||
++bouncedX;
|
||||
}
|
||||
|
||||
// if we're moving to the left and we need to bounce...
|
||||
if ((bouncedX & 0x1) && aRequestedX < screenLeft) {
|
||||
aRequestedX = screenLeft;
|
||||
if ((bouncedX & 0x1) && aRequestedX < screenRect.X()) {
|
||||
aRequestedX = screenRect.X();
|
||||
++bouncedX;
|
||||
}
|
||||
|
||||
// if we hit the bottom then bounce to the top
|
||||
if (aRequestedY + aSpecHeight > screenBottom) {
|
||||
aRequestedY = screenTop;
|
||||
if (aRequestedY + aSpecHeight > screenRect.YMost()) {
|
||||
aRequestedY = screenRect.Y();
|
||||
++bouncedY;
|
||||
}
|
||||
}
|
||||
|
@ -2176,7 +2150,8 @@ NS_IMETHODIMP
|
|||
AppWindow::GetPrimaryContentSize(int32_t* aWidth, int32_t* aHeight) {
|
||||
if (mPrimaryBrowserParent) {
|
||||
return GetPrimaryRemoteTabSize(aWidth, aHeight);
|
||||
} else if (mPrimaryContentShell) {
|
||||
}
|
||||
if (mPrimaryContentShell) {
|
||||
return GetPrimaryContentShellSize(aWidth, aHeight);
|
||||
}
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -2200,16 +2175,14 @@ nsresult AppWindow::GetPrimaryContentShellSize(int32_t* aWidth,
|
|||
nsCOMPtr<nsIBaseWindow> shellWindow(do_QueryInterface(mPrimaryContentShell));
|
||||
NS_ENSURE_STATE(shellWindow);
|
||||
|
||||
int32_t devicePixelWidth, devicePixelHeight;
|
||||
double shellScale = 1.0;
|
||||
// We want to return CSS pixels. First, we get device pixels
|
||||
// from the content area...
|
||||
shellWindow->GetSize(&devicePixelWidth, &devicePixelHeight);
|
||||
// And then get the device pixel scaling factor. Dividing device
|
||||
// pixels by this scaling factor gives us CSS pixels.
|
||||
shellWindow->GetUnscaledDevicePixelsPerCSSPixel(&shellScale);
|
||||
*aWidth = NSToIntRound(devicePixelWidth / shellScale);
|
||||
*aHeight = NSToIntRound(devicePixelHeight / shellScale);
|
||||
CSSIntSize size = RoundedToInt(
|
||||
shellWindow->GetSize() / shellWindow->UnscaledDevicePixelsPerCSSPixel());
|
||||
*aWidth = size.width;
|
||||
*aHeight = size.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2227,9 +2200,9 @@ nsresult AppWindow::SetPrimaryRemoteTabSize(int32_t aWidth, int32_t aHeight) {
|
|||
int32_t shellWidth, shellHeight;
|
||||
GetPrimaryRemoteTabSize(&shellWidth, &shellHeight);
|
||||
|
||||
double scale = 1.0;
|
||||
GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
|
||||
// FIXME: This is wrong (pre-existing), the above call acounts for zoom and
|
||||
// this one doesn't.
|
||||
double scale = UnscaledDevicePixelsPerCSSPixel().scale;
|
||||
SizeShellToWithLimit(aWidth, aHeight, shellWidth * scale,
|
||||
shellHeight * scale);
|
||||
return NS_OK;
|
||||
|
@ -3306,10 +3279,7 @@ void AppWindow::ConstrainToOpenerScreen(int32_t* aX, int32_t* aY) {
|
|||
nsCOMPtr<nsIScreenManager> screenmgr =
|
||||
do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
if (screenmgr) {
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
screenmgr->ScreenForRect(
|
||||
mOpenerScreenRect.X(), mOpenerScreenRect.Y(), mOpenerScreenRect.Width(),
|
||||
mOpenerScreenRect.Height(), getter_AddRefs(screen));
|
||||
nsCOMPtr<nsIScreen> screen = screenmgr->ScreenForRect(mOpenerScreenRect);
|
||||
if (screen) {
|
||||
screen->GetAvailRectDisplayPix(&left, &top, &width, &height);
|
||||
if (*aX < left || *aX > left + width) {
|
||||
|
|
|
@ -339,7 +339,9 @@ class AppWindow final : public nsIBaseWindow,
|
|||
uint32_t mChromeFlags;
|
||||
nsCOMPtr<nsIOpenWindowInfo> mInitialOpenWindowInfo;
|
||||
nsString mTitle;
|
||||
nsIntRect mOpenerScreenRect; // the screen rect of the opener
|
||||
|
||||
// The screen rect of the opener.
|
||||
mozilla::DesktopIntRect mOpenerScreenRect;
|
||||
|
||||
nsCOMPtr<nsIRemoteTab> mPrimaryBrowserParent;
|
||||
|
||||
|
|
|
@ -262,10 +262,8 @@ NS_IMETHODIMP nsChromeTreeOwner::Destroy() {
|
|||
return mAppWindow->Destroy();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChromeTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(
|
||||
double* aScale) {
|
||||
NS_ENSURE_STATE(mAppWindow);
|
||||
return mAppWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||
double nsChromeTreeOwner::GetWidgetCSSToDeviceScale() {
|
||||
return mAppWindow ? mAppWindow->GetWidgetCSSToDeviceScale() : 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChromeTreeOwner::GetDevicePixelsPerDesktopPixel(
|
||||
|
|
|
@ -397,10 +397,8 @@ NS_IMETHODIMP nsContentTreeOwner::Destroy() {
|
|||
return mAppWindow->Destroy();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsContentTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(
|
||||
double* aScale) {
|
||||
NS_ENSURE_STATE(mAppWindow);
|
||||
return mAppWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||
double nsContentTreeOwner::GetWidgetCSSToDeviceScale() {
|
||||
return mAppWindow ? mAppWindow->GetWidgetCSSToDeviceScale() : 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(
|
||||
|
|
Загрузка…
Ссылка в новой задаче