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:
Emilio Cobos Álvarez 2022-06-14 15:01:52 +00:00
Родитель e779b145d6
Коммит ee23efc9b5
21 изменённых файлов: 248 добавлений и 378 удалений

Просмотреть файл

@ -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(&currentScale);
// 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",

14
widget/nsIBaseWindow.cpp Normal file
Просмотреть файл

@ -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(