Bug 622328 - Fixup widget's UpdateTransparentRegion now that layout's transparent region includes all content. r=roc, a=blocking.

This commit is contained in:
Jim Mathies 2011-01-27 16:58:58 -06:00
parent b918e3ca62
commit fdb11b0950
4 changed files with 61 additions and 62 deletions

View File

@ -1538,18 +1538,15 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
NS_WARNING("Flushing retained layers!");
flags |= nsDisplayList::PAINT_FLUSH_LAYERS;
} else if (widget && !(aFlags & PAINT_DOCUMENT_RELATIVE)) {
// XXX we should simplify this API now that dirtyWindowRegion always
// covers the entire window
nsIWidget_MOZILLA_2_0_BRANCH* widget2 =
static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget);
PRInt32 pixelRatio = presContext->AppUnitsPerDevPixel();
nsIntRegion visibleWindowRegion(visibleRegion.ToOutsidePixels(pixelRatio));
nsIntRegion dirtyWindowRegion(aDirtyRegion.ToOutsidePixels(pixelRatio));
builder.SetFinalTransparentRegion(visibleRegion);
widget->UpdatePossiblyTransparentRegion(dirtyWindowRegion, visibleWindowRegion);
widget2->UpdateTransparentRegion(visibleWindowRegion);
// If we're finished building display list items for painting of the outermost
// pres shell, notify the widget about any toolbars we've encountered.
nsIWidget_MOZILLA_2_0_BRANCH* widget2 =
static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget);
widget2->UpdateThemeGeometries(builder.GetThemeGeometries());
}
}

View File

@ -123,10 +123,10 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
{ 0xcc443f0b, 0xaf39, 0x415d, \
{ 0x9c, 0x4b, 0x7e, 0x06, 0xea, 0xa8, 0xb1, 0x3b } }
// d64532e0-03d6-421c-8e63-da2cff624825
// {8FC2D005-5359-4dbf-ACB1-701992FB4617}
#define NS_IWIDGET_MOZILLA_2_0_BRANCH_IID \
{ 0xd64532e0, 0x03d6, 0x421c, \
{ 0x8e, 0x63, 0xda, 0x2c, 0xff, 0x62, 0x48, 0x25 } }
{ 0x8fc2d005, 0x5359, 0x4dbf, \
{ 0xac, 0xb1, 0x70, 0x19, 0x92, 0xfb, 0x46, 0x17 } }
/*
* Window shadow styles
@ -791,11 +791,7 @@ class nsIWidget : public nsISupports {
virtual nsTransparencyMode GetTransparencyMode() = 0;
/**
* Updates a region of the window that might not have opaque content drawn. Widgets should
* assume that the initial possibly transparent region is empty.
*
* @param aDirtyRegion the region of the window that aMaybeTransparentRegion pertains to
* @param aPossiblyTransparentRegion the region of the window that is possibly transparent
* depreciated, see 2.0 interface.
*/
virtual void UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
const nsIntRegion &aPossiblyTransparentRegion) {};
@ -1434,6 +1430,16 @@ class nsIWidget_MOZILLA_2_0_BRANCH : public nsIWidget {
* paint anything.
*/
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) = 0;
/**
* Informs the widget about the region of the window that is partially
* transparent. Widgets should assume that the initial transparent
* region is empty.
*
* @param aTransparentRegion the region of the window that is partially
* transparent.
*/
virtual void UpdateTransparentRegion(const nsIntRegion &aTransparentRegion) {};
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget_MOZILLA_2_0_BRANCH, NS_IWIDGET_MOZILLA_2_0_BRANCH_IID)

View File

