Merge back out of changeset 93c7b23284b8 (Bug 545593) for causing Md oth failures on linux.

This commit is contained in:
Timothy Nikkel 2010-02-12 16:46:46 -06:00
commit cefd1df784
14 changed files with 226 additions and 33 deletions

View File

@ -1266,6 +1266,29 @@ nsContentSink::ScrollToRef()
} }
} }
nsresult
nsContentSink::RefreshIfEnabled(nsIViewManager* vm)
{
if (!vm) {
// vm might be null if the shell got Destroy() called already
return NS_OK;
}
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIContentViewer> contentViewer;
mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
PRBool enabled;
contentViewer->GetEnableRendering(&enabled);
if (enabled) {
vm->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
}
}
return NS_OK;
}
void void
nsContentSink::StartLayout(PRBool aIgnorePendingSheets) nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
{ {
@ -1308,6 +1331,9 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return; return;
} }
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
} }
// If the document we are loading has a reference or it is a // If the document we are loading has a reference or it is a

View File

@ -257,6 +257,7 @@ protected:
// Tries to scroll to the URI's named anchor. Once we've successfully // Tries to scroll to the URI's named anchor. Once we've successfully
// done that, further calls to this method will be ignored. // done that, further calls to this method will be ignored.
void ScrollToRef(); void ScrollToRef();
nsresult RefreshIfEnabled(nsIViewManager* vm);
// Start layout. If aIgnorePendingSheets is true, this will happen even if // Start layout. If aIgnorePendingSheets is true, this will happen even if
// we still have stylesheet loads pending. Otherwise, we'll wait until the // we still have stylesheet loads pending. Otherwise, we'll wait until the

View File

@ -283,6 +283,13 @@ nsMediaDocument::StartLayout()
nsRect visibleArea = shell->GetPresContext()->GetVisibleArea(); nsRect visibleArea = shell->GetPresContext()->GetVisibleArea();
nsresult rv = shell->InitialReflow(visibleArea.width, visibleArea.height); nsresult rv = shell->InitialReflow(visibleArea.width, visibleArea.height);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Now trigger a refresh. vm might be null if the presshell got
// Destroy() called already.
nsIViewManager* vm = shell->GetViewManager();
if (vm) {
vm->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
}
} }
return NS_OK; return NS_OK;

View File

