Bug 343515 - need API for tabbrowsers to tell docshells they're visible/hidden.r=gavin,sr=bz,a=blocker

This commit is contained in:
Bobby Holley 2010-08-05 11:27:52 -04:00
parent ccbe5fc67b
commit 27a2d4812b
9 changed files with 132 additions and 4 deletions

View File

@ -737,8 +737,10 @@
this._lastRelatedTab = null;
var oldBrowser = this.mCurrentBrowser;
if (oldBrowser)
if (oldBrowser) {
oldBrowser.setAttribute("type", "content-targetable");
oldBrowser.docShell.isActive = false;
}
var updatePageReport = false;
if (!oldBrowser ||
@ -747,6 +749,7 @@
updatePageReport = true;
newBrowser.setAttribute("type", "content-primary");
newBrowser.docShell.isActive = true;
this.mCurrentBrowser = newBrowser;
this.mCurrentTab = this.selectedTab;
@ -1189,6 +1192,10 @@
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
try {
b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
// We start our browsers out as inactive, and then maintain
// activeness in the tab switcher.
b.docShell.isActive = false;
}
catch (ex) { }
}

View File

@ -703,6 +703,7 @@ nsDocShell::nsDocShell():
mAllowAuth(PR_TRUE),
mAllowKeywordFixup(PR_FALSE),
mIsOffScreenBrowser(PR_FALSE),
mIsActive(PR_TRUE),
mFiredUnloadEvent(PR_FALSE),
mEODForCurrentDocument(PR_FALSE),
mURIResultedInDocument(PR_FALSE),
@ -2496,6 +2497,10 @@ nsDocShell::SetDocLoaderParent(nsDocLoader * aParent)
{
SetAllowImages(value);
}
if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value)))
{
SetIsActive(value);
}
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
value = PR_FALSE;
}
@ -4618,6 +4623,40 @@ nsDocShell::GetIsOffScreenBrowser(PRBool *aIsOffScreen)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsActive(PRBool aIsActive)
{
// We disallow setting active on chrome docshells.
if (mItemType == nsIDocShellTreeItem::typeChrome)
return NS_ERROR_INVALID_ARG;
// Keep track ourselves.
mIsActive = aIsActive;
// Tell the PresShell about it.
nsCOMPtr<nsIPresShell> pshell;
GetPresShell(getter_AddRefs(pshell));
if (pshell)
pshell->SetIsActive(aIsActive);
// Recursively tell all of our children
PRInt32 n = mChildList.Count();
for (PRInt32 i = 0; i < n; ++i) {
nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(ChildAt(i));
if (docshell)
docshell->SetIsActive(aIsActive);
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetIsActive(PRBool *aIsActive)
{
*aIsActive = mIsActive;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetVisibility(PRBool aVisibility)
{
@ -6909,7 +6948,10 @@ nsDocShell::RestoreFromHistory()
PRBool allowDNSPrefetch;
childShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
// this.AddChild(child) calls child.SetDocLoaderParent(this), meaning
// that the child inherits our state. Among other things, this means
// that the child inherits our mIsActive, which is what we want.
AddChild(childItem);
childShell->SetAllowPlugins(allowPlugins);

View File

@ -787,6 +787,7 @@ protected:
PRPackedBool mAllowAuth;
PRPackedBool mAllowKeywordFixup;
PRPackedBool mIsOffScreenBrowser;
PRPackedBool mIsActive;
// This boolean is set to true right before we fire pagehide and generally
// unset when we embed a new content viewer. While it's true no navigation

View File

@ -71,7 +71,7 @@ interface nsIPrincipal;
interface nsIWebBrowserPrint;
interface nsIVariant;
[scriptable, uuid(8ac6b880-776a-44d4-b271-a7e64ae3debd)]
[scriptable, uuid(bf6db598-3833-400b-9e53-ec220cb2496c)]
interface nsIDocShell : nsISupports
{
/**
@ -521,4 +521,11 @@ interface nsIDocShell : nsISupports
* current docshell.
*/
readonly attribute boolean canExecuteScripts;
/**
* Sets whether a docshell is active. An active docshell is one that is
* visible, and thus is not a good candidate for certain optimizations
* like image frame discarding. Docshells are active unless told otherwise.
*/
attribute boolean isActive;
};

View File

@ -52,7 +52,7 @@ interface nsIWeakReference;
* to register any listeners. The interface may also be used at runtime
* to obtain the content DOM window and from that the rest of the DOM.
*/
[scriptable, uuid(69E5DF00-7B8B-11d3-AF61-00A024FFC08C)]
[scriptable, uuid(33e9d001-caab-4ba9-8961-54902f197202)]
interface nsIWebBrowser : nsISupports
{
/**
@ -165,4 +165,15 @@ interface nsIWebBrowser : nsISupports
* @see nsIDOMWindow
*/
readonly attribute nsIDOMWindow contentDOMWindow;
/**
* Whether this web browser is active. Active means that it's visible
* enough that we want to avoid certain optimizations like discarding
* decoded image data and throttling the refresh driver. In Firefox,
* this corresponds to the visible tab.
*
* Defaults to true. For optimal performance, set it to false when
* appropriate.
*/
attribute boolean isActive;
};

View File

@ -108,6 +108,7 @@ nsWebBrowser::nsWebBrowser() : mDocShellTreeOwner(nsnull),
mContentType(typeContentWrapper),
mActivating(PR_FALSE),
mShouldEnableHistory(PR_TRUE),
mIsActive(PR_TRUE),
mParentNativeWindow(nsnull),
mProgressListener(nsnull),
mBackgroundColor(0),
@ -419,6 +420,23 @@ NS_IMETHODIMP nsWebBrowser::GetContentDOMWindow(nsIDOMWindow **_retval)
return rv;
}
NS_IMETHODIMP nsWebBrowser::GetIsActive(PRBool *rv)
{
*rv = mIsActive;
return NS_OK;
}
NS_IMETHODIMP nsWebBrowser::SetIsActive(PRBool aIsActive)
{
// Set our copy of the value
mIsActive = aIsActive;
// If we have a docshell, pass on the request
if (mDocShell)
return mDocShell->SetIsActive(aIsActive);
return NS_OK;
}
//*****************************************************************************
// nsWebBrowser::nsIDocShellTreeItem
//*****************************************************************************
@ -1631,6 +1649,12 @@ NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
// By default, do not allow DNS prefetch, so we don't break our frozen
// API. Embeddors who decide to enable it should do so manually.
mDocShell->SetAllowDNSPrefetch(PR_FALSE);
// It's possible to call setIsActive() on us before we have a docshell.
// If we're getting a docshell now, pass along our desired value. The
// default here (true) matches the default of the docshell, so this is
// a no-op unless setIsActive(false) has been called on us.
mDocShell->SetIsActive(mIsActive);
}
else
{

View File

@ -169,6 +169,7 @@ protected:
PRUint32 mContentType;
PRPackedBool mActivating;
PRPackedBool mShouldEnableHistory;
PRPackedBool mIsActive;
nativeWindow mParentNativeWindow;
nsIWebProgressListener *mProgressListener;
nsCOMPtr<nsIWebProgress> mWebProgress;

View File

@ -954,6 +954,16 @@ public:
return mObservesMutationsForPrint;
}
void SetIsActive(PRBool aIsActive)
{
mIsActive = aIsActive;
}
PRBool IsActive()
{
return mIsActive;
}
// mouse capturing
static CapturingContentInfo gCaptureInfo;
@ -1083,6 +1093,7 @@ protected:
PRPackedBool mIsReflowing;
PRPackedBool mPaintingSuppressed; // For all documents we initially lock down painting.
PRPackedBool mIsThemeSupportDisabled; // Whether or not form controls should use nsITheme in this shell.
PRPackedBool mIsActive;
#ifdef ACCESSIBILITY
/**

View File

@ -1362,6 +1362,9 @@ public:
static PRInt64 SizeOfBidiMemoryReporter(void *) {
return EstimateShellsMemory(LiveShellBidiSizeEnumerator);
}
protected:
void QueryIsActive();
};
class nsAutoCauseReflowNotifier
@ -1595,6 +1598,7 @@ PresShell::PresShell()
#endif
mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
mIsThemeSupportDisabled = PR_FALSE;
mIsActive = PR_TRUE;
#ifdef DEBUG
mPresArenaAllocCount = 0;
#endif
@ -1801,6 +1805,9 @@ PresShell::Init(nsIDocument* aDocument,
}
#endif // MOZ_SMIL
// Get our activeness from the docShell.
QueryIsActive();
return NS_OK;
}
@ -7306,6 +7313,10 @@ PresShell::Thaw()
mDocument->EnumerateSubDocuments(ThawSubDocument, nsnull);
UnsuppressPainting();
// Get the activeness of our presshell, as this might have changed
// while we were in the bfcache
QueryIsActive();
}
void
@ -8943,3 +8954,16 @@ void nsIPresShell::ReleaseStatics()
delete sLiveShells;
sLiveShells = nsnull;
}
// Asks our docshell whether we're active.
void PresShell::QueryIsActive()
{
nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
nsCOMPtr<nsIDocShell> docshell(do_QueryInterface(container));
if (docshell) {
PRBool isActive;
nsresult rv = docshell->GetIsActive(&isActive);
if (NS_SUCCEEDED(rv))
SetIsActive(isActive);
}
}