Bug 554982 - Add support for borderless glass and remove the borders from the main window. r=roc,dao a=blocking2.0
authorRob Arnold <robarnold@cs.cmu.edu>
Tue, 17 Aug 2010 23:07:10 -0400
changeset 50770 13bfa20e543a3b591b1383421f96f798bb7262f8
parent 50769 55953a91b4d6d7771d94b5cc65c860ab1112380a
child 50771 cac7482b3cd83adb4aea32cddfa15704e7822095
push idunknown
push userunknown
push dateunknown
reviewersroc, dao, blocking2.0
bugs554982
milestone2.0b5pre
Bug 554982 - Add support for borderless glass and remove the borders from the main window. r=roc,dao a=blocking2.0
browser/themes/winstripe/browser/browser-aero.css
gfx/src/nsITheme.h
gfx/src/nsThemeConstants.h
layout/base/nsLayoutUtils.cpp
layout/style/nsCSSKeywordList.h
layout/style/nsCSSProps.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/windows/nsWindowGfx.cpp
--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -12,17 +12,17 @@
   .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
     background-image: -moz-linear-gradient(rgba(255,255,255,.7), @toolbarHighlight@ 30%),
                       -moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
   }
 }
 
 @media all and (-moz-windows-compositor) {
   #main-window:not(:-moz-lwtheme) {
-    -moz-appearance: -moz-win-glass;
+    -moz-appearance: -moz-win-borderless-glass;
     background: transparent;
   }
 
   /* the new titlebar requires this, or content will be clipped at the top of the screen. */
   #main-window[sizemode="maximized"][chromemargin^="0,"] {
     margin-top: 8px;
   }
 