@ -2034,7 +2034,29 @@ nsXULDocument::StartLayout(void)
if (! docShell) if (! docShell)
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
// Trigger a refresh before the call to InitialReflow(),
// because the view manager's UpdateView() function is
// dropping dirty rects if refresh is disabled rather than
// accumulating them until refresh is enabled and then
// triggering a repaint...
// XXXbz Is that still the case?
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsIViewManager* vm = shell->GetViewManager();
if (vm) {
nsCOMPtr<nsIContentViewer> contentViewer;
rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (NS_SUCCEEDED(rv) && (contentViewer != nsnull)) {
PRBool enabled;
contentViewer->GetEnableRendering(&enabled);
if (enabled) {
vm->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
}
}
}
// Don't try to call GetVisibleArea earlier than this --- the EnableRefresh call
// above can flush reflows, which can cause a parent document to be flushed,
// calling ResizeReflow on our document which does SetVisibleArea.
nsRect r = cx->GetVisibleArea(); nsRect r = cx->GetVisibleArea();
rv = shell->InitialReflow(r.width, r.height); rv = shell->InitialReflow(r.width, r.height);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@ -11420,6 +11420,20 @@ nsDocShell::StopDocumentLoad(void)
return NS_ERROR_DOCSHELL_REQUEST_REJECTED; return NS_ERROR_DOCSHELL_REQUEST_REJECTED;
} }
NS_IMETHODIMP
nsDocShell::SetRendering(PRBool aRender)
{
if(eCharsetReloadRequested != mCharsetReloadState)
{
if (mContentViewer) {
mContentViewer->SetEnableRendering(aRender);
return NS_OK;
}
}
//return failer if this request is not accepted due to mCharsetReloadState
return NS_ERROR_DOCSHELL_REQUEST_REJECTED;
}
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview) nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview)
{ {

View File

@ -15,7 +15,7 @@ struct nsIntRect;
[ptr] native nsIDocumentPtr(nsIDocument); [ptr] native nsIDocumentPtr(nsIDocument);
[ref] native nsIntRectRef(nsIntRect); [ref] native nsIntRectRef(nsIntRect);
[scriptable, uuid(e2e5dd7d-8140-4fc5-b2c3-3a3b4f946fc7)] [scriptable, uuid(c824ac5e-3d86-4ae5-9ccc-9433bdc43004)]
interface nsIContentViewer : nsISupports interface nsIContentViewer : nsISupports
{ {
@ -96,6 +96,8 @@ interface nsIContentViewer : nsISupports
void show(); void show();
void hide(); void hide();
attribute boolean enableRendering;
attribute boolean sticky; attribute boolean sticky;
/* /*

View File

@ -62,6 +62,7 @@ NS_IMETHODIMP nsMyObserver::Notify(
if(!mCharset.Equals(aCharset)) { if(!mCharset.Equals(aCharset)) {
if(mNotifyByReload) { if(mNotifyByReload) {
rv = mWebShellSvc->SetRendering( PR_FALSE);
rv = mWebShellSvc->StopDocumentLoad(); rv = mWebShellSvc->StopDocumentLoad();
rv = mWebShellSvc->ReloadDocument(aCharset, kCharsetFromAutoDetection); rv = mWebShellSvc->ReloadDocument(aCharset, kCharsetFromAutoDetection);
} else { } else {

View File

@ -35,6 +35,8 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
//#define DONT_INFORM_DOCSHELL
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIWebShellServices.h" #include "nsIWebShellServices.h"
#include "nsObserverBase.h" #include "nsObserverBase.h"
@ -65,16 +67,24 @@ NS_IMETHODIMP nsObserverBase::NotifyDocShell(nsISupports* aDocShell,
nsCOMPtr<nsIWebShellServices> wss; nsCOMPtr<nsIWebShellServices> wss;
wss = do_QueryInterface(aDocShell,&res); wss = do_QueryInterface(aDocShell,&res);
if (NS_SUCCEEDED(res)) { if (NS_SUCCEEDED(res)) {
#ifndef DONT_INFORM_DOCSHELL
// ask the webshellservice to load the URL // ask the webshellservice to load the URL
if (NS_FAILED(wss->StopDocumentLoad())){ if (NS_FAILED( res = wss->SetRendering(PR_FALSE) ))
// do nothing and fall through rv = res;
// XXX nisheeth, uncomment the following two line to see the reent problem
else if (NS_FAILED(res = wss->StopDocumentLoad())){
rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
} }
else if (NS_FAILED(wss->ReloadDocument(charset, source))) { else if (NS_FAILED(res = wss->ReloadDocument(charset, source))) {
// do nothing and fall through rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
} }
else { else {
rv = NS_ERROR_HTMLPARSER_STOPPARSING; // We're reloading a new document...stop loading the current. rv = NS_ERROR_HTMLPARSER_STOPPARSING; // We're reloading a new document...stop loading the current.
} }
#endif
} }
//if our reload request is not accepted, we should tell parser to go on //if our reload request is not accepted, we should tell parser to go on

View File

@ -385,8 +385,11 @@ private:
/** /**
* @param aDoInitialReflow set to true if you want to kick off the initial * @param aDoInitialReflow set to true if you want to kick off the initial
* reflow * reflow
* @param aReenableRefresh set to true if you want this to reenable refresh
* before returning; otherwise this will return with refresh disabled
* in the view manager
*/ */
nsresult InitPresentationStuff(PRBool aDoInitialReflow); nsresult InitPresentationStuff(PRBool aDoInitialReflow, PRBool aReenableRefresh);
nsresult GetPopupNode(nsIDOMNode** aNode); nsresult GetPopupNode(nsIDOMNode** aNode);
nsresult GetPopupLinkNode(nsIDOMNode** aNode); nsresult GetPopupLinkNode(nsIDOMNode** aNode);
@ -452,6 +455,7 @@ protected:
PRInt16 mNumURLStarts; PRInt16 mNumURLStarts;
PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy" PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy"
unsigned mEnableRendering : 1;
unsigned mStopped : 1; unsigned mStopped : 1;
unsigned mLoaded : 1; unsigned mLoaded : 1;
unsigned mDeferredWindowClose : 1; unsigned mDeferredWindowClose : 1;
@ -493,7 +497,6 @@ protected:
PRPackedBool mIsPageMode; PRPackedBool mIsPageMode;
PRPackedBool mCallerIsClosingWindow; PRPackedBool mCallerIsClosingWindow;
PRPackedBool mInitializedForPrintPreview; PRPackedBool mInitializedForPrintPreview;
PRPackedBool mHidden;
}; };
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -520,6 +523,7 @@ NS_NewDocumentViewer(nsIDocumentViewer** aResult)
void DocumentViewerImpl::PrepareToStartLoad() void DocumentViewerImpl::PrepareToStartLoad()
{ {
mEnableRendering = PR_TRUE;
mStopped = PR_FALSE; mStopped = PR_FALSE;
mLoaded = PR_FALSE; mLoaded = PR_FALSE;
mDeferredWindowClose = PR_FALSE; mDeferredWindowClose = PR_FALSE;
@ -554,8 +558,7 @@ DocumentViewerImpl::DocumentViewerImpl()
mPrintPreviewZoom(1.0), mPrintPreviewZoom(1.0),
#endif #endif
mHintCharsetSource(kCharsetUninitialized), mHintCharsetSource(kCharsetUninitialized),
mInitializedForPrintPreview(PR_FALSE), mInitializedForPrintPreview(PR_FALSE)
mHidden(PR_FALSE)
{ {
PrepareToStartLoad(); PrepareToStartLoad();
} }
@ -693,7 +696,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget,
} }
nsresult nsresult
DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow, PRBool aReenableRefresh)
{ {
if (GetIsPrintPreview()) if (GetIsPrintPreview())
return NS_OK; return NS_OK;
@ -736,6 +739,7 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow)
nscoord width = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.width; nscoord width = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.width;
nscoord height = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.height; nscoord height = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.height;
mViewManager->DisableRefresh();
mViewManager->SetWindowDimensions(width, height); mViewManager->SetWindowDimensions(width, height);
mPresContext->SetTextZoom(mTextZoom); mPresContext->SetTextZoom(mTextZoom);
mPresContext->SetFullZoom(mPageZoom); mPresContext->SetFullZoom(mPageZoom);
@ -757,6 +761,11 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow)
mPresContext->SetVisibleArea(nsRect(0, 0, width, height)); mPresContext->SetVisibleArea(nsRect(0, 0, width, height));
} }
// Now trigger a refresh
if (aReenableRefresh && mEnableRendering && mViewManager) {
mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
}
// now register ourselves as a selection listener, so that we get // now register ourselves as a selection listener, so that we get
// called when the selection changes in the window // called when the selection changes in the window
if (!mSelectionListener) { if (!mSelectionListener) {
@ -957,7 +966,7 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
// The ViewManager and Root View was created above (in // The ViewManager and Root View was created above (in
// MakeWindow())... // MakeWindow())...
rv = InitPresentationStuff(!makeCX); rv = InitPresentationStuff(!makeCX, !makeCX);
} }
return rv; return rv;
@ -1251,7 +1260,7 @@ DocumentViewerImpl::ResetCloseWindow()
NS_IMETHODIMP NS_IMETHODIMP
DocumentViewerImpl::PageHide(PRBool aIsUnload) DocumentViewerImpl::PageHide(PRBool aIsUnload)
{ {
mHidden = PR_TRUE; mEnableRendering = PR_FALSE;
if (!mDocument) { if (!mDocument) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
@ -1631,7 +1640,7 @@ DocumentViewerImpl::Stop(void)
mDocument->StopDocumentLoad(); mDocument->StopDocumentLoad();
} }
if (!mHidden && (mLoaded || mStopped) && mPresContext && !mSHEntry) if (mEnableRendering && (mLoaded || mStopped) && mPresContext && !mSHEntry)
mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode); mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
mStopped = PR_TRUE; mStopped = PR_TRUE;
@ -1746,7 +1755,10 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument)
mPresContext->SetLinkHandler(linkHandler); mPresContext->SetLinkHandler(linkHandler);
} }
rv = InitPresentationStuff(PR_FALSE); rv = InitPresentationStuff(PR_FALSE, PR_FALSE);
if (NS_SUCCEEDED(rv) && mEnableRendering && mViewManager) {
mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
}
} }
return rv; return rv;
@ -1973,7 +1985,8 @@ DocumentViewerImpl::Show(void)
if (mPresContext) { if (mPresContext) {
Hide(); Hide();
rv = InitPresentationStuff(mDocument->MayStartLayout()); rv = InitPresentationStuff(mDocument->MayStartLayout(),
mDocument->MayStartLayout());
} }
// If we get here the document load has already started and the // If we get here the document load has already started and the
@ -2041,6 +2054,26 @@ DocumentViewerImpl::Hide(void)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
DocumentViewerImpl::SetEnableRendering(PRBool aOn)
{
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
mEnableRendering = aOn;
if (mViewManager) {
if (aOn) {
mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
nsIView* view;
mViewManager->GetRootView(view); // views are not refCounted
if (view) {
mViewManager->UpdateView(view, NS_VMREFRESH_IMMEDIATE);
}
}
else {
mViewManager->DisableRefresh();
}
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
DocumentViewerImpl::GetSticky(PRBool *aSticky) DocumentViewerImpl::GetSticky(PRBool *aSticky)
@ -2058,6 +2091,17 @@ DocumentViewerImpl::SetSticky(PRBool aSticky)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
DocumentViewerImpl::GetEnableRendering(PRBool* aResult)
{
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
if (aResult) {
*aResult = mEnableRendering;
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
DocumentViewerImpl::RequestWindowClose(PRBool* aCanClose) DocumentViewerImpl::RequestWindowClose(PRBool* aCanClose)
{ {
@ -4202,6 +4246,10 @@ DocumentViewerImpl::ReturnToGalleyPresentation()
mPrintEngine->Destroy(); mPrintEngine->Destroy();
mPrintEngine = nsnull; mPrintEngine = nsnull;
if (mViewManager) {
mViewManager->EnableRefresh(NS_VMREFRESH_DEFERRED);
}
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer)); nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
ResetFocusState(docShell); ResetFocusState(docShell);
@ -4312,6 +4360,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetPageMode(PRBool aPageMode, nsIPrintSettings
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
InitInternal(mParentWidget, nsnull, mBounds, PR_TRUE, PR_FALSE, PR_FALSE); InitInternal(mParentWidget, nsnull, mBounds, PR_TRUE, PR_FALSE, PR_FALSE);
mViewManager->EnableRefresh(NS_VMREFRESH_NO_SYNC);
Show(); Show();
return NS_OK; return NS_OK;

View File

@ -600,17 +600,23 @@ nsHtml5TreeOpExecutor::NeedsCharsetSwitchTo(const char* aEncoding)
return; return;
} }
nsresult rv = NS_OK;
nsCOMPtr<nsIWebShellServices> wss = do_QueryInterface(mDocShell); nsCOMPtr<nsIWebShellServices> wss = do_QueryInterface(mDocShell);
if (!wss) { if (!wss) {
return; return;
} }
#ifndef DONT_INFORM_WEBSHELL
// ask the webshellservice to load the URL // ask the webshellservice to load the URL
if (NS_SUCCEEDED(wss->StopDocumentLoad())) { if (NS_FAILED(rv = wss->SetRendering(PR_FALSE))) {
wss->ReloadDocument(aEncoding, kCharsetFromMetaTag); // do nothing and fall thru
} else if (NS_FAILED(rv = wss->StopDocumentLoad())) {
rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
} else if (NS_FAILED(rv = wss->ReloadDocument(aEncoding, kCharsetFromMetaTag))) {
rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
} }
// if the charset switch was accepted, wss has called Terminate() on the // if the charset switch was accepted, wss has called Terminate() on the
// parser by now // parser by now
#endif
if (!mParser) { if (!mParser) {
// success // success

View File

@ -50,8 +50,8 @@ class nsIDeviceContext;
class nsIViewObserver; class nsIViewObserver;
#define NS_IVIEWMANAGER_IID \ #define NS_IVIEWMANAGER_IID \
{ 0xbbdd429c, 0x6542, 0x477a, \ { 0x6ca2fd1c, 0xa57e, 0x4802, \
{ 0xab, 0x48, 0x6c, 0xd6, 0xcb, 0xb8, 0xdf, 0x98 } } { 0xad, 0x55, 0x85, 0xf6, 0x6f, 0x4a, 0x2c, 0x04 } }
class nsIViewManager : public nsISupports class nsIViewManager : public nsISupports
{ {
@ -277,6 +277,23 @@ public:
*/ */
NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext) = 0; NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext) = 0;
/**
* prevent the view manager from refreshing.
* @return error status
*/
// XXXbz callers of this function don't seem to realize that it disables
// refresh for the entire view manager hierarchy.... Maybe it shouldn't do
// that?
NS_IMETHOD DisableRefresh(void) = 0;
/**
* allow the view manager to refresh. this may cause a synchronous
* paint to occur inside the call.
* @param aUpdateFlags see bottom of nsIViewManager.h for description
* @return error status
*/
NS_IMETHOD EnableRefresh(PRUint32 aUpdateFlags) = 0;
class NS_STACK_CLASS UpdateViewBatch { class NS_STACK_CLASS UpdateViewBatch {
public: public:
UpdateViewBatch() {} UpdateViewBatch() {}

View File

@ -256,6 +256,8 @@ NS_IMETHODIMP nsViewManager::Init(nsIDeviceContext* aContext)
} }
mContext = aContext; mContext = aContext;
mRefreshEnabled = PR_TRUE;
return NS_OK; return NS_OK;
} }
@ -519,7 +521,7 @@ void nsViewManager::ProcessPendingUpdates(nsView* aView, PRBool aDoInvalidate)
if (aDoInvalidate && aView->HasNonEmptyDirtyRegion()) { if (aDoInvalidate && aView->HasNonEmptyDirtyRegion()) {
// Push out updates after we've processed the children; ensures that // Push out updates after we've processed the children; ensures that
// damage is applied based on the final widget geometry // damage is applied based on the final widget geometry
NS_ASSERTION(IsRefreshEnabled(), "Cannot process pending updates with refresh disabled"); NS_ASSERTION(mRefreshEnabled, "Cannot process pending updates with refresh disabled");
nsRegion* dirtyRegion = aView->GetDirtyRegion(); nsRegion* dirtyRegion = aView->GetDirtyRegion();
if (dirtyRegion) { if (dirtyRegion) {
nsView* nearestViewWithWidget = aView; nsView* nearestViewWithWidget = aView;
@ -1597,15 +1599,29 @@ nsViewManager::CreateRenderingContext(nsView &aView)
return cx; return cx;
} }
void nsViewManager::TriggerRefresh(PRUint32 aUpdateFlags) NS_IMETHODIMP nsViewManager::DisableRefresh(void)
{ {
if (!IsRootVM()) { if (!IsRootVM()) {
RootViewManager()->TriggerRefresh(aUpdateFlags); return RootViewManager()->DisableRefresh();
return;
} }
if (mUpdateBatchCnt > 0) if (mUpdateBatchCnt > 0)
return; return NS_OK;
mRefreshEnabled = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsViewManager::EnableRefresh(PRUint32 aUpdateFlags)
{
if (!IsRootVM()) {
return RootViewManager()->EnableRefresh(aUpdateFlags);
}
if (mUpdateBatchCnt > 0)
return NS_OK;
mRefreshEnabled = PR_TRUE;
// nested batching can combine IMMEDIATE with DEFERRED. Favour // nested batching can combine IMMEDIATE with DEFERRED. Favour
// IMMEDIATE over DEFERRED and DEFERRED over NO_SYNC. We need to // IMMEDIATE over DEFERRED and DEFERRED over NO_SYNC. We need to
@ -1622,6 +1638,8 @@ void nsViewManager::TriggerRefresh(PRUint32 aUpdateFlags)
} else { // NO_SYNC } else { // NO_SYNC
FlushPendingInvalidates(); FlushPendingInvalidates();
} }
return NS_OK;
} }
nsIViewManager* nsViewManager::BeginUpdateViewBatch(void) nsIViewManager* nsViewManager::BeginUpdateViewBatch(void)
@ -1630,11 +1648,15 @@ nsIViewManager* nsViewManager::BeginUpdateViewBatch(void)
return RootViewManager()->BeginUpdateViewBatch(); return RootViewManager()->BeginUpdateViewBatch();
} }
nsresult result = NS_OK;
if (mUpdateBatchCnt == 0) { if (mUpdateBatchCnt == 0) {
mUpdateBatchFlags = 0; mUpdateBatchFlags = 0;
result = DisableRefresh();
} }
++mUpdateBatchCnt; if (NS_SUCCEEDED(result))
++mUpdateBatchCnt;
return this; return this;
} }
@ -1643,6 +1665,8 @@ NS_IMETHODIMP nsViewManager::EndUpdateViewBatch(PRUint32 aUpdateFlags)
{ {
NS_ASSERTION(IsRootVM(), "Should only be called on root"); NS_ASSERTION(IsRootVM(), "Should only be called on root");
nsresult result = NS_OK;
--mUpdateBatchCnt; --mUpdateBatchCnt;
NS_ASSERTION(mUpdateBatchCnt >= 0, "Invalid batch count!"); NS_ASSERTION(mUpdateBatchCnt >= 0, "Invalid batch count!");
@ -1655,10 +1679,10 @@ NS_IMETHODIMP nsViewManager::EndUpdateViewBatch(PRUint32 aUpdateFlags)
mUpdateBatchFlags |= aUpdateFlags; mUpdateBatchFlags |= aUpdateFlags;
if (mUpdateBatchCnt == 0) { if (mUpdateBatchCnt == 0) {
TriggerRefresh(mUpdateBatchFlags); result = EnableRefresh(mUpdateBatchFlags);
} }
return NS_OK; return result;
} }
NS_IMETHODIMP nsViewManager::GetRootWidget(nsIWidget **aWidget) NS_IMETHODIMP nsViewManager::GetRootWidget(nsIWidget **aWidget)
@ -1742,9 +1766,17 @@ nsViewManager::FlushPendingInvalidates()
// all of them together. We don't use // all of them together. We don't use
// BeginUpdateViewBatch/EndUpdateViewBatch, since that would reenter this // BeginUpdateViewBatch/EndUpdateViewBatch, since that would reenter this
// exact code, but we want the effect of a single big update batch. // exact code, but we want the effect of a single big update batch.
PRBool refreshEnabled = mRefreshEnabled;
mRefreshEnabled = PR_FALSE;
++mUpdateBatchCnt; ++mUpdateBatchCnt;
CallWillPaintOnObservers(); CallWillPaintOnObservers();
--mUpdateBatchCnt; --mUpdateBatchCnt;
// Someone could have called EnableRefresh on us from inside WillPaint().
// Only reset the old mRefreshEnabled value if the current value is false.
if (!mRefreshEnabled) {
mRefreshEnabled = refreshEnabled;
}
} }
if (mHasPendingUpdates) { if (mHasPendingUpdates) {

View File

@ -149,6 +149,9 @@ public:
NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext); NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext);
NS_IMETHOD DisableRefresh(void);
NS_IMETHOD EnableRefresh(PRUint32 aUpdateFlags);
virtual nsIViewManager* BeginUpdateViewBatch(void); virtual nsIViewManager* BeginUpdateViewBatch(void);
NS_IMETHOD EndUpdateViewBatch(PRUint32 aUpdateFlags); NS_IMETHOD EndUpdateViewBatch(PRUint32 aUpdateFlags);
@ -186,8 +189,6 @@ private:
void UpdateViews(nsView *aView, PRUint32 aUpdateFlags); void UpdateViews(nsView *aView, PRUint32 aUpdateFlags);
void TriggerRefresh(PRUint32 aUpdateFlags);
void Refresh(nsView *aView, nsIRenderingContext *aContext, void Refresh(nsView *aView, nsIRenderingContext *aContext,
nsIRegion *region, PRUint32 aUpdateFlags); nsIRegion *region, PRUint32 aUpdateFlags);
void RenderViews(nsView *aRootView, nsIRenderingContext& aRC, void RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
@ -275,7 +276,7 @@ public: // NOT in nsIViewManager, so private to the view module
nsresult CreateRegion(nsIRegion* *result); nsresult CreateRegion(nsIRegion* *result);
PRBool IsRefreshEnabled() { return RootViewManager()->mUpdateBatchCnt == 0; } PRBool IsRefreshEnabled() { return RootViewManager()->mRefreshEnabled; }
nsIViewObserver* GetViewObserver() { return mObserver; } nsIViewObserver* GetViewObserver() { return mObserver; }
@ -310,6 +311,8 @@ private:
PRInt32 mUpdateBatchCnt; PRInt32 mUpdateBatchCnt;
PRUint32 mUpdateBatchFlags; PRUint32 mUpdateBatchFlags;
PRInt32 mScrollCnt; PRInt32 mScrollCnt;
// Use IsRefreshEnabled() to check the value of mRefreshEnabled.
PRPackedBool mRefreshEnabled;
// Use IsPainting() and SetPainting() to access mPainting. // Use IsPainting() and SetPainting() to access mPainting.
PRPackedBool mPainting; PRPackedBool mPainting;
PRPackedBool mRecursiveRefreshPending; PRPackedBool mRecursiveRefreshPending;

View File

@ -42,9 +42,10 @@
// Interface ID for nsIWebShellServices // Interface ID for nsIWebShellServices
/* 0c628af0-5638-4703-8f99-ed6134c9de18 */ /* 8b26a346-031e-11d3-aeea-00108300ff91 */
#define NS_IWEB_SHELL_SERVICES_IID \ #define NS_IWEB_SHELL_SERVICES_IID \
{ 0x0c628af0, 0x5638, 0x4703, {0x8f, 0x99, 0xed, 0x61, 0x34, 0xc9, 0xde, 0x18} } { 0x8b26a346, 0x031e, 0x11d3, {0xae, 0xea, 0x00, 0x10, 0x83, 0x00, 0xff, 0x91} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -55,6 +56,7 @@ public:
NS_IMETHOD ReloadDocument(const char* aCharset = nsnull , NS_IMETHOD ReloadDocument(const char* aCharset = nsnull ,
PRInt32 aSource = kCharsetUninitialized) = 0; PRInt32 aSource = kCharsetUninitialized) = 0;
NS_IMETHOD StopDocumentLoad(void) = 0; NS_IMETHOD StopDocumentLoad(void) = 0;
NS_IMETHOD SetRendering(PRBool aRender) = 0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIWebShellServices, NS_IWEB_SHELL_SERVICES_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIWebShellServices, NS_IWEB_SHELL_SERVICES_IID)
@ -63,5 +65,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIWebShellServices, NS_IWEB_SHELL_SERVICES_IID)
#define NS_DECL_NSIWEBSHELLSERVICES \ #define NS_DECL_NSIWEBSHELLSERVICES \
NS_IMETHOD ReloadDocument(const char *aCharset=nsnull, PRInt32 aSource=kCharsetUninitialized); \ NS_IMETHOD ReloadDocument(const char *aCharset=nsnull, PRInt32 aSource=kCharsetUninitialized); \
NS_IMETHOD StopDocumentLoad(void); \ NS_IMETHOD StopDocumentLoad(void); \
NS_IMETHOD SetRendering(PRBool aRender);
#endif /* nsIWebShellServices_h___ */ #endif /* nsIWebShellServices_h___ */