зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1439875: Size the XUL window before doing layout. r=smaug
The only subtle thing is the mCenterAfterLoad stuff, which is gated after a mChromeLoaded. Other than that it follows the same pattern as bug 345560. MozReview-Commit-ID: 8qDiA2yn9DB
This commit is contained in:
Родитель
5d9c70d584
Коммит
7ca346f1b8
|
@ -2663,19 +2663,17 @@ XULDocument::DoneWalking()
|
|||
NotifyPossibleTitleChange(false);
|
||||
|
||||
// Before starting layout, check whether we're a toplevel chrome
|
||||
// window. If we are, set our chrome flags now, so that we don't have
|
||||
// to restyle the whole frame tree after StartLayout.
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShell();
|
||||
if (item) {
|
||||
// window. If we are, setup some state so that we don't have to restyle
|
||||
// the whole tree after StartLayout.
|
||||
if (nsCOMPtr<nsIDocShellTreeItem> item = GetDocShell()) {
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
item->GetTreeOwner(getter_AddRefs(owner));
|
||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(owner);
|
||||
if (xulWin) {
|
||||
if (nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(owner)) {
|
||||
nsCOMPtr<nsIDocShell> xulWinShell;
|
||||
xulWin->GetDocShell(getter_AddRefs(xulWinShell));
|
||||
if (SameCOMIdentity(xulWinShell, item)) {
|
||||
// We're the chrome document! Apply our chrome flags now.
|
||||
xulWin->ApplyChromeFlags();
|
||||
// We're the chrome document!
|
||||
xulWin->BeforeStartLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,12 +128,14 @@ interface nsIXULWindow : nsISupports
|
|||
attribute nsIXULBrowserWindow XULBrowserWindow;
|
||||
|
||||
/**
|
||||
* Back-door method to force application of chrome flags at a particular
|
||||
* time. Do NOT call this unless you know what you're doing! In particular,
|
||||
* Back-door method to make sure some stuff is done when the document is
|
||||
* ready for layout, that would cause expensive computation otherwise later.
|
||||
*
|
||||
* Do NOT call this unless you know what you're doing! In particular,
|
||||
* calling this when this XUL window doesn't yet have a document in its
|
||||
* docshell could cause problems.
|
||||
*/
|
||||
[noscript] void applyChromeFlags();
|
||||
[noscript] void beforeStartLayout();
|
||||
|
||||
/**
|
||||
* Given the dimensions of some content area held within this
|
||||
|
|
|
@ -274,8 +274,9 @@ NS_IMETHODIMP nsXULWindow::SetChromeFlags(uint32_t aChromeFlags)
|
|||
"SetChromeFlags() after AssumeChromeFlagsAreFrozen()!");
|
||||
|
||||
mChromeFlags = aChromeFlags;
|
||||
if (mChromeLoaded)
|
||||
NS_ENSURE_SUCCESS(ApplyChromeFlags(), NS_ERROR_FAILURE);
|
||||
if (mChromeLoaded) {
|
||||
ApplyChromeFlags();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1083,82 +1084,7 @@ void nsXULWindow::OnChromeLoaded()
|
|||
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.)
|
||||
if (!parentWindow)
|
||||
positionSet = false;
|
||||
#endif
|
||||
if (positionSet) {
|
||||
// We have to do this before sizing the window, because sizing depends
|
||||
// on the resolution of the screen we're on. But positioning needs to
|
||||
// know the size so that it can constrain to screen bounds.... as an
|
||||
// initial guess here, we'll use the specified size (if any).
|
||||
positionSet = LoadPositionFromXUL(specWidth, specHeight);
|
||||
}
|
||||
|
||||
if (gotSize) {
|
||||
SetSpecifiedSize(specWidth, specHeight);
|
||||
}
|
||||
|
||||
if (mIntrinsicallySized) {
|
||||
// (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
|
||||
nsCOMPtr<nsIContentViewer> cv;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(cv));
|
||||
if (cv) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = do_QueryInterface(mDocShell);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
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 + 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) {
|
||||
LoadPositionFromXUL(specWidth, specHeight);
|
||||
}
|
||||
|
||||
LoadMiscPersistentAttributesFromXUL();
|
||||
|
||||
if (mCenterAfterLoad && !positionSet) {
|
||||
Center(parentWindow, parentWindow ? false : true, false);
|
||||
}
|
||||
SizeShell();
|
||||
|
||||
if (mShowAfterLoad) {
|
||||
SetVisibility(true);
|
||||
|
@ -2262,10 +2188,13 @@ void nsXULWindow::PersistentAttributesDirty(uint32_t aDirtyFlags)
|
|||
mPersistentAttributesDirty |= aDirtyFlags & mPersistentAttributesMask;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::ApplyChromeFlags()
|
||||
void
|
||||
nsXULWindow::ApplyChromeFlags()
|
||||
{
|
||||
nsCOMPtr<dom::Element> window = GetWindowDOMElement();
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mChromeLoaded) {
|
||||
// The two calls in this block don't need to happen early because they
|
||||
|
@ -2304,12 +2233,99 @@ NS_IMETHODIMP nsXULWindow::ApplyChromeFlags()
|
|||
|
||||
// Note that if we're not actually changing the value this will be a no-op,
|
||||
// so no need to compare to the old value.
|
||||
ErrorResult rv;
|
||||
IgnoredErrorResult rv;
|
||||
window->SetAttribute(NS_LITERAL_STRING("chromehidden"), newvalue, rv);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULWindow::BeforeStartLayout()
|
||||
{
|
||||
ApplyChromeFlags();
|
||||
SyncAttributesToWidget();
|
||||
SizeShell();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULWindow::SizeShell()
|
||||
{
|
||||
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.)
|
||||
if (!parentWindow)
|
||||
positionSet = false;
|
||||
#endif
|
||||
if (positionSet) {
|
||||
// We have to do this before sizing the window, because sizing depends
|
||||
// on the resolution of the screen we're on. But positioning needs to
|
||||
// know the size so that it can constrain to screen bounds.... as an
|
||||
// initial guess here, we'll use the specified size (if any).
|
||||
positionSet = LoadPositionFromXUL(specWidth, specHeight);
|
||||
}
|
||||
|
||||
if (gotSize) {
|
||||
SetSpecifiedSize(specWidth, specHeight);
|
||||
}
|
||||
|
||||
if (mIntrinsicallySized) {
|
||||
// (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
|
||||
nsCOMPtr<nsIContentViewer> cv;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(cv));
|
||||
if (cv) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = do_QueryInterface(mDocShell);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
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 + 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) {
|
||||
LoadPositionFromXUL(specWidth, specHeight);
|
||||
}
|
||||
|
||||
LoadMiscPersistentAttributesFromXUL();
|
||||
|
||||
if (mChromeLoaded && mCenterAfterLoad && !positionSet) {
|
||||
Center(parentWindow, parentWindow ? false : true, false);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::GetXULBrowserWindow(nsIXULBrowserWindow * *aXULBrowserWindow)
|
||||
{
|
||||
NS_IF_ADDREF(*aXULBrowserWindow = mXULBrowserWindow);
|
||||
|
|
|
@ -93,6 +93,8 @@ protected:
|
|||
NS_IMETHOD ForceRoundedDimensions();
|
||||
NS_IMETHOD GetAvailScreenSize(int32_t* aAvailWidth, int32_t* aAvailHeight);
|
||||
|
||||
void ApplyChromeFlags();
|
||||
void SizeShell();
|
||||
void OnChromeLoaded();
|
||||
void StaggerPosition(int32_t &aRequestedX, int32_t &aRequestedY,
|
||||
int32_t aSpecWidth, int32_t aSpecHeight);
|
||||
|
|
Загрузка…
Ссылка в новой задаче