Bug 1446264 part 3 - Avoid ignoring and persisting size/position/sizemode when we are setting them from SizeShell(). r?bz,florian
When SetSize etc. are called before OnChromeLoaded has been invoked,
the functions assume that the window initialization code wants to size
the window specifically, and thus ignore the values from the <window>
element.
However,
bug 1439875 changes the behavior so that SizeShell is also
invoked before OnChromeLoaded, which confuses the functions above, and
causes some of the attributes not to be loaded properly.
This patch adds a separate flag to avoid ignoring those attributes when
those functions are invoked as part of SizeShell itself.
It can cause extra reflow if the window is opened in maximized state,
and thus the new whitelist items. They may be fixed by
bug 1448199.
MozReview-Commit-ID: 7jT8w9KGmzy
--- a/browser/base/content/test/performance/browser_windowopen.js
+++ b/browser/base/content/test/performance/browser_windowopen.js
@@ -110,16 +110,41 @@ add_task(async function() {
});
await TestUtils.topicObserved("browser-delayed-startup-finished",
subject => subject == win);
await BrowserTestUtils.firstBrowserLoaded(win, false);
await BrowserTestUtils.browserStopped(win.gBrowser.selectedBrowser, "about:home");
+ if (Services.appinfo.OS == "WINNT" && win.windowState == win.STATE_MAXIMIZED) {
+ // The reflows below are triggered by maximizing the window after
+ // layout. They should be fixed by bug 1447864.
+ EXPECTED_REFLOWS.push(
+ {
+ stack: [
+ "rect@chrome://browser/content/browser-tabsintitlebar.js",
+ "_update@chrome://browser/content/browser-tabsintitlebar.js",
+ "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
+ "handleEvent@chrome://browser/content/tabbrowser.xml",
+ ],
+ maxCount: 4,
+ },
+ {
+ stack: [
+ "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
+ "_update@chrome://browser/content/browser-tabsintitlebar.js",
+ "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js",
+ "handleEvent@chrome://browser/content/tabbrowser.xml",
+ ],
+ maxCount: 2,
+ },
+ );
+ }
+
await new Promise(resolve => {
// 10 is an arbitrary value here, it needs to be at least 2 to avoid
// races with code initializing itself using idle callbacks.
(function waitForIdle(count = 10) {
if (!count) {
resolve();
return;
}
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -88,16 +88,17 @@ using dom::AutoNoJSAPI;
nsXULWindow::nsXULWindow(uint32_t aChromeFlags)
: mChromeTreeOwner(nullptr),
mContentTreeOwner(nullptr),
mPrimaryContentTreeOwner(nullptr),
mModalStatus(NS_OK),
mContinueModalLoop(false),
mDebuting(false),
mChromeLoaded(false),
+ mSizingShellFromXUL(false),
mShowAfterLoad(false),
mIntrinsicallySized(false),
mCenterAfterLoad(false),
mIsHiddenWindow(false),
mLockedUntilChromeLoad(false),
mIgnoreXULSize(false),
mIgnoreXULPosition(false),
mChromeFlagsFrozen(false),
@@ -572,16 +573,21 @@ NS_IMETHODIMP nsXULWindow::GetUnscaledDe
{
*aScale = mWindow ? mWindow->GetDefaultScale().scale : 1.0;
return NS_OK;
}
NS_IMETHODIMP nsXULWindow::SetPositionDesktopPix(int32_t aX, int32_t aY)
{
mWindow->Move(aX, aY);
+ if (mSizingShellFromXUL) {
+ // If we're invoked for sizing from XUL, we want to neither ignore anything
+ // nor persist anything, since it's already the value in XUL.
+ return NS_OK;
+ }
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this position. We don't persist this one-time position.
mIgnoreXULPosition = true;
return NS_OK;
}
PersistentAttributesDirty(PAD_POSITION);
SavePersistentAttributes();
@@ -611,16 +617,21 @@ NS_IMETHODIMP nsXULWindow::SetSize(int32
the window is being opened. but it should probably just always be so. */
mWindow->SetSizeMode(nsSizeMode_Normal);
mIntrinsicallySized = false;
DesktopToLayoutDeviceScale scale = mWindow->GetDesktopToDeviceScale();
DesktopSize size = LayoutDeviceIntSize(aCX, aCY) / scale;
mWindow->Resize(size.width, size.height, aRepaint);
+ if (mSizingShellFromXUL) {
+ // If we're invoked for sizing from XUL, we want to neither ignore anything
+ // nor persist anything, since it's already the value in XUL.
+ return NS_OK;
+ }
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this size & in the normal size mode (since it is the only mode
// in which setting dimensions makes sense). We don't persist this one-time
// size.
mIgnoreXULSize = true;
mIgnoreXULSizeMode = true;
return NS_OK;
@@ -644,16 +655,21 @@ NS_IMETHODIMP nsXULWindow::SetPositionAn
mWindow->SetSizeMode(nsSizeMode_Normal);
mIntrinsicallySized = false;
DesktopToLayoutDeviceScale scale = mWindow->GetDesktopToDeviceScale();
DesktopRect rect = LayoutDeviceIntRect(aX, aY, aCX, aCY) / scale;
mWindow->Resize(rect.X(), rect.Y(), rect.Width(), rect.Height(),
!!(aFlags & nsIBaseWindow::eRepaint));
+ if (mSizingShellFromXUL) {
+ // If we're invoked for sizing from XUL, we want to neither ignore anything
+ // nor persist anything, since it's already the value in XUL.
+ return NS_OK;
+ }
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this size and position. We don't persist this one-time setting.
mIgnoreXULPosition = true;
mIgnoreXULSize = true;
mIgnoreXULSizeMode = true;
return NS_OK;
}
@@ -2265,16 +2281,19 @@ nsXULWindow::BeforeStartLayout()
SyncAttributesToWidget();
SizeShell();
return NS_OK;
}
void
nsXULWindow::SizeShell()
{
+ AutoRestore<bool> sizingShellFromXUL(mSizingShellFromXUL);
+ mSizingShellFromXUL = true;
+
int32_t specWidth = -1, specHeight = -1;
bool gotSize = false;
bool isContent = false;
GetHasPrimaryContent(&isContent);
CSSIntSize windowDiff = GetOuterToInnerSizeDifferenceInCSSPixels(mWindow);
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -152,16 +152,17 @@ protected:
nsCOMPtr<nsIPrompt> mPrompter;
nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
nsCOMPtr<nsIXULBrowserWindow> mXULBrowserWindow;
nsCOMPtr<nsIDocShellTreeItem> mPrimaryContentShell;
nsresult mModalStatus;
bool mContinueModalLoop;
bool mDebuting; // being made visible right now
bool mChromeLoaded; // True when chrome has loaded
+ bool mSizingShellFromXUL; // true when in SizeShell()
bool mShowAfterLoad;
bool mIntrinsicallySized;
bool mCenterAfterLoad;
bool mIsHiddenWindow;
bool mLockedUntilChromeLoad;
bool mIgnoreXULSize;
bool mIgnoreXULPosition;
bool mChromeFlagsFrozen;