mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 05:44:10 +00:00
Bug 450767 - Don't necessarily apply Aero Glass to the entire window r=jimm sr=roc
This commit is contained in:
parent
abc2950b98
commit
868b41f2d3
@ -42,6 +42,8 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
|
||||
class nsIntRegion;
|
||||
|
||||
/**
|
||||
* Implementation of regions.
|
||||
* A region is represented as circular double-linked list of nsRegion::RgnRect structures.
|
||||
@ -176,6 +178,7 @@ public:
|
||||
PRBool IsEqual (const nsRegion& aRegion) const;
|
||||
PRUint32 GetNumRects () const { return mRectCount; }
|
||||
const nsRect& GetBounds () const { return mBoundRect; }
|
||||
nsIntRegion ToOutsidePixels (nscoord aAppUnitsPerPixel) const;
|
||||
|
||||
/**
|
||||
* Make sure the region has at most aMaxRects by adding area to it
|
||||
|
@ -1288,6 +1288,17 @@ void nsRegion::MoveBy (nsPoint aPt)
|
||||
}
|
||||
}
|
||||
|
||||
nsIntRegion nsRegion::ToOutsidePixels(nscoord aAppUnitsPerPixel) const {
|
||||
nsIntRegion result;
|
||||
nsRegionRectIterator rgnIter(*this);
|
||||
const nsRect *currentRect;
|
||||
while (currentRect = rgnIter.Next()) {
|
||||
nsIntRect deviceRect = currentRect->ToOutsidePixels(aAppUnitsPerPixel);
|
||||
result.Or(result, deviceRect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsRegion::SimplifyOutward (PRUint32 aMaxRects)
|
||||
{
|
||||
NS_ASSERTION(aMaxRects >= 1, "Invalid max rect count");
|
||||
|
@ -1229,6 +1229,12 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
||||
PRUint32 flags = nsDisplayList::PAINT_DEFAULT;
|
||||
if (aFlags & PAINT_WIDGET_LAYERS) {
|
||||
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
|
||||
nsIWidget *widget = aFrame->GetWindow();
|
||||
PRInt32 pixelRatio = widget->GetDeviceContext()->AppUnitsPerDevPixel();
|
||||
nsIntRegion visibleWindowRegion(visibleRegion.ToOutsidePixels(pixelRatio));
|
||||
nsIntRegion dirtyWindowRegion(aDirtyRegion.ToOutsidePixels(pixelRatio));
|
||||
|
||||
widget->UpdatePossiblyTransparentRegion(dirtyWindowRegion, visibleWindowRegion);
|
||||
}
|
||||
list.Paint(&builder, aRenderingContext, flags);
|
||||
// Flush the list so we don't trigger the IsEmpty-on-destruction assertion
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsCoord.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
#include "prthread.h"
|
||||
#include "nsEvent.h"
|
||||
@ -588,6 +589,16 @@ 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
|
||||
*/
|
||||
virtual void UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
|
||||
const nsIntRegion &aPossiblyTransparentRegion) {};
|
||||
|
||||
/**
|
||||
* This represents a command to set the bounds and clip region of
|
||||
* a child widget.
|
||||
|
@ -37,6 +37,8 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef __UXThemeData_h__
|
||||
#define __UXThemeData_h__
|
||||
#include <windows.h>
|
||||
#include <uxtheme.h>
|
||||
|
||||
@ -190,3 +192,4 @@ public:
|
||||
}
|
||||
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
};
|
||||
#endif // __UXThemeData_h__
|
||||
|
@ -168,7 +168,6 @@
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
||||
#if !defined(WINCE)
|
||||
#include "nsUXThemeData.h"
|
||||
#include "nsUXThemeConstants.h"
|
||||
#include "nsKeyboardLayout.h"
|
||||
#include "nsNativeDragTarget.h"
|
||||
@ -400,6 +399,9 @@ nsWindow::nsWindow() : nsBaseWidget()
|
||||
mTransparentSurface = nsnull;
|
||||
mMemoryDC = nsnull;
|
||||
mTransparencyMode = eTransparencyOpaque;
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
memset(&mGlassMargins, 0, sizeof mGlassMargins);
|
||||
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
#endif
|
||||
mBackground = ::GetSysColor(COLOR_BTNFACE);
|
||||
mBrush = ::CreateSolidBrush(NSRGB_2_COLOREF(mBackground));
|
||||
@ -2017,6 +2019,66 @@ void nsWindow::SetTransparencyMode(nsTransparencyMode aMode)
|
||||
{
|
||||
GetTopLevelWindow(PR_TRUE)->SetWindowTranslucencyInner(aMode);
|
||||
}
|
||||
|
||||
void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
|
||||
const nsIntRegion &aPossiblyTransparentRegion) {
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
if (mTransparencyMode != eTransparencyGlass)
|
||||
return;
|
||||
|
||||
HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE);
|
||||
nsWindow* topWindow = GetNSWindowPtr(hWnd);
|
||||
|
||||
mPossiblyTransparentRegion.Sub(mPossiblyTransparentRegion, aDirtyRegion);
|
||||
mPossiblyTransparentRegion.Or(mPossiblyTransparentRegion, aPossiblyTransparentRegion);
|
||||
|
||||
nsIntRect clientBounds;
|
||||
topWindow->GetClientBounds(clientBounds);
|
||||
nsIntRegion opaqueRegion;
|
||||
opaqueRegion.Sub(clientBounds, mPossiblyTransparentRegion);
|
||||
MARGINS margins = { 0, 0, 0, 0 };
|
||||
DWORD_PTR dwStyle = ::GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
// If there is no opaque region or hidechrome=true then full glass
|
||||
if (opaqueRegion.IsEmpty() || !(dwStyle & WS_CAPTION)) {
|
||||
margins.cxLeftWidth = -1;
|
||||
} else {
|
||||
// Find the largest rectangle and use that to calculate the inset
|
||||
nsIntRegionRectIterator rgnIter(opaqueRegion);
|
||||
const nsIntRect *currentRect = rgnIter.Next();
|
||||
nsIntRect largest = *currentRect;
|
||||
nscoord largestArea = largest.width * largest.height;
|
||||
while (currentRect = rgnIter.Next()) {
|
||||
nscoord area = currentRect->width * currentRect->height;
|
||||
if (area > largestArea) {
|
||||
largest = *currentRect;
|
||||
largestArea = area;
|
||||
}
|
||||
}
|
||||
margins.cxLeftWidth = largest.x;
|
||||
margins.cxRightWidth = clientBounds.width - largest.XMost();
|
||||
margins.cyTopHeight = largest.y;
|
||||
margins.cyBottomHeight = clientBounds.height - largest.YMost();
|
||||
}
|
||||
if (memcmp(&mGlassMargins, &margins, sizeof mGlassMargins)) {
|
||||
mGlassMargins = margins;
|
||||
UpdateGlass();
|
||||
}
|
||||
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
}
|
||||
|
||||
void nsWindow::UpdateGlass() {
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE);
|
||||
DWMNCRENDERINGPOLICY policy = DWMNCRP_USEWINDOWSTYLE;
|
||||
if(eTransparencyGlass == mTransparencyMode) {
|
||||
policy = DWMNCRP_ENABLED;
|
||||
}
|
||||
if(nsUXThemeData::CheckForCompositor()) {
|
||||
nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &mGlassMargins);
|
||||
nsUXThemeData::dwmSetWindowAttributePtr(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy);
|
||||
}
|
||||
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************
|
||||
@ -4584,10 +4646,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
|
||||
case WM_DWMCOMPOSITIONCHANGED:
|
||||
BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED);
|
||||
DispatchStandardEvent(NS_THEMECHANGED);
|
||||
if (nsUXThemeData::CheckForCompositor() && mTransparencyMode == eTransparencyGlass) {
|
||||
MARGINS margins = { -1, -1, -1, -1 };
|
||||
nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(mWnd, &margins);
|
||||
}
|
||||
UpdateGlass();
|
||||
Invalidate(PR_FALSE);
|
||||
break;
|
||||
#endif
|
||||
@ -6692,18 +6751,7 @@ void nsWindow::SetWindowTranslucencyInner(nsTransparencyMode aMode)
|
||||
mTransparencyMode = aMode;
|
||||
|
||||
SetupTranslucentWindowMemoryBitmap(aMode);
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
MARGINS margins = { 0, 0, 0, 0 };
|
||||
DWMNCRENDERINGPOLICY policy = DWMNCRP_USEWINDOWSTYLE;
|
||||
if(eTransparencyGlass == aMode) {
|
||||
margins.cxLeftWidth = -1;
|
||||
policy = DWMNCRP_ENABLED;
|
||||
}
|
||||
if(nsUXThemeData::sHaveCompositor) {
|
||||
nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &margins);
|
||||
nsUXThemeData::dwmSetWindowAttributePtr(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy);
|
||||
}
|
||||
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
UpdateGlass();
|
||||
#endif // #ifndef WINCE
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,9 @@
|
||||
#include "nsIAccessible.h"
|
||||
#endif
|
||||
|
||||
#if !defined(WINCE)
|
||||
#include "nsUXThemeData.h"
|
||||
#endif // !defined(WINCE)
|
||||
/**
|
||||
* Forward class definitions
|
||||
*/
|
||||
@ -182,6 +185,7 @@ public:
|
||||
#ifdef MOZ_XUL
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||
virtual nsTransparencyMode GetTransparencyMode();
|
||||
virtual void UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion, const nsIntRegion& aPossiblyTransparentRegion);
|
||||
#endif // MOZ_XUL
|
||||
#ifdef NS_ENABLE_TSF
|
||||
NS_IMETHOD OnIMEFocusChange(PRBool aFocus);
|
||||
@ -385,6 +389,7 @@ private:
|
||||
void ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight, PRBool force = PR_FALSE);
|
||||
nsresult UpdateTranslucentWindow();
|
||||
void SetupTranslucentWindowMemoryBitmap(nsTransparencyMode aMode);
|
||||
void UpdateGlass();
|
||||
protected:
|
||||
#endif // MOZ_XUL
|
||||
|
||||
@ -492,6 +497,10 @@ protected:
|
||||
nsRefPtr<gfxWindowsSurface> mTransparentSurface;
|
||||
HDC mMemoryDC;
|
||||
nsTransparencyMode mTransparencyMode;
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
nsIntRegion mPossiblyTransparentRegion;
|
||||
MARGINS mGlassMargins;
|
||||
#endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
#endif // MOZ_XUL
|
||||
|
||||
// Win7 Gesture processing and management
|
||||
|
Loading…
x
Reference in New Issue
Block a user