--- a/docshell/base/nsIDocShellTreeOwner.idl
+++ b/docshell/base/nsIDocShellTreeOwner.idl
@@ -76,16 +76,36 @@ interface nsIDocShellTreeOwner : nsISupp
/*
Tells the tree owner to size its window or parent window in such a way
that the shell passed along will be the size specified.
*/
void sizeShellTo(in nsIDocShellTreeItem shell, in long cx, in long cy);
/*
+ Gets the size of the primary content area in CSS pixels. This should work
+ for both in-process and out-of-process content areas.
+ */
+ void getPrimaryContentSize(out long width, out long height);
+ /*
+ Sets the size of the primary content area in CSS pixels. This should work
+ for both in-process and out-of-process content areas.
+ */
+ void setPrimaryContentSize(in long width, in long height);
+
+ /*
+ Gets the size of the root docshell in CSS pixels.
+ */
+ void getRootShellSize(out long width, out long height);
+ /*
+ Sets the size of the root docshell in CSS pixels.
+ */
+ void setRootShellSize(in long width, in long height);
+
+ /*
Sets the persistence of different attributes of the window.
*/
void setPersistence(in boolean aPersistPosition,
in boolean aPersistSize,
in boolean aPersistSizeMode);
/*
Gets the current persistence states of the window.
@@ -93,9 +113,15 @@ interface nsIDocShellTreeOwner : nsISupp
void getPersistence(out boolean aPersistPosition,
out boolean aPersistSize,
out boolean aPersistSizeMode);
/*
Gets the number of targettable docshells.
*/
readonly attribute unsigned long targetableShellCount;
+
+ /*
+ Returns true if there is a primary content shell or a primary
+ tab parent.
+ */
+ readonly attribute bool hasPrimaryContent;
};
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5406,32 +5406,30 @@ ContentParent::RecvCreateWindow(PBrowser
}
return true;
}
nsCOMPtr<mozIDOMWindowProxy> window;
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
- const char* features = aFeatures.IsVoid() ? nullptr : aFeatures.get();
-
nsCOMPtr<nsPIWindowWatcher> pwwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
if (NS_WARN_IF(NS_FAILED(*aResult))) {
return true;
}
nsCOMPtr<nsITabParent> newRemoteTab;
if (!thisTabParent) {
// Because we weren't passed an opener tab, the content process has asked us
// to open a new window that is unrelated to a pre-existing tab.
*aResult = pwwatch->OpenWindowWithoutParent(getter_AddRefs(newRemoteTab));
} else {
- *aResult = pwwatch->OpenWindowWithTabParent(thisTabParent, features, aCalledFromJS,
+ *aResult = pwwatch->OpenWindowWithTabParent(thisTabParent, aFeatures, aCalledFromJS,
aFullZoom, getter_AddRefs(newRemoteTab));
}
if (NS_WARN_IF(NS_FAILED(*aResult))) {
return true;
}
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
--- a/embedding/browser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -439,16 +439,44 @@ nsDocShellTreeOwner::GetPrimaryTabParent
}
nsCOMPtr<nsITabParent> tab = mPrimaryTabParent;
tab.forget(aTab);
return NS_OK;
}
NS_IMETHODIMP
+nsDocShellTreeOwner::GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetRootShellSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
nsDocShellTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
int32_t aCX, int32_t aCY)
{
nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
NS_ENSURE_STATE(mTreeOwner || webBrowserChrome);
if (mTreeOwner) {
@@ -532,16 +560,23 @@ nsDocShellTreeOwner::GetTargetableShellC
mTreeOwner->GetTargetableShellCount(aResult);
} else {
*aResult = 0;
}
return NS_OK;
}
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetHasPrimaryContent(bool* aResult)
+{
+ *aResult = mPrimaryTabParent || mPrimaryContentShell;
+ return NS_OK;
+}
+
//*****************************************************************************
// nsDocShellTreeOwner::nsIBaseWindow
//*****************************************************************************
NS_IMETHODIMP
nsDocShellTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
nsIWidget* aParentWidget, int32_t aX,
int32_t aY, int32_t aCX, int32_t aCY)
--- a/embedding/components/windowwatcher/nsPIWindowWatcher.idl
+++ b/embedding/components/windowwatcher/nsPIWindowWatcher.idl
@@ -100,17 +100,17 @@ interface nsPIWindowWatcher : nsISupport
* @param aOpenerFullZoom
* The current zoom multiplier for the opener tab. This is then
* applied to the newly opened window.
*
* @return the nsITabParent of the initial browser for the newly opened
* window.
*/
nsITabParent openWindowWithTabParent(in nsITabParent aOpeningTab,
- in string aFeatures,
+ in ACString aFeatures,
in boolean aCalledFromJS,
in float aOpenerFullZoom);
/**
* Find a named docshell tree item amongst all windows registered
* with the window watcher. This may be a subframe in some window,
* for example.
*
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -486,22 +486,22 @@ CheckUserContextCompatibility(nsIDocShel
NS_ENSURE_SUCCESS(rv, false);
return principalUserContextId == userContextId;
}
NS_IMETHODIMP
nsWindowWatcher::OpenWindowWithoutParent(nsITabParent** aResult)
{
- return OpenWindowWithTabParent(nullptr, "", true, 1.0f, aResult);
+ return OpenWindowWithTabParent(nullptr, EmptyCString(), true, 1.0f, aResult);
}
NS_IMETHODIMP
nsWindowWatcher::OpenWindowWithTabParent(nsITabParent* aOpeningTabParent,
- const char* aFeatures,
+ const nsACString& aFeatures,
bool aCalledFromJS,
float aOpenerFullZoom,
nsITabParent** aResult)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(mWindowCreator);
if (!nsContentUtils::IsSafeToRunScript()) {
@@ -564,18 +564,17 @@ nsWindowWatcher::OpenWindowWithTabParent
// B2G multi-screen support. mozDisplayId is returned from the
// "display-changed" event, it is also platform-dependent.
#ifdef MOZ_WIDGET_GONK
int retval = WinHasOption(features, "mozDisplayId", 0, nullptr);
windowCreator2->SetScreenId(retval);
#endif
- nsAutoCString features(aFeatures);
- uint32_t chromeFlags = CalculateChromeFlagsForChild(features);
+ uint32_t chromeFlags = CalculateChromeFlagsForChild(aFeatures);
// A content process has asked for a new window, which implies
// that the new window will need to be remote.
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
bool cancel = false;
nsCOMPtr<nsIWebBrowserChrome> parentChrome(do_GetInterface(parentTreeOwner));
nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
@@ -611,25 +610,25 @@ nsWindowWatcher::OpenWindowWithTabParent
}
chromeContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
// Tabs opened from a content process can only open new windows
// that will also run with out-of-process tabs.
chromeContext->SetRemoteTabs(true);
- if (PL_strcasestr(features.get(), "width=") ||
- PL_strcasestr(features.get(), "height=")) {
+ if (PL_strcasestr(aFeatures.BeginReading(), "width=") ||
+ PL_strcasestr(aFeatures.BeginReading(), "height=")) {
chromeTreeOwner->SetPersistence(false, false, false);
}
SizeSpec sizeSpec;
- CalcSizeSpec(features, sizeSpec);
- SizeOpenedDocShellItem(chromeTreeItem, parentWindowOuter, false, sizeSpec,
- &aOpenerFullZoom);
+ CalcSizeSpec(aFeatures, sizeSpec);
+ SizeOpenedWindow(chromeTreeOwner, parentWindowOuter, false, sizeSpec,
+ &aOpenerFullZoom);
nsCOMPtr<nsITabParent> newTabParent;
chromeTreeOwner->GetPrimaryTabParent(getter_AddRefs(newTabParent));
if (NS_WARN_IF(!newTabParent)) {
return NS_ERROR_UNEXPECTED;
}
newTabParent.forget(aResult);
@@ -1223,18 +1222,20 @@ nsWindowWatcher::OpenWindowInternal(mozI
getter_AddRefs(storage));
if (storage) {
newStorageManager->CloneStorage(storage);
}
}
}
if (isNewToplevelWindow) {
- SizeOpenedDocShellItem(newDocShellItem, aParent, isCallerChrome, sizeSpec,
- aOpenerFullZoom);
+ nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
+ newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
+ SizeOpenedWindow(newTreeOwner, aParent, isCallerChrome, sizeSpec,
+ aOpenerFullZoom);
}
// XXXbz isn't windowIsModal always true when windowIsModalContentDialog?
if (windowIsModal || windowIsModalContentDialog) {
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
@@ -2231,81 +2232,95 @@ nsWindowWatcher::CalcSizeSpec(const nsAC
aResult.mUseDefaultHeight = true;
} else {
aResult.mInnerHeight = temp;
}
aResult.mInnerHeightSpecified = true;
}
}
-/* Size and position the new window according to aSizeSpec. This method
+/* Size and position a new window according to aSizeSpec. This method
is assumed to be called after the window has already been given
a default position and size; thus its current position and size are
accurate defaults. The new window is made visible at method end.
+ @param aTreeOwner
+ The top-level nsIDocShellTreeOwner of the newly opened window.
+ @param aParent (optional)
+ The parent window from which to inherit zoom factors from if
+ aOpenerFullZoom isn't passed.
+ @param aIsCallerChrome
+ True if the code requesting the new window is privileged.
+ @param aSizeSpec
+ The size that the new window should be.
+ @param aOpenerFullZoom
+ An optional pointer to a zoom factor to scale the content
+ to.
*/
void
-nsWindowWatcher::SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
- mozIDOMWindowProxy* aParent,
- bool aIsCallerChrome,
- const SizeSpec& aSizeSpec,
- float* aOpenerFullZoom)
+nsWindowWatcher::SizeOpenedWindow(nsIDocShellTreeOwner* aTreeOwner,
+ mozIDOMWindowProxy* aParent,
+ bool aIsCallerChrome,
+ const SizeSpec& aSizeSpec,
+ float* aOpenerFullZoom)
{
+ // We should only be sizing top-level windows if we're in the parent
+ // process.
+ MOZ_ASSERT(XRE_IsParentProcess());
+
// position and size of window
int32_t left = 0, top = 0, width = 100, height = 100;
// difference between chrome and content size
int32_t chromeWidth = 0, chromeHeight = 0;
// whether the window size spec refers to chrome or content
bool sizeChromeWidth = true, sizeChromeHeight = true;
// get various interfaces for aDocShellItem, used throughout this method
- nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
- aDocShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
- nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(treeOwner));
+ nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(aTreeOwner));
if (!treeOwnerAsWin) { // we'll need this to actually size the docshell
return;
}
double openerZoom = aOpenerFullZoom ? *aOpenerFullZoom : 1.0;
if (aParent && !aOpenerFullZoom) {
nsCOMPtr<nsPIDOMWindowOuter> piWindow = nsPIDOMWindowOuter::From(aParent);
if (nsIDocument* doc = piWindow->GetDoc()) {
if (nsIPresShell* shell = doc->GetShell()) {
if (nsPresContext* presContext = shell->GetPresContext()) {
openerZoom = presContext->GetFullZoom();
}
}
}
}
- double scale;
+ double scale = 1.0;
treeOwnerAsWin->GetUnscaledDevicePixelsPerCSSPixel(&scale);
/* The current position and size will be unchanged if not specified
(and they fit entirely onscreen). Also, calculate the difference
between chrome and content sizes on aDocShellItem's window.
This latter point becomes important if chrome and content
specifications are mixed in aFeatures, and when bringing the window
back from too far off the right or bottom edges of the screen. */
treeOwnerAsWin->GetPositionAndSize(&left, &top, &width, &height);
left = NSToIntRound(left / scale);
top = NSToIntRound(top / scale);
width = NSToIntRound(width / scale);
height = NSToIntRound(height / scale);
{
- // scope shellWindow why not
- nsCOMPtr<nsIBaseWindow> shellWindow(do_QueryInterface(aDocShellItem));
- if (shellWindow) {
- int32_t cox, coy;
- double shellScale;
- shellWindow->GetSize(&cox, &coy);
- shellWindow->GetUnscaledDevicePixelsPerCSSPixel(&shellScale);
- chromeWidth = width - NSToIntRound(cox / shellScale);
- chromeHeight = height - NSToIntRound(coy / shellScale);
+ int32_t contentWidth, contentHeight;
+ bool hasPrimaryContent = false;
+ aTreeOwner->GetHasPrimaryContent(&hasPrimaryContent);
+ if (hasPrimaryContent) {
+ aTreeOwner->GetPrimaryContentSize(&contentWidth, &contentHeight);
+ } else {
+ aTreeOwner->GetRootShellSize(&contentWidth, &contentHeight);
}
+ chromeWidth = width - contentWidth;
+ chromeHeight = height - contentHeight;
}
// Set up left/top
if (aSizeSpec.mLeftSpecified) {
left = NSToIntRound(aSizeSpec.mLeft * openerZoom);
}
if (aSizeSpec.mTopSpecified) {
@@ -2347,17 +2362,16 @@ nsWindowWatcher::SizeOpenedDocShellItem(
if (aIsCallerChrome) {
// Only enable special priveleges for chrome when chrome calls
// open() on a chrome window
nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(aParent));
enabled = !aParent || chromeWin;
}
if (!enabled) {
-
// Security check failed. Ensure all args meet minimum reqs.
int32_t oldTop = top, oldLeft = left;
// We'll also need the screen dimensions
nsCOMPtr<nsIScreen> screen;
nsCOMPtr<nsIScreenManager> screenMgr(
do_GetService("@mozilla.org/gfx/screenmanager;1"));
@@ -2450,17 +2464,23 @@ nsWindowWatcher::SizeOpenedDocShellItem(
// wherever it really ended up
treeOwnerAsWin->GetUnscaledDevicePixelsPerCSSPixel(&scale);
}
if (aSizeSpec.SizeSpecified()) {
/* Prefer to trust the interfaces, which think in terms of pure
chrome or content sizes. If we have a mix, use the chrome size
adjusted by the chrome/content differences calculated earlier. */
if (!sizeChromeWidth && !sizeChromeHeight) {
- treeOwner->SizeShellTo(aDocShellItem, width * scale, height * scale);
+ bool hasPrimaryContent = false;
+ aTreeOwner->GetHasPrimaryContent(&hasPrimaryContent);
+ if (hasPrimaryContent) {
+ aTreeOwner->SetPrimaryContentSize(width * scale, height * scale);
+ } else {
+ aTreeOwner->SetRootShellSize(width * scale, height * scale);
+ }
} else {
if (!sizeChromeWidth) {
width += chromeWidth;
}
if (!sizeChromeHeight) {
height += chromeHeight;
}
treeOwnerAsWin->SetSize(width * scale, height * scale, false);
--- a/embedding/components/windowwatcher/nsWindowWatcher.h
+++ b/embedding/components/windowwatcher/nsWindowWatcher.h
@@ -102,21 +102,21 @@ protected:
static int32_t WinHasOption(const nsACString& aOptions, const char* aName,
int32_t aDefault, bool* aPresenceFlag);
/* Compute the right SizeSpec based on aFeatures */
static void CalcSizeSpec(const nsACString& aFeatures, SizeSpec& aResult);
static nsresult ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
nsPIDOMWindowOuter* aParent,
bool aWindowIsNew,
mozIDOMWindowProxy** aOpenedWindow);
- static void SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
- mozIDOMWindowProxy* aParent,
- bool aIsCallerChrome,
- const SizeSpec& aSizeSpec,
- float* aOpenerFullZoom);
+ static void SizeOpenedWindow(nsIDocShellTreeOwner* aTreeOwner,
+ mozIDOMWindowProxy* aParent,
+ bool aIsCallerChrome,
+ const SizeSpec& aSizeSpec,
+ float* aOpenerFullZoom);
static void GetWindowTreeItem(mozIDOMWindowProxy* aWindow,
nsIDocShellTreeItem** aResult);
static void GetWindowTreeOwner(nsPIDOMWindowOuter* aWindow,
nsIDocShellTreeOwner** aResult);
private:
static uint32_t CalculateChromeFlagsHelper(uint32_t aInitialFlags,
const nsACString& aFeatures,
--- a/xpfe/appshell/moz.build
+++ b/xpfe/appshell/moz.build
@@ -33,8 +33,10 @@ UNIFIED_SOURCES += [
'nsXULWindow.cpp',
]
LOCAL_INCLUDES += [
'/dom/base',
]
FINAL_LIBRARY = 'xul'
+
+include('/ipc/chromium/chromium-config.mozbuild')
\ No newline at end of file
--- a/xpfe/appshell/nsChromeTreeOwner.cpp
+++ b/xpfe/appshell/nsChromeTreeOwner.cpp
@@ -264,16 +264,48 @@ nsChromeTreeOwner::TabParentRemoved(nsIT
NS_IMETHODIMP
nsChromeTreeOwner::GetPrimaryTabParent(nsITabParent** aTab)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->GetPrimaryTabParent(aTab);
}
+NS_IMETHODIMP
+nsChromeTreeOwner::GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetPrimaryContentSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsChromeTreeOwner::SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->SetPrimaryContentSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsChromeTreeOwner::GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetRootShellSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsChromeTreeOwner::SetRootShellSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->SetRootShellSize(aWidth, aHeight);
+}
+
NS_IMETHODIMP nsChromeTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
int32_t aCX, int32_t aCY)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->SizeShellTo(aShellItem, aCX, aCY);
}
NS_IMETHODIMP
@@ -344,16 +376,23 @@ nsChromeTreeOwner::GetPersistence(bool*
NS_IMETHODIMP
nsChromeTreeOwner::GetTargetableShellCount(uint32_t* aResult)
{
*aResult = 0;
return NS_OK;
}
+NS_IMETHODIMP
+nsChromeTreeOwner::GetHasPrimaryContent(bool* aResult)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetHasPrimaryContent(aResult);
+}
+
//*****************************************************************************
// nsChromeTreeOwner::nsIBaseWindow
//*****************************************************************************
NS_IMETHODIMP nsChromeTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy)
{
// Ignore widget parents for now. Don't think those are a vaild thing to call.
--- a/xpfe/appshell/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/nsContentTreeOwner.cpp
@@ -329,16 +329,48 @@ nsContentTreeOwner::TabParentRemoved(nsI
NS_IMETHODIMP
nsContentTreeOwner::GetPrimaryTabParent(nsITabParent** aTab)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->GetPrimaryTabParent(aTab);
}
+NS_IMETHODIMP
+nsContentTreeOwner::GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetPrimaryContentSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsContentTreeOwner::SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->SetPrimaryContentSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsContentTreeOwner::GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetRootShellSize(aWidth, aHeight);
+}
+
+NS_IMETHODIMP
+nsContentTreeOwner::SetRootShellSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->SetRootShellSize(aWidth, aHeight);
+}
+
NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
int32_t aCX, int32_t aCY)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->SizeShellTo(aShellItem, aCX, aCY);
}
NS_IMETHODIMP
@@ -439,16 +471,23 @@ nsContentTreeOwner::GetPersistence(bool*
NS_IMETHODIMP
nsContentTreeOwner::GetTargetableShellCount(uint32_t* aResult)
{
NS_ENSURE_STATE(mXULWindow);
*aResult = mXULWindow->mTargetableShells.Count();
return NS_OK;
}
+NS_IMETHODIMP
+nsContentTreeOwner::GetHasPrimaryContent(bool* aResult)
+{
+ NS_ENSURE_STATE(mXULWindow);
+ return mXULWindow->GetHasPrimaryContent(aResult);
+}
+
//*****************************************************************************
// nsContentTreeOwner::nsIWebBrowserChrome3
//*****************************************************************************
NS_IMETHODIMP nsContentTreeOwner::OnBeforeLinkTraversal(const nsAString &originalTarget,
nsIURI *linkURI,
nsIDOMNode *linkNode,
bool isAppTab,
--- a/xpfe/appshell/nsIXULWindow.idl
+++ b/xpfe/appshell/nsIXULWindow.idl
@@ -130,17 +130,36 @@ interface nsIXULWindow : nsISupports
/**
* 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,
* calling this when this XUL window doesn't yet have a document in its
* docshell could cause problems.
*/
[noscript] void applyChromeFlags();
-
/**
- * Sometimes the child's nsDocShellTreeOwner needs to propogate a SizeShellTo call to the parent. But the
- * shellItem argument of the call will not be available on the parent side, so we pass its dimensions here.
+ * Given the dimensions of some content area held within this
+ * XUL window, and assuming that that content area will change
+ * its dimensions in linear proportion to the dimensions of this
+ * XUL window, changes the size of the XUL window so that the
+ * content area reaches a particular size.
+ *
+ * We need to supply the content area dimensions because sometimes
+ * the child's nsDocShellTreeOwner needs to propagate a SizeShellTo
+ * call to the parent. But the shellItem argument of the call will
+ * not be available on the parent side.
+ *
* Note: this is an internal method, other consumers should never call this.
+ *
+ * @param aDesiredWidth
+ * The desired width of the content area in device pixels.
+ * @param aDesiredHeight
+ * The desired height of the content area in device pixels.
+ * @param shellItemWidth
+ * The current width of the content area.
+ * @param shellItemHeight
+ * The current height of the content area.
*/
- [noscript, notxpcom] void sizeShellToWithLimit(in int32_t aCx, in int32_t aCy,
- in int32_t shellItemCx, in int32_t shellItemCy);
+ [noscript, notxpcom] void sizeShellToWithLimit(in int32_t aDesiredWidth,
+ in int32_t aDesiredHeight,
+ in int32_t shellItemWidth,
+ in int32_t shellItemHeight);
};
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -56,16 +56,17 @@
#include "prenv.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/dom/BarProps.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/TabParent.h"
using namespace mozilla;
using dom::AutoNoJSAPI;
#define SIZEMODE_NORMAL NS_LITERAL_STRING("normal")
#define SIZEMODE_MAXIMIZED NS_LITERAL_STRING("maximized")
#define SIZEMODE_MINIMIZED NS_LITERAL_STRING("minimized")
#define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
@@ -1796,16 +1797,107 @@ nsresult nsXULWindow::ContentShellRemove
if (!curItem || SameCOMIdentity(curItem, aContentShell)) {
mTargetableShells.RemoveObjectAt(i);
}
}
return NS_OK;
}
+NS_IMETHODIMP
+nsXULWindow::GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ if (mPrimaryTabParent) {
+ return GetPrimaryTabParentSize(aWidth, aHeight);
+ } else if (mPrimaryContentShell) {
+ return GetPrimaryContentShellSize(aWidth, aHeight);
+ }
+ return NS_ERROR_UNEXPECTED;
+}
+
+nsresult
+nsXULWindow::GetPrimaryTabParentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ TabParent* tabParent = TabParent::GetFrom(mPrimaryTabParent);
+ Element* element = tabParent->GetOwnerElement();
+ NS_ENSURE_STATE(element);
+
+ *aWidth = element->ClientWidth();
+ *aHeight = element->ClientHeight();
+ return NS_OK;
+}
+
+nsresult
+nsXULWindow::GetPrimaryContentShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ NS_ENSURE_STATE(mPrimaryContentShell);
+
+ nsCOMPtr<nsIBaseWindow> shellWindow(do_QueryInterface(mPrimaryContentShell));
+ NS_ENSURE_STATE(shellWindow);
+
+ int32_t devicePixelWidth, devicePixelHeight;
+ double shellScale = 1.0;
+ // We want to return CSS pixels. First, we get device pixels
+ // from the content area...
+ shellWindow->GetSize(&devicePixelWidth, &devicePixelHeight);
+ // And then get the device pixel scaling factor. Dividing device
+ // pixels by this scaling factor gives us CSS pixels.
+ shellWindow->GetUnscaledDevicePixelsPerCSSPixel(&shellScale);
+ *aWidth = NSToIntRound(devicePixelWidth / shellScale);
+ *aHeight = NSToIntRound(devicePixelHeight / shellScale);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULWindow::SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ if (mPrimaryTabParent) {
+ return SetPrimaryTabParentSize(aWidth, aHeight);
+ } else if (mPrimaryContentShell) {
+ return SizeShellTo(mPrimaryContentShell, aWidth, aHeight);
+ }
+ return NS_ERROR_UNEXPECTED;
+}
+
+nsresult
+nsXULWindow::SetPrimaryTabParentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ int32_t shellWidth, shellHeight;
+ GetPrimaryTabParentSize(&shellWidth, &shellHeight);
+
+ double scale = 1.0;
+ GetUnscaledDevicePixelsPerCSSPixel(&scale);
+
+ SizeShellToWithLimit(aWidth, aHeight,
+ shellWidth * scale, shellHeight * scale);
+ return NS_OK;
+}
+
+nsresult
+nsXULWindow::GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ nsCOMPtr<nsIBaseWindow> shellAsWin = do_QueryInterface(mDocShell);
+ NS_ENSURE_TRUE(shellAsWin, NS_ERROR_FAILURE);
+ return shellAsWin->GetSize(aWidth, aHeight);
+}
+
+nsresult
+nsXULWindow::SetRootShellSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = do_QueryInterface(mDocShell);
+ return SizeShellTo(docShellAsItem, aWidth, aHeight);
+}
+
NS_IMETHODIMP nsXULWindow::SizeShellTo(nsIDocShellTreeItem* aShellItem,
int32_t aCX, int32_t aCY)
{
// XXXTAB This is wrong, we should actually reflow based on the passed in
// shell. For now we are hacking and doing delta sizing. This is bad
// because it assumes all size we add will go to the shell which probably
// won't happen.
@@ -1924,16 +2016,22 @@ NS_IMETHODIMP nsXULWindow::CreateNewCont
NS_ENSURE_STATE(xulWin->mPrimaryContentShell || xulWin->mPrimaryTabParent);
*_retval = newWindow;
NS_ADDREF(*_retval);
return NS_OK;
}
+NS_IMETHODIMP nsXULWindow::GetHasPrimaryContent(bool* aResult)
+{
+ *aResult = mPrimaryTabParent || mPrimaryContentShell;
+ return NS_OK;
+}
+
void nsXULWindow::EnableParent(bool aEnable)
{
nsCOMPtr<nsIBaseWindow> parentWindow;
nsCOMPtr<nsIWidget> parentWidget;
parentWindow = do_QueryReferent(mParentWindow);
if (parentWindow)
parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
@@ -2177,34 +2275,36 @@ NS_IMETHODIMP nsXULWindow::GetXULBrowser
}
NS_IMETHODIMP nsXULWindow::SetXULBrowserWindow(nsIXULBrowserWindow * aXULBrowserWindow)
{
mXULBrowserWindow = aXULBrowserWindow;
return NS_OK;
}
-void nsXULWindow::SizeShellToWithLimit(int32_t aCX, int32_t aCY,
- int32_t shellItemCx, int32_t shellItemCy)
+void nsXULWindow::SizeShellToWithLimit(int32_t aDesiredWidth,
+ int32_t aDesiredHeight,
+ int32_t shellItemWidth,
+ int32_t shellItemHeight)
{
- int32_t widthDelta = aCX - shellItemCx;
- int32_t heightDelta = aCY - shellItemCy;
+ int32_t widthDelta = aDesiredWidth - shellItemWidth;
+ int32_t heightDelta = aDesiredHeight - shellItemHeight;
if (widthDelta || heightDelta) {
- int32_t winCX = 0;
- int32_t winCY = 0;
+ int32_t winWidth = 0;
+ int32_t winHeight = 0;
- GetSize(&winCX, &winCY);
+ GetSize(&winWidth, &winHeight);
// There's no point in trying to make the window smaller than the
- // desired docshell size --- that's not likely to work. This whole
+ // desired content area size --- that's not likely to work. This whole
// function assumes that the outer docshell is adding some constant
- // "border" chrome to aShellItem.
- winCX = std::max(winCX + widthDelta, aCX);
- winCY = std::max(winCY + heightDelta, aCY);
- SetSize(winCX, winCY, true);
+ // "border" chrome to the content area.
+ winWidth = std::max(winWidth + widthDelta, aDesiredWidth);
+ winHeight = std::max(winHeight + heightDelta, aDesiredHeight);
+ SetSize(winWidth, winHeight, true);
}
}
//*****************************************************************************
//*** nsContentShellInfo: Object Management
//*****************************************************************************
nsContentShellInfo::nsContentShellInfo(const nsAString& aID,
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -104,21 +104,31 @@ protected:
NS_IMETHOD GetWindowDOMWindow(mozIDOMWindowProxy** aDOMWindow);
mozilla::dom::Element* GetWindowDOMElement() const;
// See nsIDocShellTreeOwner for docs on next two methods
nsresult ContentShellAdded(nsIDocShellTreeItem* aContentShell,
bool aPrimary, bool aTargetable,
const nsAString& aID);
nsresult ContentShellRemoved(nsIDocShellTreeItem* aContentShell);
+ NS_IMETHOD GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight);
+ NS_IMETHOD SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight);
+ nsresult GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight);
+ nsresult SetRootShellSize(int32_t aWidth,
+ int32_t aHeight);
+
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
int32_t aCY);
NS_IMETHOD ExitModalLoop(nsresult aStatus);
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
+ NS_IMETHOD GetHasPrimaryContent(bool* aResult);
void EnableParent(bool aEnable);
bool ConstrainToZLevel(bool aImmediate, nsWindowZ *aPlacement,
nsIWidget *aReqBelow, nsIWidget **aActualBelow);
void PlaceWindowLayersBehind(uint32_t aLowLevel, uint32_t aHighLevel,
nsIXULWindow *aBehind);
void SetContentScrollbarVisibility(bool aVisible);
bool GetContentScrollbarVisibility();
@@ -158,16 +168,20 @@ protected:
uint32_t mPersistentAttributesMask;
uint32_t mChromeFlags;
nsString mTitle;
nsIntRect mOpenerScreenRect; // the screen rect of the opener
nsCOMArray<nsIWeakReference> mTargetableShells; // targetable shells only
nsCOMPtr<nsITabParent> mPrimaryTabParent;
+private:
+ nsresult GetPrimaryTabParentSize(int32_t* aWidth, int32_t* aHeight);
+ nsresult GetPrimaryContentShellSize(int32_t* aWidth, int32_t* aHeight);
+ nsresult SetPrimaryTabParentSize(int32_t aWidth, int32_t aHeight);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULWindow, NS_XULWINDOW_IMPL_CID)
// nsContentShellInfo
// Used to map shell IDs to nsIDocShellTreeItems.
class nsContentShellInfo