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">