Bug 565388 - No paint for invisible docshell. r=tnikkel

This commit is contained in:
Gabor Krizsanits 2013-10-16 15:18:42 +02:00
parent 448be8c3cc
commit 142ec1922d
8 changed files with 60 additions and 5 deletions

View File

@ -3478,6 +3478,11 @@ nsDocument::doCreateShell(nsPresContext* aContext,
// Note: we don't hold a ref to the shell (it holds a ref to us)
mPresShell = shell;
// Make sure to never paint if we belong to an invisible DocShell.
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
if (docShell && docShell->IsInvisible())
shell->SetNeverPainting(true);
mExternalResourceMap.ShowViewers();
MaybeRescheduleAnimationFrameNotifications();

View File

@ -765,6 +765,7 @@ nsDocShell::nsDocShell():
mInEnsureScriptEnv(false),
#endif
mAffectPrivateSessionLifetime(true),
mInvisible(false),
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
mFrameType(eFrameTypeRegular),
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
@ -12801,3 +12802,15 @@ nsDocShell::HasUnloadedParent()
}
return false;
}
bool
nsDocShell::IsInvisible()
{
return mInvisible;
}
void
nsDocShell::SetInvisible(bool aInvisible)
{
mInvisible = aInvisible;
}

View File

@ -846,6 +846,7 @@ protected:
bool mInEnsureScriptEnv;
#endif
bool mAffectPrivateSessionLifetime;
bool mInvisible;
uint64_t mHistoryID;
uint32_t mDefaultLoadFlags;

View File

@ -43,7 +43,7 @@ interface nsIReflowObserver;
typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(4ca172c3-67bf-4e6d-89a3-cbfb929c370d)]
[scriptable, builtinclass, uuid(c0bb3b19-5448-4f4d-9366-cbcd4d7cdb96)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@ -922,4 +922,12 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
boolean isCommandEnabled(in string command);
void doCommand(in string command);
/**
* Invisible DocShell are dummy construct to simulate DOM windows
* without any actual visual representation. They have to be marked
* at construction time, to avoid any painting activity.
*/
[noscript, notxpcom] bool IsInvisible();
[noscript, notxpcom] void SetInvisible(in bool aIsInvisibleDochsell);
};

View File

@ -126,10 +126,10 @@ typedef struct CapturingContentInfo {
} CapturingContentInfo;
// d39cd4ce-6b38-4793-8c1a-00985c56d931
// f5b542a9-eaf0-4560-a656-37a9d379864c
#define NS_IPRESSHELL_IID \
{ 0xd39cd4ce, 0x6b38, 0x4793, \
{ 0x8c, 0x1a, 0x00, 0x98, 0x5c, 0x56, 0xd9, 0x31 } }
{ 0xf5b542a9, 0xeaf0, 0x4560, \
{ 0x37, 0xa9, 0xd3, 0x79, 0x86, 0x4c } }
// debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01
@ -1467,6 +1467,17 @@ public:
mReflowOnZoomPending = false;
}
/**
* Documents belonging to an invisible DocShell must not be painted ever.
*/
bool IsNeverPainting() {
return mIsNeverPainting;
}
void SetNeverPainting(bool aNeverPainting) {
mIsNeverPainting = aNeverPainting;
}
protected:
friend class nsRefreshDriver;
@ -1588,6 +1599,11 @@ protected:
// The maximum width of a line box. Text on a single line that exceeds this
// width will be wrapped. A value of 0 indicates that no limit is enforced.
nscoord mMaxLineBoxWidth;
// If a document belongs to an invisible DocShell, this flag must be set
// to true, so we can avoid any paint calls for widget related to this
// presshell.
bool mIsNeverPainting;
};
#endif /* nsIPresShell_h___ */

View File

@ -7424,7 +7424,7 @@ PresShell::GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
bool
PresShell::ShouldIgnoreInvalidation()
{
return mPaintingSuppressed || !mIsActive;
return mPaintingSuppressed || !mIsActive || mIsNeverPainting;
}
void

View File

@ -295,6 +295,10 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion)
{
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
if (mPresShell && mPresShell->IsNeverPainting()) {
return;
}
// damageRegion is the damaged area, in twips, relative to the view origin
nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
// move region from widget coordinates into view coordinates
@ -370,6 +374,10 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
return;
}
if (mPresShell && mPresShell->IsNeverPainting()) {
return;
}
if (aView->HasWidget()) {
aView->ResetWidgetBounds(false, true);
}
@ -415,6 +423,7 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
printf("---- PAINT END ----\n");
}
#endif
aView->SetForcedRepaint(false);
SetPainting(false);
FlushDirtyRegionToWidget(aView);

View File

@ -395,6 +395,9 @@ nsAppShellService::CreateWindowlessBrowser(bool aIsChrome, nsIWebNavigation **aR
nsISupports *isstub = NS_ISUPPORTS_CAST(nsIWebBrowserChrome2*, stub);
nsRefPtr<nsIWebNavigation> result = new WindowlessBrowserStub(browser, isstub);
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(result);
docshell->SetInvisible(true);
result.forget(aResult);
return NS_OK;
}