diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 5a1a642a56b8..af8311e431a6 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -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 ownerWindow(do_QueryInterface(mTreeOwner)); - if (ownerWindow) { - return ownerWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale); + if (nsCOMPtr ownerWindow = do_QueryInterface(mTreeOwner)) { + return ownerWindow->GetWidgetCSSToDeviceScale(); } - - *aScale = 1.0; - return NS_OK; + return 1.0; } NS_IMETHODIMP diff --git a/docshell/base/nsDocShellTreeOwner.cpp b/docshell/base/nsDocShellTreeOwner.cpp index e5787bc423f6..1f0667b5e49c 100644 --- a/docshell/base/nsDocShellTreeOwner.cpp +++ b/docshell/base/nsDocShellTreeOwner.cpp @@ -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 diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 5a35b25ee800..621e3e71590f 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -7518,53 +7518,37 @@ void nsGlobalWindowInner::SetReplaceableWindowCoord( if (innerWidthSpecified || innerHeightSpecified || outerWidthSpecified || outerHeightSpecified) { nsCOMPtr treeOwnerAsWin = outer->GetTreeOwnerWindow(); - nsCOMPtr screen; nsCOMPtr 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 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); } } diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 025f6accb270..674353189dca 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -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(aDeviceSize.width / scale / zoom), - static_cast(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(aCSSSize.width * scale * zoom), - static_cast(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 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 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 deviceSize = GetRDMDeviceSize(*mDoc); if (deviceSize.isSome()) { - const CSSIntSize& size = deviceSize.value(); - return nsIntSize(size.width, size.height); + return *deviceSize; } } nsCOMPtr 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 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 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); diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index e34b8b93a8d0..70cea10edfd5 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -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, diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp index 17b05c19afe1..09698b52f639 100644 --- a/dom/ipc/BrowserParent.cpp +++ b/dom/ipc/BrowserParent.cpp @@ -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; diff --git a/gfx/src/nsDeviceContext.cpp b/gfx/src/nsDeviceContext.cpp index 8913a90dcdaf..a4b28f3d0c14 100644 --- a/gfx/src/nsDeviceContext.cpp +++ b/gfx/src/nsDeviceContext.cpp @@ -74,7 +74,7 @@ void nsDeviceContext::SetDPI(double* aScale) { mAppUnitsPerDevPixelAtUnitFullZoom = NS_lround((AppUnitsPerCSSPixel() * 96) / dpi); } else { - RefPtr primaryScreen = + RefPtr 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; } diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp index 1558cc335a93..6a2a462dcd5f 100644 --- a/toolkit/components/browser/nsWebBrowser.cpp +++ b/toolkit/components/browser/nsWebBrowser.cpp @@ -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 diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp index 6c57fda5a083..33ffbeb8e969 100644 --- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp +++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp @@ -539,7 +539,7 @@ nsWindowWatcher::OpenWindowWithRemoteTab(nsIRemoteTab* aRemoteTab, // get various interfaces for aDocShellItem, used throughout this method CSSToDesktopScale cssToDesktopScale(1.0f); if (nsCOMPtr 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 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 = diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 98510b93e0b3..8a26fadb5673 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -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."); diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 134db026e30b..d78c35950c12 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -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; diff --git a/widget/Screen.cpp b/widget/Screen.cpp index dc9e810f9d2f..4962d1c9bac7 100644 --- a/widget/Screen.cpp +++ b/widget/Screen.cpp @@ -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; } diff --git a/widget/Screen.h b/widget/Screen.h index c29c15c01fb1..ac890e8ab26f 100644 --- a/widget/Screen.h +++ b/widget/Screen.h @@ -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; diff --git a/widget/moz.build b/widget/moz.build index 965f467aea68..21df2695eaad 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -225,6 +225,7 @@ UNIFIED_SOURCES += [ "nsDragServiceProxy.cpp", "nsFilePickerProxy.cpp", "nsHTMLFormatConverter.cpp", + "nsIBaseWindow.cpp", "nsIDeviceContextSpec.cpp", "nsIWidgetListener.cpp", "nsPrimitiveHelpers.cpp", diff --git a/widget/nsIBaseWindow.cpp b/widget/nsIBaseWindow.cpp new file mode 100644 index 000000000000..a9ebdcc86050 --- /dev/null +++ b/widget/nsIBaseWindow.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); +} diff --git a/widget/nsIBaseWindow.idl b/widget/nsIBaseWindow.idl index 3276ed780d51..0aef81a35091 100644 --- a/widget/nsIBaseWindow.idl +++ b/widget/nsIBaseWindow.idl @@ -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(); } %} diff --git a/widget/windows/SystemStatusBar.cpp b/widget/windows/SystemStatusBar.cpp index 3d39c1361259..5c710f58032f 100644 --- a/widget/windows/SystemStatusBar.cpp +++ b/widget/windows/SystemStatusBar.cpp @@ -244,17 +244,10 @@ LRESULT StatusBarEntry::OnMessage(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { return DefWindowProc(hWnd, msg, wp, lp); } - nsCOMPtr docShell = popupFrame->PresContext()->GetDocShell(); - nsCOMPtr 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 , and the popup code // that manages it expects that the window that the 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); diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp index fb36837f23da..4bd9ed49e56b 100644 --- a/xpfe/appshell/AppWindow.cpp +++ b/xpfe/appshell/AppWindow.cpp @@ -180,31 +180,22 @@ nsresult AppWindow::Initialize(nsIAppWindow* aParent, nsIAppWindow* aOpener, mIsHiddenWindow = aIsHiddenWindow; - int32_t initialX = 0, initialY = 0; + DesktopIntPoint initialPos; nsCOMPtr 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 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 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 screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1"); if (screenmgr) { - nsCOMPtr screen; - screenmgr->ScreenForRect( - mOpenerScreenRect.X(), mOpenerScreenRect.Y(), mOpenerScreenRect.Width(), - mOpenerScreenRect.Height(), getter_AddRefs(screen)); + nsCOMPtr screen = screenmgr->ScreenForRect(mOpenerScreenRect); if (screen) { screen->GetAvailRectDisplayPix(&left, &top, &width, &height); if (*aX < left || *aX > left + width) { diff --git a/xpfe/appshell/AppWindow.h b/xpfe/appshell/AppWindow.h index 749c64d9a684..d6c385ca201d 100644 --- a/xpfe/appshell/AppWindow.h +++ b/xpfe/appshell/AppWindow.h @@ -339,7 +339,9 @@ class AppWindow final : public nsIBaseWindow, uint32_t mChromeFlags; nsCOMPtr mInitialOpenWindowInfo; nsString mTitle; - nsIntRect mOpenerScreenRect; // the screen rect of the opener + + // The screen rect of the opener. + mozilla::DesktopIntRect mOpenerScreenRect; nsCOMPtr mPrimaryBrowserParent; diff --git a/xpfe/appshell/nsChromeTreeOwner.cpp b/xpfe/appshell/nsChromeTreeOwner.cpp index e400c1c482a8..faded6e791a9 100644 --- a/xpfe/appshell/nsChromeTreeOwner.cpp +++ b/xpfe/appshell/nsChromeTreeOwner.cpp @@ -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( diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp index e98baac37001..61b3e8e028a9 100644 --- a/xpfe/appshell/nsContentTreeOwner.cpp +++ b/xpfe/appshell/nsContentTreeOwner.cpp @@ -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(