--- a/gfx/src/nsITheme.h
+++ b/gfx/src/nsITheme.h
@@ -64,17 +64,18 @@ class nsIWidget;
 { 0x23db7c13, 0x873d, 0x4fb5, { 0xaf, 0x29, 0xc1, 0xe9, 0xed, 0x91, 0x23, 0xf9 } }
 // {D930E29B-6909-44e5-AB4B-AF10D6923705}
 #define NS_THEMERENDERER_CID \
 { 0xd930e29b, 0x6909, 0x44e5, { 0xab, 0x4b, 0xaf, 0x10, 0xd6, 0x92, 0x37, 0x5 } }
 
 enum nsTransparencyMode {
   eTransparencyOpaque = 0,  // Fully opaque
   eTransparencyTransparent, // Parts of the window may be transparent
-  eTransparencyGlass        // Transparent parts of the window have Vista AeroGlass effect applied
+  eTransparencyGlass,       // Transparent parts of the window have Vista AeroGlass effect applied
+  eTransparencyBorderlessGlass // As above, but without a border around the opaque areas when there would otherwise be one with eTransparencyGlass
 };
 
 /**
  * nsITheme is a service that provides platform-specific native
  * rendering for widgets.  In other words, it provides the necessary
  * operations to draw a rendering object (an nsIFrame) as a native
  * widget.
  *
--- a/gfx/src/nsThemeConstants.h
+++ b/gfx/src/nsThemeConstants.h
@@ -231,16 +231,17 @@
 #define NS_THEME_WIN_COMMUNICATIONS_TOOLBOX                221
 #define NS_THEME_WIN_MEDIA_TOOLBOX                         222
 #define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX               223
 
 // Unified toolbar on the Mac
 #define NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR                   224
 
 // Vista glass
+#define NS_THEME_WIN_BORDERLESS_GLASS                      229
 #define NS_THEME_WIN_GLASS                                 230
 
 // Windows themed window frame elements
 #define NS_THEME_WINDOW_TITLEBAR                           231
 #define NS_THEME_WINDOW_TITLEBAR_MAXIMIZED                 232
 #define NS_THEME_WINDOW_FRAME_LEFT                         233
 #define NS_THEME_WINDOW_FRAME_RIGHT                        234
 #define NS_THEME_WINDOW_FRAME_BOTTOM                       235
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3282,16 +3282,19 @@ nsLayoutUtils::GetFrameTransparency(nsIF
   if (aCSSRootFrame->IsThemed(&transparency))
     return transparency == nsITheme::eTransparent
          ? eTransparencyTransparent
          : eTransparencyOpaque;
 
   if (aCSSRootFrame->GetStyleDisplay()->mAppearance == NS_THEME_WIN_GLASS)
     return eTransparencyGlass;
 
+  if (aCSSRootFrame->GetStyleDisplay()->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS)
+    return eTransparencyBorderlessGlass;
+
   // We need an uninitialized window to be treated as opaque because
   // doing otherwise breaks window display effects on some platforms,
   // specifically Vista. (bug 450322)
   if (aBackgroundFrame->GetType() == nsGkAtoms::viewportFrame &&
       !aBackgroundFrame->GetFirstChild(nsnull)) {
     return eTransparencyOpaque;
   }
 
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -588,16 +588,17 @@ CSS_KEY(checkbox-label, checkboxlabel)
 CSS_KEY(radio-label, radiolabel)
 CSS_KEY(button-focus, buttonfocus)
 CSS_KEY(-moz-win-media-toolbox, _moz_win_media_toolbox)
 CSS_KEY(-moz-win-communications-toolbox, _moz_win_communications_toolbox)
 CSS_KEY(-moz-win-browsertabbar-toolbox, _moz_win_browsertabbar_toolbox)
 CSS_KEY(-moz-win-mediatext, _moz_win_mediatext)
 CSS_KEY(-moz-win-communicationstext, _moz_win_communicationstext)
 CSS_KEY(-moz-win-glass, _moz_win_glass)
+CSS_KEY(-moz-win-borderless-glass, _moz_win_borderless_glass)
 CSS_KEY(-moz-window-titlebar, _moz_window_titlebar)
 CSS_KEY(-moz-window-titlebar-maximized, _moz_window_titlebar_maximized)
 CSS_KEY(-moz-window-frame-left, _moz_window_frame_left)
 CSS_KEY(-moz-window-frame-right, _moz_window_frame_right)
 CSS_KEY(-moz-window-frame-bottom, _moz_window_frame_bottom)
 CSS_KEY(-moz-window-button-close, _moz_window_button_close)
 CSS_KEY(-moz-window-button-minimize, _moz_window_button_minimize)
 CSS_KEY(-moz-window-button-maximize, _moz_window_button_maximize)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -494,16 +494,17 @@ const PRInt32 nsCSSProps::kAppearanceKTa
   eCSSKeyword_menuseparator,          NS_THEME_MENUSEPARATOR,
   eCSSKeyword_menuarrow,              NS_THEME_MENUARROW,
   eCSSKeyword_menuimage,              NS_THEME_MENUIMAGE,
   eCSSKeyword_menuitemtext,           NS_THEME_MENUITEMTEXT,
   eCSSKeyword__moz_win_media_toolbox, NS_THEME_WIN_MEDIA_TOOLBOX,
   eCSSKeyword__moz_win_communications_toolbox, NS_THEME_WIN_COMMUNICATIONS_TOOLBOX,
   eCSSKeyword__moz_win_browsertabbar_toolbox,  NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX,
   eCSSKeyword__moz_win_glass,         NS_THEME_WIN_GLASS,
+  eCSSKeyword__moz_win_borderless_glass,      NS_THEME_WIN_BORDERLESS_GLASS,
   eCSSKeyword__moz_mac_unified_toolbar,       NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR,
   eCSSKeyword__moz_window_titlebar,           NS_THEME_WINDOW_TITLEBAR,
   eCSSKeyword__moz_window_titlebar_maximized, NS_THEME_WINDOW_TITLEBAR_MAXIMIZED,
   eCSSKeyword__moz_window_frame_left,         NS_THEME_WINDOW_FRAME_LEFT,
   eCSSKeyword__moz_window_frame_right,        NS_THEME_WINDOW_FRAME_RIGHT,
   eCSSKeyword__moz_window_frame_bottom,       NS_THEME_WINDOW_FRAME_BOTTOM,
   eCSSKeyword__moz_window_button_close,       NS_THEME_WINDOW_BUTTON_CLOSE,
   eCSSKeyword__moz_window_button_minimize,    NS_THEME_WINDOW_BUTTON_MINIMIZE,
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -834,17 +834,17 @@ DWORD nsWindow::WindowStyle()
       style = WS_OVERLAPPED | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_3DLOOK |
               DS_MODALFRAME | WS_CLIPCHILDREN;
       if (mBorderStyle != eBorderStyle_default)
         style |= WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
       break;
 
     case eWindowType_popup:
       style = WS_POPUP;
-      if (mTransparencyMode != eTransparencyGlass) {
+      if (!HasGlass()) {
         style |= WS_OVERLAPPED;
       }
       break;
 
     default:
       NS_ERROR("unknown border style");
       // fall through
 
@@ -1270,32 +1270,32 @@ NS_METHOD nsWindow::IsVisible(PRBool & b
  *
  **************************************************************/
 
 // XP and Vista visual styles sometimes require window clipping regions to be applied for proper
 // transparency. These routines are called on size and move operations.
 void nsWindow::ClearThemeRegion()
 {
 #ifndef WINCE
-  if (nsUXThemeData::sIsVistaOrLater && mTransparencyMode != eTransparencyGlass &&
+  if (nsUXThemeData::sIsVistaOrLater && !HasGlass() &&
       mWindowType == eWindowType_popup && (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel)) {
     SetWindowRgn(mWnd, NULL, false);
   }
 #endif
 }
 
 void nsWindow::SetThemeRegion()
 {
 #ifndef WINCE
   // Popup types that have a visual styles region applied (bug 376408). This can be expanded
   // for other window types as needed. The regions are applied generically to the base window
   // so default constants are used for part and state. At some point we might need part and
   // state values from nsNativeThemeWin's GetThemePartAndState, but currently windows that
   // change shape based on state haven't come up.
-  if (nsUXThemeData::sIsVistaOrLater && mTransparencyMode != eTransparencyGlass &&
+  if (nsUXThemeData::sIsVistaOrLater && !HasGlass() &&
       mWindowType == eWindowType_popup && (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel)) {
     HRGN hRgn = nsnull;
     RECT rect = {0,0,mBounds.width,mBounds.height};
     
     HDC dc = ::GetDC(mWnd);
     nsUXThemeData::getThemeBackgroundRegion(nsUXThemeData::GetTheme(eUXTooltip), dc, TTP_STANDARD, TS_NORMAL, &rect, &hRgn);
     if (hRgn) {
       if (!SetWindowRgn(mWnd, hRgn, false)) // do not delete or alter hRgn if accepted.
@@ -2442,17 +2442,17 @@ namespace {
     region->Or(*region, clientArea);
     return TRUE;
   }
 }
 
 void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion,
                                                const nsIntRegion &aPossiblyTransparentRegion) {
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-  if (mTransparencyMode != eTransparencyGlass)
+  if (!HasGlass())
     return;
 
   HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE);
   nsWindow* topWindow = GetNSWindowPtr(hWnd);
 
   if (GetParent())
     return;
 
@@ -2503,29 +2503,41 @@ void nsWindow::UpdatePossiblyTransparent
   }
 #endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
 }
 
 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
   //                          rendered based on the window style.
   // DWMNCRP_ENABLED        - The non-client area rendering is
   //                          enabled; the window style is ignored.
   DWMNCRENDERINGPOLICY policy = DWMNCRP_USEWINDOWSTYLE;
-  if (mTransparencyMode == eTransparencyGlass) {
+  switch (mTransparencyMode) {
+  case eTransparencyBorderlessGlass:
+    {
+      const PRInt32 kGlassMarginAdjustment = 2;
+      margins.cxLeftWidth += kGlassMarginAdjustment;
+      margins.cyTopHeight += kGlassMarginAdjustment;
+      margins.cxRightWidth += kGlassMarginAdjustment;
+      margins.cyBottomHeight += kGlassMarginAdjustment;
+    }
+    // Fall through
+  case eTransparencyGlass:
     policy = DWMNCRP_ENABLED;
+    break;
   }
 
   // Extends the window frame behind the client area
   if(nsUXThemeData::CheckForCompositor()) {
-    nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &mGlassMargins);
+    nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &margins);
     nsUXThemeData::dwmSetWindowAttributePtr(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy);
   }
 #endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
 }
 #endif
 
 /**************************************************************
  *
@@ -7614,17 +7626,17 @@ void nsWindow::SetWindowTranslucencyInne
    else
      exStyle &= ~WS_EX_LAYERED;
 
   VERIFY_WINDOW_STYLE(style);
   ::SetWindowLongPtrW(hWnd, GWL_STYLE, style);
   ::SetWindowLongPtrW(hWnd, GWL_EXSTYLE, exStyle);
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-  if (mTransparencyMode == eTransparencyGlass)
+  if (HasGlass())
     memset(&mGlassMargins, 0, sizeof mGlassMargins);
 #endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
   mTransparencyMode = aMode;
 
   SetupTranslucentWindowMemoryBitmap(aMode);
   UpdateGlass();
 #endif // #ifndef WINCE
 }
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -304,16 +304,20 @@ protected:
   PRBool                  CanTakeFocus();
   PRBool                  UpdateNonClientMargins(PRInt32 aSizeMode = -1, PRBool aReflowWindow = PR_TRUE);
   void                    ResetLayout();
   void                    InvalidateNonClientRegion();
   HRGN                    ExcludeNonClientFromPaintRegion(HRGN aRegion);
 #if !defined(WINCE)
   static void             InitTrackPointHack();
 #endif
+  PRBool                  HasGlass() const {
+    return mTransparencyMode == eTransparencyGlass ||
+           mTransparencyMode == eTransparencyBorderlessGlass;
+  }
 
   /**
    * Event processing helpers
    */
   PRBool                  DispatchPluginEvent(const MSG &aMsg);
   PRBool                  DispatchFocusToTopLevelWindow(PRUint32 aEventType);
   PRBool                  DispatchFocus(PRUint32 aEventType);
   PRBool                  DispatchStandardEvent(PRUint32 aMsg);
