mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 113232. Make 'background:transparent' work on top-level XUL windows. r=pavlov,kmcclusk,bzbarsky,sr=bzbarsky
This commit is contained in:
parent
3dace14ed6
commit
4f81dc78d1
@ -100,7 +100,7 @@ public:
|
||||
GetAlphas computes an array of alpha values for a rectangle of pixels, using
|
||||
the drawn-onto-black and the drawn-onto-white images. The pixels are
|
||||
returned in a new'ed array of aRect.width*aRect.height elements, in row-major
|
||||
order. This array must be freed by the caller.
|
||||
order. This array must be freed by the caller with delete[].
|
||||
*/
|
||||
NS_IMETHOD GetAlphas(const nsRect& aRect, nsDrawingSurface aBlack,
|
||||
nsDrawingSurface aWhite, PRUint8** aAlphas) = 0;
|
||||
|
@ -2610,14 +2610,32 @@ nsCSSRendering::FindNonTransparentBackground(nsStyleContext* aContext,
|
||||
* canvas.
|
||||
*/
|
||||
|
||||
inline PRBool
|
||||
IsCanvasFrame(nsIFrame *aFrame)
|
||||
// Returns nsnull if aFrame is not a canvas frame.
|
||||
// Otherwise, it returns the frame we should look for the background on.
|
||||
// This is normally aFrame but if aFrame is the viewport, we need to
|
||||
// look for the background starting at the scroll root (which shares
|
||||
// style context with the document root) or the document root itself.
|
||||
// We need to treat the viewport as canvas because, even though
|
||||
// it does not actually paint a background, we need to get the right
|
||||
// background style so we correctly detect transparent documents.
|
||||
inline nsIFrame*
|
||||
IsCanvasFrame(nsIPresContext* aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
return (frameType == nsLayoutAtoms::canvasFrame ||
|
||||
frameType == nsLayoutAtoms::rootFrame ||
|
||||
frameType == nsLayoutAtoms::pageFrame);
|
||||
if (frameType == nsLayoutAtoms::canvasFrame ||
|
||||
frameType == nsLayoutAtoms::rootFrame ||
|
||||
frameType == nsLayoutAtoms::pageFrame) {
|
||||
return aFrame;
|
||||
} else if (frameType == nsLayoutAtoms::viewportFrame) {
|
||||
nsIFrame* firstChild;
|
||||
aFrame->FirstChild(aPresContext, nsnull, &firstChild);
|
||||
if (firstChild) {
|
||||
return firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
@ -2714,7 +2732,7 @@ FindElementBackground(nsIPresContext* aPresContext,
|
||||
nsIFrame *parentFrame;
|
||||
aForFrame->GetParent(&parentFrame);
|
||||
// XXXldb We shouldn't have to null-check |parentFrame| here.
|
||||
if (parentFrame && IsCanvasFrame(parentFrame)) {
|
||||
if (parentFrame && IsCanvasFrame(aPresContext, parentFrame) == parentFrame) {
|
||||
// Check that we're really the root (rather than in another child list).
|
||||
nsIFrame *childFrame;
|
||||
parentFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
||||
@ -2756,10 +2774,10 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext,
|
||||
const nsStyleBackground** aBackground,
|
||||
PRBool* aIsCanvas)
|
||||
{
|
||||
PRBool isCanvas = IsCanvasFrame(aForFrame);
|
||||
*aIsCanvas = isCanvas;
|
||||
return isCanvas
|
||||
? FindCanvasBackground(aPresContext, aForFrame, aBackground)
|
||||
nsIFrame* canvasFrame = IsCanvasFrame(aPresContext, aForFrame);
|
||||
*aIsCanvas = canvasFrame != nsnull;
|
||||
return canvasFrame
|
||||
? FindCanvasBackground(aPresContext, canvasFrame, aBackground)
|
||||
: FindElementBackground(aPresContext, aForFrame, aBackground);
|
||||
}
|
||||
|
||||
@ -2831,11 +2849,21 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext,
|
||||
vm->GetRootView(rootView);
|
||||
nsIView* rootParent;
|
||||
rootView->GetParent(rootParent);
|
||||
if (nsnull == rootParent) {
|
||||
// Ensure that we always paint a color for the root (in case there's
|
||||
// no background at all or a partly transparent image).
|
||||
canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
|
||||
aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor);
|
||||
if (!rootParent) {
|
||||
PRBool widgetIsTranslucent = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
rootView->GetWidget(*getter_AddRefs(rootWidget));
|
||||
if (rootWidget) {
|
||||
rootWidget->GetWindowTranslucency(widgetIsTranslucent);
|
||||
}
|
||||
|
||||
if (!widgetIsTranslucent) {
|
||||
// Ensure that we always paint a color for the root (in case there's
|
||||
// no background at all or a partly transparent image).
|
||||
canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
|
||||
aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsStyleContext.h"
|
||||
@ -558,15 +559,41 @@ SyncFrameViewGeometryDependentProperties(nsIPresContext* aPresContext,
|
||||
(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) ||
|
||||
!aFrame->CanPaintBackground() ||
|
||||
HasNonZeroBorderRadius(aStyleContext);
|
||||
if (isCanvas && viewHasTransparentContent) {
|
||||
if (isCanvas) {
|
||||
nsIView* rootView;
|
||||
vm->GetRootView(rootView);
|
||||
nsIView* rootParent;
|
||||
rootView->GetParent(rootParent);
|
||||
if (nsnull == rootParent) {
|
||||
if (!rootParent) {
|
||||
viewHasTransparentContent = PR_FALSE;
|
||||
|
||||
// We need to set window translucency for top-level windows
|
||||
// which have transparent backgrounds
|
||||
if (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
shell->GetDocument(getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIDocument> parentDoc;
|
||||
doc->GetParentDocument(getter_AddRefs(parentDoc));
|
||||
if (!parentDoc) {
|
||||
// our document is the root of the doc tree, so we must
|
||||
// either be a top-level XUL window or something embedded.
|
||||
// The SetWindowTranslucency call will fail if we're embedded.
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
aView->GetWidget(*getter_AddRefs(widget));
|
||||
if (widget) {
|
||||
// Enable translucency in the widget
|
||||
widget->SetWindowTranslucency(PR_TRUE);
|
||||
viewHasTransparentContent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// XXX we should also set widget transparency for XUL popups that ask for it
|
||||
|
||||
const nsStyleDisplay* display;
|
||||
::GetStyleData(aStyleContext, &display);
|
||||
|
@ -2610,14 +2610,32 @@ nsCSSRendering::FindNonTransparentBackground(nsStyleContext* aContext,
|
||||
* canvas.
|
||||
*/
|
||||
|
||||
inline PRBool
|
||||
IsCanvasFrame(nsIFrame *aFrame)
|
||||
// Returns nsnull if aFrame is not a canvas frame.
|
||||
// Otherwise, it returns the frame we should look for the background on.
|
||||
// This is normally aFrame but if aFrame is the viewport, we need to
|
||||
// look for the background starting at the scroll root (which shares
|
||||
// style context with the document root) or the document root itself.
|
||||
// We need to treat the viewport as canvas because, even though
|
||||
// it does not actually paint a background, we need to get the right
|
||||
// background style so we correctly detect transparent documents.
|
||||
inline nsIFrame*
|
||||
IsCanvasFrame(nsIPresContext* aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
return (frameType == nsLayoutAtoms::canvasFrame ||
|
||||
frameType == nsLayoutAtoms::rootFrame ||
|
||||
frameType == nsLayoutAtoms::pageFrame);
|
||||
if (frameType == nsLayoutAtoms::canvasFrame ||
|
||||
frameType == nsLayoutAtoms::rootFrame ||
|
||||
frameType == nsLayoutAtoms::pageFrame) {
|
||||
return aFrame;
|
||||
} else if (frameType == nsLayoutAtoms::viewportFrame) {
|
||||
nsIFrame* firstChild;
|
||||
aFrame->FirstChild(aPresContext, nsnull, &firstChild);
|
||||
if (firstChild) {
|
||||
return firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
@ -2714,7 +2732,7 @@ FindElementBackground(nsIPresContext* aPresContext,
|
||||
nsIFrame *parentFrame;
|
||||
aForFrame->GetParent(&parentFrame);
|
||||
// XXXldb We shouldn't have to null-check |parentFrame| here.
|
||||
if (parentFrame && IsCanvasFrame(parentFrame)) {
|
||||
if (parentFrame && IsCanvasFrame(aPresContext, parentFrame) == parentFrame) {
|
||||
// Check that we're really the root (rather than in another child list).
|
||||
nsIFrame *childFrame;
|
||||
parentFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
||||
@ -2756,10 +2774,10 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext,
|
||||
const nsStyleBackground** aBackground,
|
||||
PRBool* aIsCanvas)
|
||||
{
|
||||
PRBool isCanvas = IsCanvasFrame(aForFrame);
|
||||
*aIsCanvas = isCanvas;
|
||||
return isCanvas
|
||||
? FindCanvasBackground(aPresContext, aForFrame, aBackground)
|
||||
nsIFrame* canvasFrame = IsCanvasFrame(aPresContext, aForFrame);
|
||||
*aIsCanvas = canvasFrame != nsnull;
|
||||
return canvasFrame
|
||||
? FindCanvasBackground(aPresContext, canvasFrame, aBackground)
|
||||
: FindElementBackground(aPresContext, aForFrame, aBackground);
|
||||
}
|
||||
|
||||
@ -2831,11 +2849,21 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext,
|
||||
vm->GetRootView(rootView);
|
||||
nsIView* rootParent;
|
||||
rootView->GetParent(rootParent);
|
||||
if (nsnull == rootParent) {
|
||||
// Ensure that we always paint a color for the root (in case there's
|
||||
// no background at all or a partly transparent image).
|
||||
canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
|
||||
aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor);
|
||||
if (!rootParent) {
|
||||
PRBool widgetIsTranslucent = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
rootView->GetWidget(*getter_AddRefs(rootWidget));
|
||||
if (rootWidget) {
|
||||
rootWidget->GetWindowTranslucency(widgetIsTranslucent);
|
||||
}
|
||||
|
||||
if (!widgetIsTranslucent) {
|
||||
// Ensure that we always paint a color for the root (in case there's
|
||||
// no background at all or a partly transparent image).
|
||||
canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
|
||||
aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2769,6 +2769,8 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
||||
aWidth, aHeight);
|
||||
#endif
|
||||
|
||||
// ResizeTransparencyBitmap uses the old bounds, so pass it the new bounds
|
||||
// before we change the old bounds.
|
||||
ResizeTransparencyBitmap(aWidth, aHeight);
|
||||
|
||||
mBounds.width = aWidth;
|
||||
@ -4421,10 +4423,10 @@ NS_IMETHODIMP nsWindow::UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint
|
||||
|
||||
NS_ASSERTION(mIsTranslucent, "Window is not transparent");
|
||||
|
||||
if (mTransparencyBitmap == nsnull) {
|
||||
if (!mTransparencyBitmap) {
|
||||
PRInt32 size = ((mBounds.width+7)/8)*mBounds.height;
|
||||
mTransparencyBitmap = new gchar[size];
|
||||
if (mTransparencyBitmap == nsnull)
|
||||
if (!mTransparencyBitmap)
|
||||
return NS_ERROR_FAILURE;
|
||||
memset(mTransparencyBitmap, 255, size);
|
||||
}
|
||||
|
@ -874,6 +874,7 @@ void nsXULWindow::OnChromeLoaded()
|
||||
LoadSizeStateFromXUL();
|
||||
|
||||
//LoadContentAreas();
|
||||
LoadChromeHidingFromXUL();
|
||||
|
||||
if (mCenterAfterLoad && !positionSet)
|
||||
Center(parentWindow, parentWindow ? PR_FALSE : PR_TRUE, PR_FALSE);
|
||||
@ -883,6 +884,25 @@ void nsXULWindow::OnChromeLoaded()
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsXULWindow::LoadChromeHidingFromXUL()
|
||||
{
|
||||
NS_ENSURE_STATE(mWindow);
|
||||
|
||||
// Get <window> element.
|
||||
nsCOMPtr<nsIDOMElement> windowElement;
|
||||
GetWindowDOMElement(getter_AddRefs(windowElement));
|
||||
NS_ENSURE_TRUE(windowElement, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString attr;
|
||||
nsresult rv = windowElement->GetAttribute(NS_LITERAL_STRING("hidechrome"), attr);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && attr.EqualsIgnoreCase("true")) {
|
||||
mWindow->HideWindowChrome(PR_TRUE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsXULWindow::LoadPositionFromXUL()
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -80,6 +80,7 @@ protected:
|
||||
PRBool LoadPositionFromXUL();
|
||||
PRBool LoadSizeFromXUL();
|
||||
PRBool LoadSizeStateFromXUL();
|
||||
nsresult LoadChromeHidingFromXUL();
|
||||
NS_IMETHOD LoadTitleFromXUL();
|
||||
NS_IMETHOD LoadWindowClassFromXUL();
|
||||
NS_IMETHOD LoadIconFromXUL();
|
||||
|
Loading…
Reference in New Issue
Block a user