Bug 1442521 - Make width/height attr on <window> mean the inner size in nsXULWindow. r?smaug
It seems that the layout system assumes those attributes are for size of
the <window> element, i.e. inner window size, not outer window size.
See for example nsContainerFrame::SyncWindowProperties. It reads
{min,max}{width,height} attributes from the element via
nsIFrame::GetXUL{Min,Max}Size, and passes them into SetSizeConstraints.
The latter inflates the sizes with window decoration size before calling
into widget code. It can also be seen that various XUL size related
methods on nsBox and nsIFrame put the same assumption.
The test test_windowminmaxsize.xul apparently puts the same assumption
as the layout system on the meaning of those properties.
(Another test test_resize_move_windows.xul, which tests effectiveness of
features of window.open, also fails if we size the window earlier than
current in
bug 1439875, and doesn't fail with this patch on top. It may
indicate that it makes use of the same assumption, but I can't really
figure out how it does so.)
MozReview-Commit-ID: IdMwDc59Ltg
--- a/toolkit/content/tests/chrome/test_screenPersistence.xul
+++ b/toolkit/content/tests/chrome/test_screenPersistence.xul
@@ -39,18 +39,18 @@
}
function checkTest2() {
let runTime = Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime);
if (runTime.OS != "Linux") {
is(win.screenX, 80, "The window should be placed now at x=80px");
is(win.screenY, 80, "The window should be placed now at y=80px");
}
- is(win.outerHeight, 300, "The window size should be height=300px");
- is(win.outerWidth, 300, "The window size should be width=300px");
+ is(win.innerHeight, 300, "The window size should be height=300px");
+ is(win.innerWidth, 300, "The window size should be width=300px");
win.close();
SimpleTest.finish();
}
]]></script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -1059,37 +1059,55 @@ NS_IMETHODIMP nsXULWindow::ForceRoundedD
SetPrimaryContentSize(targetContentWidth, targetContentHeight);
mIgnoreXULSize = true;
mIgnoreXULSizeMode = true;
return NS_OK;
}
+static LayoutDeviceIntSize
+GetWindowOuterInnerDiff(nsIWidget* aWindow)
+{
+ if (!aWindow) {
+ return LayoutDeviceIntSize();
+ }
+ LayoutDeviceIntSize baseSize(200, 200);
+ LayoutDeviceIntSize windowSize = aWindow->ClientToWindowSize(baseSize);
+ return windowSize - baseSize;
+}
+
void nsXULWindow::OnChromeLoaded()
{
nsresult rv = EnsureContentTreeOwner();
if (NS_SUCCEEDED(rv)) {
mChromeLoaded = true;
ApplyChromeFlags();
SyncAttributesToWidget();
int32_t specWidth = -1, specHeight = -1;
bool gotSize = false;
bool isContent = false;
GetHasPrimaryContent(&isContent);
+ CSSIntSize windowDiff = mWindow
+ ? RoundedToInt(GetWindowOuterInnerDiff(mWindow) /
+ mWindow->GetDefaultScale())
+ : CSSIntSize();
+
// If this window has a primary content and fingerprinting resistance is
// enabled, we enforce this window to rounded dimensions.
if (isContent && nsContentUtils::ShouldResistFingerprinting()) {
ForceRoundedDimensions();
} else if (!mIgnoreXULSize) {
gotSize = LoadSizeFromXUL(specWidth, specHeight);
+ specWidth += windowDiff.width;
+ specHeight += windowDiff.height;
}
bool positionSet = !mIgnoreXULPosition;
nsCOMPtr<nsIXULWindow> parentWindow(do_QueryReferent(mParentWindow));
#if defined(XP_UNIX) && !defined(XP_MACOSX)
// don't override WM placement on unix for independent, top-level windows
// (however, we think the benefits of intelligent dependent window placement
// trump that override.)
@@ -1118,18 +1136,18 @@ void nsXULWindow::OnChromeLoaded()
docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
if (treeOwner) {
// GetContentSize can fail, so initialise |width| and |height| to be
// on the safe side.
int32_t width = 0, height = 0;
if (NS_SUCCEEDED(cv->GetContentSize(&width, &height))) {
treeOwner->SizeShellTo(docShellAsItem, width, height);
// Update specified size for the final LoadPositionFromXUL call.
- specWidth = width;
- specHeight = height;
+ specWidth = width + windowDiff.width;
+ specHeight = height + windowDiff.height;
}
}
}
}
// Now that we have set the window's final size, we can re-do its
// positioning so that it is properly constrained to the screen.
if (positionSet) {
@@ -1653,27 +1671,30 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
if (shouldPersist) {
IgnoredErrorResult err;
ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE, err);
}
}
}
if ((mPersistentAttributesDirty & PAD_SIZE) && gotRestoredBounds) {
+ LayoutDeviceIntSize winDiff = GetWindowOuterInnerDiff(mWindow);
if (persistString.Find("width") >= 0) {
- SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.Width() / sizeScale.scale));
+ auto width = rect.Width() - winDiff.width;
+ SprintfLiteral(sizeBuf, "%d", NSToIntRound(width / sizeScale.scale));
CopyASCIItoUTF16(sizeBuf, sizeString);
docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
if (shouldPersist) {
IgnoredErrorResult err;
ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE, err);
}
}
if (persistString.Find("height") >= 0) {
- SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.Height() / sizeScale.scale));
+ auto height = rect.Height() - winDiff.height;
+ SprintfLiteral(sizeBuf, "%d", NSToIntRound(height / sizeScale.scale));
CopyASCIItoUTF16(sizeBuf, sizeString);
docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
if (shouldPersist) {
IgnoredErrorResult err;
ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE, err);
}
}
}