--- a/widget/src/windows/nsWindowGfx.cpp
+++ b/widget/src/windows/nsWindowGfx.cpp
@@ -536,30 +536,34 @@ DDRAW_FAILED:
           thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
 #endif
 
           // don't need to double buffer with anything but GDI
           BasicLayerManager::BufferMode doubleBuffering =
             BasicLayerManager::BUFFER_NONE;
           if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) {
 # if defined(MOZ_XUL) && !defined(WINCE)
-            if (eTransparencyGlass == mTransparencyMode && nsUXThemeData::sHaveCompositor) {
-              doubleBuffering = BasicLayerManager::BUFFER_BUFFERED;
-           } else if (eTransparencyTransparent == mTransparencyMode) {
-              // If we're rendering with translucency, we're going to be
-              // rendering the whole window; make sure we clear it first
-              thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-              thebesContext->Paint();
-              thebesContext->SetOperator(gfxContext::OPERATOR_OVER);
-            } else
+            switch (mTransparencyMode) {
+              case eTransparencyGlass:
+              case eTransparencyBorderlessGlass:
+              default:
+                // If we're not doing translucency, then double buffer
+                doubleBuffering = BasicLayerManager::BUFFER_BUFFERED;
+                break;
+              case eTransparencyTransparent:
+                // If we're rendering with translucency, we're going to be
+                // rendering the whole window; make sure we clear it first
+                thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR);
+                thebesContext->Paint();
+                thebesContext->SetOperator(gfxContext::OPERATOR_OVER);
+                break;
+            }
+#else
+            doubleBuffering = BasicLayerManager::BUFFER_BUFFERED;
 #endif
-            {
-              // If we're not doing translucency, then double buffer
-              doubleBuffering = BasicLayerManager::BUFFER_BUFFERED;
-            }
           }
 
           {
             AutoLayerManagerSetup
                 setupLayerManager(this, thebesContext, doubleBuffering);
             result = DispatchWindowEvent(&event, eventStatus);
           }