@ -376,6 +376,10 @@ static const int MIN_OPAQUE_RECT_HEIGHT_FOR_GLASS_MARGINS = 50;
// Windows' glaze effect will start to look stupid.
static const int MAX_HORIZONTAL_GLASS_MARGIN = 5;
// 2 pixel offset for eTransparencyBorderlessGlass which equals
// the size of the default window border Windows paints.
static const PRInt32 kGlassMarginAdjustment = 2;
/**************************************************************
**************************************************************
**
@ -2557,63 +2561,66 @@ void nsWindow::SetTransparencyMode(nsTransparencyMode aMode)
GetTopLevelWindow(PR_TRUE)->SetWindowTranslucencyInner(aMode);
}
static const PRInt32 kGlassMarginAdjustment = 2;
static const nsIntRegion
RegionFromArray(const nsTArray<nsIntRect>& aRects)
{
nsIntRegion region;
for (PRUint32 i = 0; i < aRects.Length(); ++i) {
region.Or(region, aRects[i]);
}
return region;
}
void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
const nsIntRegion &aPossiblyTransparentRegion) {
void nsWindow::UpdateTransparentRegion(const nsIntRegion &aTransparentRegion)
{
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
if (!HasGlass())
if (!HasGlass() || GetParent())
return;
HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE);
nsWindow* topWindow = GetNSWindowPtr(hWnd);
if (GetParent())
return;
mPossiblyTransparentRegion.Sub(mPossiblyTransparentRegion, aDirtyRegion);
mPossiblyTransparentRegion.Or(mPossiblyTransparentRegion, aPossiblyTransparentRegion);
nsIntRect clientBounds;
topWindow->GetClientBounds(clientBounds);
GetClientBounds(clientBounds);
// calculate the known fully opaque region by subtracting the transparent
// areas from client bounds. We'll use this to calculate our new glass
// bounds.
nsIntRegion opaqueRegion;
opaqueRegion.Sub(clientBounds, mPossiblyTransparentRegion);
MARGINS margins = { 0, 0, 0, 0 };
DWORD_PTR dwStyle = ::GetWindowLongPtrW(hWnd, GWL_STYLE);
opaqueRegion.Sub(clientBounds, aTransparentRegion);
// If there is no opaque region or hidechrome=true, set margins
// to support a full sheet of glass.
// Comments in MSDN indicate all values must be set to -1 to get a full
// sheet of glass.
margins.cxLeftWidth = margins.cxRightWidth =
margins.cyTopHeight = margins.cyBottomHeight = -1;
// to support a full sheet of glass. Comments in MSDN indicate
// all values must be set to -1 to get a full sheet of glass.
MARGINS margins = { -1, -1, -1, -1 };
bool visiblePlugin = false;
if (!opaqueRegion.IsEmpty() && !mHideChrome) {
nsIntRect pluginBounds;
for (nsIWidget* child = GetFirstChild(); child; child = child->GetNextSibling()) {
nsWindowType type;
child->GetWindowType(type);
if (type == eWindowType_plugin) {
// Collect the bounds of all plugins for GetLargestRectangle.
nsIntRect childBounds;
child->GetBounds(childBounds);
if (mTransparencyMode == eTransparencyBorderlessGlass) {
// We shrink the margins by kGlassMarginAdjustment in UpdateGlass.
// So here, try to ensure that the shrunk margin will still contain
// the plugin bounds. Of course there's no guarantee that we'll
// find an opaque rectangle including this enlarged area, for example
// if the plugin is already at the edge of the window.
childBounds.Inflate(kGlassMarginAdjustment, kGlassMarginAdjustment);
}
pluginBounds.UnionRect(pluginBounds, childBounds);
// Detect if any region of a plugin is visible.
nsTArray<nsIntRect> currentRects;
child->GetWindowClipRegion(&currentRects);
nsIntRegion currentClipRegion = RegionFromArray(currentRects);
nsIntRect bounds = currentClipRegion.GetBounds();
if (!bounds.IsEmpty()) {
visiblePlugin = true;
}
}
}
// Find the largest rectangle and use that to calculate the inset. Our top
// priority is to include the bounds of all plugins.
// Also don't let MIN_OPAQUE_RECT_HEIGHT_FOR_GLASS_MARGINS override content
// that contains a visible plugin since glass over plugins looks bad.
nsIntRect largest = opaqueRegion.GetLargestRectangle(pluginBounds);
if (largest.x <= MAX_HORIZONTAL_GLASS_MARGIN &&
clientBounds.width - largest.XMost() <= MAX_HORIZONTAL_GLASS_MARGIN &&
largest.height >= MIN_OPAQUE_RECT_HEIGHT_FOR_GLASS_MARGINS) {
if (visiblePlugin ||
(largest.x <= MAX_HORIZONTAL_GLASS_MARGIN &&
clientBounds.width - largest.XMost() <= MAX_HORIZONTAL_GLASS_MARGIN &&
largest.height >= MIN_OPAQUE_RECT_HEIGHT_FOR_GLASS_MARGINS)) {
margins.cxLeftWidth = largest.x;
margins.cxRightWidth = clientBounds.width - largest.XMost();
margins.cyBottomHeight = clientBounds.height - largest.YMost();
@ -2639,7 +2646,6 @@ void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
void nsWindow::UpdateGlass()
{
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE);
MARGINS margins = mGlassMargins;
// DWMNCRP_USEWINDOWSTYLE - The non-client rendering area is
@ -2675,8 +2681,8 @@ void nsWindow::UpdateGlass()
// Extends the window frame behind the client area
if(nsUXThemeData::CheckForCompositor()) {
nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &margins);
nsUXThemeData::dwmSetWindowAttributePtr(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy);
nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(mWnd, &margins);
nsUXThemeData::dwmSetWindowAttributePtr(mWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy);
}
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
}
@ -7312,16 +7318,6 @@ CreateHRGNFromArray(const nsTArray<nsIntRect>& aRects)
return ::ExtCreateRegion(NULL, buf.Length(), data);
}
static const nsIntRegion
RegionFromArray(const nsTArray<nsIntRect>& aRects)
{
nsIntRegion region;
for (PRUint32 i = 0; i < aRects.Length(); ++i) {
region.Or(region, aRects[i]);
}
return region;
}
static const nsTArray<nsIntRect>
ArrayFromRegion(const nsIntRegion& aRegion)
{

View File

@ -196,7 +196,7 @@ public:
#ifdef MOZ_XUL
virtual void SetTransparencyMode(nsTransparencyMode aMode);
virtual nsTransparencyMode GetTransparencyMode();
virtual void UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion, const nsIntRegion& aPossiblyTransparentRegion);
virtual void UpdateTransparentRegion(const nsIntRegion& aTransparentRegion);
#endif // MOZ_XUL
#ifdef NS_ENABLE_TSF
NS_IMETHOD OnIMEFocusChange(PRBool aFocus);