diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 46f945e1696..db160d76b0a 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -99,6 +99,9 @@ #include "nsIUBidiUtils.h" #endif +#include "nsIFrame.h" +#include "nsIStyleContext.h" + static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID); static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); static NS_DEFINE_CID(kDocumentCharsetInfoCID, NS_DOCUMENTCHARSETINFO_CID); @@ -3019,13 +3022,33 @@ NS_IMETHODIMP nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) } } - // Stop any activity that may be happening in the old document before - // releasing it... - if (mContentViewer) { - mContentViewer->Stop(); - } + nscolor bgcolor = NS_RGBA(0, 0, 0, 0); + PRBool bgSet = PR_FALSE; if (mContentViewer) { + // Stop any activity that may be happening in the old document before + // releasing it... + mContentViewer->Stop(); + + // Try to extract the default background color from the old + // view manager, so we can use it for the next document. + nsCOMPtr docviewer = do_QueryInterface(mContentViewer); + + if (docviewer) { + nsCOMPtr shell; + docviewer->GetPresShell(*getter_AddRefs(shell)); + + if (shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + + if (vm) { + vm->GetDefaultBackgroundColor(&bgcolor); + bgSet = PR_TRUE; + } + } + } + mContentViewer->Destroy(); mContentViewer = nsnull; } @@ -3056,6 +3079,26 @@ NS_IMETHODIMP nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) return NS_ERROR_FAILURE; } + if (bgSet) { + // Stuff the bgcolor from the last view manager into the new + // view manager. This improves page load continuity. + nsCOMPtr docviewer = do_QueryInterface(mContentViewer); + + if (docviewer) { + nsCOMPtr shell; + docviewer->GetPresShell(*getter_AddRefs(shell)); + + if (shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + + if (vm) { + vm->SetDefaultBackgroundColor(bgcolor); + } + } + } + } + #ifdef IBMBIDI if (newViewer) { // set the old state onto the new content viewer diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 39473fea05c..407cba19903 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -3984,6 +3984,28 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext) return PR_FALSE; } +void +nsFrame::SetDefaultBackgroundColor(nsIPresContext* aPresContext) +{ + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + + if (shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + + if (vm) { + nsStyleColor color; + mStyleContext->GetStyle(eStyleStruct_Color, color); + + vm->SetDefaultBackgroundColor( + (color.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) == 0 + ? color.mBackgroundColor + : NS_RGBA(0, 0, 0, 0)); + } + } +} + #ifdef IBMBIDI /** * retrieve Bidi property of this frame diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index 93dbb1cc0dd..225c23502c9 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -464,6 +464,10 @@ protected: static void XMLQuote(nsString& aString); + // Helper function that sets the view manager's default background to be + // the background of this frame. + void SetDefaultBackgroundColor(nsIPresContext* aPresContext); + virtual PRBool ParentDisablesSelection() const; // Set the overflow clip rect into the rendering-context. Used for block-level diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp index cdcb4912c11..1f795edd988 100644 --- a/mozilla/layout/generic/nsHTMLFrame.cpp +++ b/mozilla/layout/generic/nsHTMLFrame.cpp @@ -85,6 +85,11 @@ public: return NS_OK; } + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + /** * Get the "type" of the frame * @@ -220,6 +225,18 @@ CanvasFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +CanvasFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + SetDefaultBackgroundColor(aPresContext); + } + return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + NS_IMETHODIMP CanvasFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 39473fea05c..407cba19903 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -3984,6 +3984,28 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext) return PR_FALSE; } +void +nsFrame::SetDefaultBackgroundColor(nsIPresContext* aPresContext) +{ + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + + if (shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + + if (vm) { + nsStyleColor color; + mStyleContext->GetStyle(eStyleStruct_Color, color); + + vm->SetDefaultBackgroundColor( + (color.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) == 0 + ? color.mBackgroundColor + : NS_RGBA(0, 0, 0, 0)); + } + } +} + #ifdef IBMBIDI /** * retrieve Bidi property of this frame diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index 93dbb1cc0dd..225c23502c9 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -464,6 +464,10 @@ protected: static void XMLQuote(nsString& aString); + // Helper function that sets the view manager's default background to be + // the background of this frame. + void SetDefaultBackgroundColor(nsIPresContext* aPresContext); + virtual PRBool ParentDisablesSelection() const; // Set the overflow clip rect into the rendering-context. Used for block-level diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp index cdcb4912c11..1f795edd988 100644 --- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp @@ -85,6 +85,11 @@ public: return NS_OK; } + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + /** * Get the "type" of the frame * @@ -220,6 +225,18 @@ CanvasFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +CanvasFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + SetDefaultBackgroundColor(aPresContext); + } + return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + NS_IMETHODIMP CanvasFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index d1b2aefc1dc..1ce6c618eec 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -1302,6 +1302,15 @@ nsBoxFrame::Paint(nsIPresContext* aPresContext, nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, *outline, mStyleContext, 0); + // See if we need to cache the background color + nsIFrame* parent = nsnull; + GetParent(&parent); + nsIAtom* parentType = nsnull; + parent->GetFrameType(&parentType); + if (nsLayoutAtoms::rootFrame == parentType) { + SetDefaultBackgroundColor(aPresContext); + } + // The sole purpose of this is to trigger display // of the selection window for Named Anchors, // which don't have any children and normally don't diff --git a/mozilla/view/public/nsIViewManager.h b/mozilla/view/public/nsIViewManager.h index a2cffb9a4f2..dc55eb12708 100644 --- a/mozilla/view/public/nsIViewManager.h +++ b/mozilla/view/public/nsIViewManager.h @@ -511,6 +511,21 @@ public: NS_IMETHOD FlushPendingInvalidates()=0; + /** + * Set the default background color that the view manager should use + * to paint otherwise unowned areas. If the color isn't known, just set + * it to zero (which means 'transparent' since the color is RGBA). + * + * @param aColor the default background color + */ + NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor)=0; + + /** + * Retrieve the default background color. + * + * @param aColor the default background color + */ + NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor)=0; }; //when the refresh happens, should it be double buffered? diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index c3cf00e7657..4cb2928844e 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -423,6 +423,7 @@ nsViewManager::nsViewManager() mX = 0; mY = 0; mCachingWidgetChanges = 0; + mDefaultBackgroundColor = NS_RGBA(0, 0, 0, 0); mAllowDoubleBuffering = PR_TRUE; mHasPendingInvalidates = PR_FALSE; mPendingInvalidateEvent = PR_FALSE; @@ -947,6 +948,35 @@ void nsViewManager::Refresh(nsIView *aView, nsIRenderingContext *aContext, const #endif } +void nsViewManager::DefaultRefresh(nsIView* aView, const nsRect* aRect) +{ + nsCOMPtr widget; + GetWidgetForView(aView, getter_AddRefs(widget)); + if (! widget) + return; + + nsCOMPtr context + = getter_AddRefs(CreateRenderingContext(*aView)); + + if (! context) + return; + + nscolor bgcolor = mDefaultBackgroundColor; + + if (NS_GET_A(mDefaultBackgroundColor) == 0) { + // If we haven't been given a default bgcolor, then use the + // widget's bgcolor. + nsCOMPtr widget; + GetWidgetForView(aView, getter_AddRefs(widget)); + + if (widget) + bgcolor = widget->GetBackgroundColor(); + } + + context->SetColor(bgcolor); + context->FillRect(*aRect); +} + // Perform a *stable* sort of the buffer by increasing Z-index. The common case is // when many or all z-indices are equal and the list is mostly sorted; make sure // that's fast (should be linear time if all z-indices are equal). @@ -1930,28 +1960,14 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS Refresh(view, ((nsPaintEvent*)aEvent)->renderingContext, &damrect, updateFlags); } else { - // since we got an NS_PAINT event we need to draw something so we don't get blank areas. - nsCOMPtr widget; - GetWidgetForView(view, getter_AddRefs(widget)); - if (widget) { - nsCOMPtr context; - context = getter_AddRefs(CreateRenderingContext(*view)); - if (context) { - nscolor bgColor = 0; - SystemAttrStruct info; - info.mColor = &bgColor; - mContext->GetSystemAttribute(eSystemAttr_Color_WindowBackground, &info); - context->SetColor(bgColor); - context->FillRect(damrect); - } + // since we got an NS_PAINT event, we need to + // draw something so we don't get blank areas. + DefaultRefresh(view, &damrect); } } } } - *aStatus = nsEventStatus_eConsumeNoDefault; - } - break; } @@ -3833,4 +3849,16 @@ nsViewManager::ProcessWidgetChanges(nsIView* aView) return NS_OK; } +NS_IMETHODIMP +nsViewManager::SetDefaultBackgroundColor(nscolor aColor) +{ + mDefaultBackgroundColor = aColor; + return NS_OK; +} +NS_IMETHODIMP +nsViewManager::GetDefaultBackgroundColor(nscolor* aColor) +{ + *aColor = mDefaultBackgroundColor; + return NS_OK; +} diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index 4a6498959bb..85050c0fbee 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -154,6 +154,8 @@ public: NS_IMETHOD AllowDoubleBuffering(PRBool aDoubleBuffer); NS_IMETHOD IsPainting(PRBool& aIsPainting); NS_IMETHOD FlushPendingInvalidates(); + NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor); + NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor); nsresult ProcessInvalidateEvent(); static PRInt32 GetViewManagerCount(); static const nsVoidArray* GetViewManagerArray(); @@ -175,6 +177,7 @@ private: nsIRegion *region, PRUint32 aUpdateFlags); void Refresh(nsIView* aView, nsIRenderingContext *aContext, const nsRect *rect, PRUint32 aUpdateFlags); + void DefaultRefresh(nsIView* aView, const nsRect* aRect); void RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult); @@ -327,6 +330,7 @@ private: nsRect mTranslucentArea; // bounding box of all translucent views. nsIScrollableView *mRootScrollable; PRInt32 mCachingWidgetChanges; + nscolor mDefaultBackgroundColor; nsHashtable mMapPlaceholderViewToZTreeNode; diff --git a/mozilla/view/src/nsViewManager2.cpp b/mozilla/view/src/nsViewManager2.cpp index 8a901a1096f..6516839e2bb 100755 --- a/mozilla/view/src/nsViewManager2.cpp +++ b/mozilla/view/src/nsViewManager2.cpp @@ -2967,4 +2967,15 @@ nsViewManager2::ProcessWidgetChanges(nsIView* aView) return NS_OK; } +NS_IMETHODIMP +nsViewManager2::SetDefaultBackgroundColor(nscolor aColor) +{ + return NS_OK; +} +NS_IMETHODIMP +nsViewManager2::GetDefaultBackgroundColor(nscolor* aColor) +{ + *aColor = 0; + return NS_OK; +} diff --git a/mozilla/view/src/nsViewManager2.h b/mozilla/view/src/nsViewManager2.h index 1ea50abe655..9e9d0100a13 100755 --- a/mozilla/view/src/nsViewManager2.h +++ b/mozilla/view/src/nsViewManager2.h @@ -151,6 +151,8 @@ public: NS_IMETHOD AllowDoubleBuffering(PRBool aDoubleBuffer); NS_IMETHOD IsPainting(PRBool& aIsPainting); NS_IMETHOD FlushPendingInvalidates(); + NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor); + NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor); nsresult ProcessInvalidateEvent(); static PRInt32 GetViewManagerCount(); static const nsVoidArray* GetViewManagerArray();