diff --git a/devtools/client/framework/toolbox-window.xhtml b/devtools/client/framework/toolbox-window.xhtml index 09960681b763..a3ecc39ae41d 100644 --- a/devtools/client/framework/toolbox-window.xhtml +++ b/devtools/client/framework/toolbox-window.xhtml @@ -5,13 +5,19 @@ - + diff --git a/gfx/src/nsSize.h b/gfx/src/nsSize.h index b4125e603585..823630ec9f76 100644 --- a/gfx/src/nsSize.h +++ b/gfx/src/nsSize.h @@ -26,6 +26,10 @@ struct nsSize : public mozilla::gfx::BaseSize { float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; inline mozilla::gfx::IntSize ToNearestPixels(nscoord aAppUnitsPerPixel) const; + inline mozilla::gfx::IntSize ScaleToOutsidePixels( + float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; + inline mozilla::gfx::IntSize ToOutsidePixels(nscoord aAppUnitsPerPixel) const; + /** * Return this size scaled to a different appunits per pixel (APP) ratio. * @param aFromAPP the APP to scale from @@ -44,11 +48,24 @@ inline mozilla::gfx::IntSize nsSize::ScaleToNearestPixels( aYScale)); } +inline mozilla::gfx::IntSize nsSize::ScaleToOutsidePixels( + float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { + return mozilla::gfx::IntSize( + NSToIntCeil(NSAppUnitsToDoublePixels(width, aAppUnitsPerPixel) * aXScale), + NSToIntCeil(NSAppUnitsToDoublePixels(height, aAppUnitsPerPixel) * + aYScale)); +} + inline mozilla::gfx::IntSize nsSize::ToNearestPixels( nscoord aAppUnitsPerPixel) const { return ScaleToNearestPixels(1.0f, 1.0f, aAppUnitsPerPixel); } +inline mozilla::gfx::IntSize nsSize::ToOutsidePixels( + nscoord aAppUnitsPerPixel) const { + return ScaleToOutsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); +} + inline nsSize nsSize::ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const { if (aFromAPP != aToAPP) { diff --git a/layout/base/Units.h b/layout/base/Units.h index 2240f65c6894..0aa3a5aab18a 100644 --- a/layout/base/Units.h +++ b/layout/base/Units.h @@ -429,6 +429,12 @@ struct LayoutDevicePixel { aRect.ToOutsidePixels(aAppUnitsPerDevPixel)); } + static LayoutDeviceIntSize FromAppUnitsToOutside( + const nsSize& aSize, nscoord aAppUnitsPerDevPixel) { + return LayoutDeviceIntSize::FromUnknownSize( + aSize.ToOutsidePixels(aAppUnitsPerDevPixel)); + } + static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize, nscoord aAppUnitsPerDevPixel) { return LayoutDeviceIntSize( diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index e82300814b48..cb3e53c9347c 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3136,8 +3136,10 @@ nsresult nsDocumentViewer::GetContentSizeInternal(int32_t* aWidth, // Ceil instead of rounding here, so we can actually guarantee showing all the // content. - *aWidth = std::ceil(presContext->AppUnitsToFloatDevPixels(shellArea.width)); - *aHeight = std::ceil(presContext->AppUnitsToFloatDevPixels(shellArea.height)); + auto devOuterSize = LayoutDeviceIntSize::FromAppUnitsToOutside( + shellArea, presContext->AppUnitsPerDevPixel()); + *aWidth = devOuterSize.width; + *aHeight = devOuterSize.height; return NS_OK; } diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 549cef84ff16..154d8f6841ca 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -551,18 +551,22 @@ static bool IsTopLevelWidget(nsIWidget* aWidget) { void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, nsIFrame* aFrame, nsView* aView, gfxContext* aRC, uint32_t aFlags) { -#ifdef MOZ_XUL - if (!aView || !nsCSSRendering::IsCanvasFrame(aFrame) || !aView->HasWidget()) + if (!aView || !nsCSSRendering::IsCanvasFrame(aFrame) || !aView->HasWidget()) { return; + } nsCOMPtr windowWidget = GetPresContextContainerWidget(aPresContext); - if (!windowWidget || !IsTopLevelWidget(windowWidget)) return; + if (!windowWidget || !IsTopLevelWidget(windowWidget)) { + return; + } nsViewManager* vm = aView->GetViewManager(); nsView* rootView = vm->GetRootView(); - if (aView != rootView) return; + if (aView != rootView) { + return; + } Element* rootElement = aPresContext->Document()->GetRootElement(); if (!rootElement) { @@ -571,7 +575,9 @@ void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, nsIFrame* rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame(); - if (!rootFrame) return; + if (!rootFrame) { + return; + } if (aFlags & SET_ASYNC) { aView->SetNeedsWindowPropertiesSync(); @@ -600,7 +606,9 @@ void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, windowWidget->SetWindowShadowStyle(shadow); } - if (!aRC) return; + if (!aRC) { + return; + } if (!weak.IsAlive()) { return; @@ -608,36 +616,49 @@ void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, nsSize minSize(0, 0); nsSize maxSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - if (rootElement->IsXULElement()) { - nsBoxLayoutState aState(aPresContext, aRC); - minSize = rootFrame->GetXULMinSize(aState); - maxSize = rootFrame->GetXULMaxSize(aState); - } else { - auto* pos = rootFrame->StylePosition(); - if (pos->mMinWidth.ConvertsToLength()) { - minSize.width = pos->mMinWidth.ToLength(); - } - if (pos->mMinHeight.ConvertsToLength()) { - minSize.height = pos->mMinHeight.ToLength(); - } - if (pos->mMaxWidth.ConvertsToLength()) { - maxSize.width = pos->mMaxWidth.ToLength(); - } - if (pos->mMaxHeight.ConvertsToLength()) { - maxSize.height = pos->mMaxHeight.ToLength(); + + const auto& pos = *rootFrame->StylePosition(); +#ifdef MOZ_XUL + if (rootFrame->IsXULBoxFrame()) { + nsBoxLayoutState xulState(aPresContext, aRC); + minSize = rootFrame->GetXULMinSize(xulState); + const bool isMinContent = + pos.mMinWidth.IsExtremumLength() && + pos.mMinWidth.AsExtremumLength() == StyleExtremumLength::MinContent; + // By default we behave with min-width: max-content, to ensure that all + // content is shown (i.e., the GetXULPrefSize call below). + // + // It can be overridden to min-content (i.e., leave GetXULMinSize()) and + // a fixed width (handled below). + if (!isMinContent && !pos.mMinWidth.ConvertsToLength()) { + minSize.width = rootFrame->GetXULPrefSize(xulState).width; } + maxSize = rootFrame->GetXULMaxSize(xulState); } - SetSizeConstraints(aPresContext, windowWidget, minSize, maxSize); #endif + + if (pos.mMinWidth.ConvertsToLength()) { + minSize.width = pos.mMinWidth.ToLength(); + } + if (pos.mMinHeight.ConvertsToLength()) { + minSize.height = pos.mMinHeight.ToLength(); + } + if (pos.mMaxWidth.ConvertsToLength()) { + maxSize.width = pos.mMaxWidth.ToLength(); + } + if (pos.mMaxHeight.ConvertsToLength()) { + maxSize.height = pos.mMaxHeight.ToLength(); + } + + SetSizeConstraints(aPresContext, windowWidget, minSize, maxSize); } void nsContainerFrame::SetSizeConstraints(nsPresContext* aPresContext, nsIWidget* aWidget, const nsSize& aMinSize, const nsSize& aMaxSize) { - LayoutDeviceIntSize devMinSize( - aPresContext->AppUnitsToDevPixels(aMinSize.width), - aPresContext->AppUnitsToDevPixels(aMinSize.height)); + auto devMinSize = LayoutDeviceIntSize::FromAppUnitsToOutside( + aMinSize, aPresContext->AppUnitsPerDevPixel()); LayoutDeviceIntSize devMaxSize( aMaxSize.width == NS_UNCONSTRAINEDSIZE ? NS_MAXSIZE @@ -647,9 +668,8 @@ void nsContainerFrame::SetSizeConstraints(nsPresContext* aPresContext, : aPresContext->AppUnitsToDevPixels(aMaxSize.height)); // MinSize has a priority over MaxSize - if (devMinSize.width > devMaxSize.width) devMaxSize.width = devMinSize.width; - if (devMinSize.height > devMaxSize.height) - devMaxSize.height = devMinSize.height; + devMaxSize.width = std::max(devMinSize.width, devMaxSize.width); + devMaxSize.height = std::max(devMinSize.height, devMaxSize.height); widget::SizeConstraints constraints(devMinSize, devMaxSize); diff --git a/toolkit/content/tests/chrome/window_screenPosSize.xhtml b/toolkit/content/tests/chrome/window_screenPosSize.xhtml index accc10d8f10b..cfb9f38343b1 100644 --- a/toolkit/content/tests/chrome/window_screenPosSize.xhtml +++ b/toolkit/content/tests/chrome/window_screenPosSize.xhtml @@ -8,6 +8,7 @@ screenY="80" height="300" width="300" + style="min-width: 0" persist="screenX screenY height width">