Bug 391984 - [10.5] Add roundness to context menus, r=josh sr=roc a191=beltzner
authorMarkus Stange <mstange@themasta.com>
Thu, 11 Dec 2008 15:37:38 +0100
changeset 22330 55582aea3232294bc88a9061897bfc57c947eed7
parent 22329 0dc120ad23141bd037e77caacce9086e40d7a0e1
child 22331 8ab13896946059f1e8194be3ea99d87dc1f91a48
push id169
push usermstange@themasta.com
push dateMon, 15 Dec 2008 14:42:03 +0000
reviewersjosh, roc
bugs391984
milestone1.9.1b3pre
Bug 391984 - [10.5] Add roundness to context menus, r=josh sr=roc a191=beltzner
gfx/public/nsITheme.h
layout/base/nsLayoutUtils.cpp
layout/generic/nsIFrame.h
widget/public/nsIWidget.h
widget/src/cocoa/nsChildView.mm
widget/src/cocoa/nsNativeThemeCocoa.h
widget/src/cocoa/nsNativeThemeCocoa.mm
widget/src/gtk2/nsNativeThemeGTK.cpp
widget/src/gtk2/nsNativeThemeGTK.h
widget/src/qt/nsNativeThemeQt.cpp
widget/src/qt/nsNativeThemeQt.h
widget/src/windows/nsNativeThemeWin.cpp
widget/src/windows/nsNativeThemeWin.h
--- a/gfx/public/nsITheme.h
+++ b/gfx/public/nsITheme.h
@@ -52,24 +52,30 @@ struct nsMargin;
 class nsPresContext;
 class nsIRenderingContext;
 class nsIDeviceContext;
 class nsIFrame;
 class nsIContent;
 class nsIAtom;
 
 // IID for the nsITheme interface
-// {df8baf21-5ea7-49eb-a2bc-f2fd4a9fd896}
+// {f5eb2e02-ed3f-4340-82fc-22f55bb556f9}
 #define NS_ITHEME_IID     \
-{ 0xdf8baf21, 0x5ea7, 0x49eb, { 0xa2, 0xbc, 0xf2, 0xfd, 0x4a, 0x9f, 0xd8, 0x96 } }
+{ 0xf5eb2e02, 0xed3f, 0x4340, { 0x82, 0xfc, 0x22, 0xf5, 0x5b, 0xb5, 0x56, 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
+};
+
 /**
  * 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.
  *
  * All the methods on nsITheme take a rendering context or device
  * context, a frame (the rendering object), and a widget type (one of
@@ -128,16 +134,18 @@ public:
    * widget.
    */
   NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext,
                                   nsIFrame* aFrame,
                                   PRUint8 aWidgetType,
                                   nsSize* aResult,
                                   PRBool* aIsOverridable)=0;
 
+  virtual nsTransparencyMode GetWidgetTransparency(PRUint8 aWidgetType)=0;
+
   NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType, 
                                 nsIAtom* aAttribute, PRBool* aShouldRepaint)=0;
 
   NS_IMETHOD ThemeChanged()=0;
 
   /**
    * Can the nsITheme implementation handle this widget?
    */
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2936,18 +2936,19 @@ nsLayoutUtils::HasNonZeroCorner(const ns
 /* static */ nsTransparencyMode
 nsLayoutUtils::GetFrameTransparency(nsIFrame* aFrame) {
   if (aFrame->GetStyleContext()->GetStyleDisplay()->mOpacity < 1.0f)
     return eTransparencyTransparent;
 
   if (HasNonZeroCorner(aFrame->GetStyleContext()->GetStyleBorder()->mBorderRadius))
     return eTransparencyTransparent;
 
-  if (aFrame->IsThemed())
-    return eTransparencyOpaque;
+  nsTransparencyMode transparency;
+  if (aFrame->IsThemed(&transparency))
+    return transparency;
 
   if (aFrame->GetStyleDisplay()->mAppearance == NS_THEME_WIN_GLASS)
     return eTransparencyGlass;
   PRBool isCanvas;
   const nsStyleBackground* bg;
   if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg, &isCanvas))
     return eTransparencyTransparent;
   if (NS_GET_A(bg->mBackgroundColor) < 255)
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -837,25 +837,31 @@ public:
    * painted on top of the rest of the display list items.
    *
    * @param aDirtyRect is the dirty rectangle that we're repainting.
    */
   nsresult DisplayCaret(nsDisplayListBuilder*       aBuilder,
                         const nsRect&               aDirtyRect,
                         const nsDisplayListSet&     aLists);
 
-  PRBool IsThemed() {
-    return IsThemed(GetStyleDisplay());
+  PRBool IsThemed(nsTransparencyMode* aTransparencyMode = nsnull) {
+    return IsThemed(GetStyleDisplay(), aTransparencyMode);
   }
-  PRBool IsThemed(const nsStyleDisplay* aDisp) {
+  PRBool IsThemed(const nsStyleDisplay* aDisp,
+                  nsTransparencyMode* aTransparencyMode = nsnull) {
     if (!aDisp->mAppearance)
       return PR_FALSE;
     nsPresContext* pc = PresContext();
     nsITheme *theme = pc->GetTheme();
-    return theme && theme->ThemeSupportsWidget(pc, this, aDisp->mAppearance);
+    if(!theme || !theme->ThemeSupportsWidget(pc, this, aDisp->mAppearance))
+      return PR_FALSE;
+    if (aTransparencyMode) {
+      *aTransparencyMode = theme->GetWidgetTransparency(aDisp->mAppearance);
+    }
+    return PR_TRUE;
   }
   
   /**
    * Builds a display list for the content represented by this frame,
    * treating this frame as the root of a stacking context.
    * @param aDirtyRect content outside this rectangle can be ignored; the
    * rectangle is in frame coordinates
    */
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -41,16 +41,17 @@
 #include "nsISupports.h"
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsRect.h"
 
 #include "prthread.h"
 #include "nsEvent.h"
 #include "nsCOMPtr.h"
+#include "nsITheme.h"
 
 // forward declarations
 class   nsIAppShell;
 class   nsIToolkit;
 class   nsIFontMetrics;
 class   nsIRenderingContext;
 class   nsIDeviceContext;
 class   nsIRegion;
@@ -232,22 +233,16 @@ enum nsContentType {
 };
 
 enum nsTopLevelWidgetZPlacement { // for PlaceBehind()
   eZPlacementBottom = 0,  // bottom of the window stack
   eZPlacementBelow,       // just below another widget
   eZPlacementTop          // top of the window stack
 };
 
-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
-};
-
 /**
  * Basic struct for widget initialization data.
  * @see Create member function of nsIWidget
  */
 
 struct nsWidgetInitData {
   nsWidgetInitData()
     : clipChildren(PR_FALSE), 
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -2909,17 +2909,17 @@ NSEvent* gLastDragEvent = nil;
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 
 // Limit shadow invalidation to 10 times per second.
 static const PRInt32 sShadowInvalidationInterval = 100;
 - (void)maybeInvalidateShadow
 {
-  if (!mIsTransparent || ![mWindow hasShadow])
+  if ([mWindow isOpaque] || ![mWindow hasShadow])
     return;
 
   PRIntervalTime now = PR_IntervalNow();
   PRInt32 elapsed = PR_IntervalToMilliseconds(now - mLastShadowInvalidation);
   if (!mLastShadowInvalidation ||
       elapsed >= sShadowInvalidationInterval) {
     [mWindow invalidateShadow];
     mLastShadowInvalidation = now;
--- a/widget/src/cocoa/nsNativeThemeCocoa.h
+++ b/widget/src/cocoa/nsNativeThemeCocoa.h
@@ -83,16 +83,17 @@ public:
                                   nsSize* aResult, PRBool* aIsOverridable);
   NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType, 
                                 nsIAtom* aAttribute, PRBool* aShouldRepaint);
   NS_IMETHOD ThemeChanged();
   PRBool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, PRUint8 aWidgetType);
   PRBool WidgetIsContainer(PRUint8 aWidgetType);
   PRBool ThemeDrawsFocusForWidget(nsPresContext* aPresContext, nsIFrame* aFrame, PRUint8 aWidgetType);
   PRBool ThemeNeedsComboboxDropmarker();
+  virtual nsTransparencyMode GetWidgetTransparency(PRUint8 aWidgetType);
 
 protected:  
 
   nsresult GetSystemColor(PRUint8 aWidgetType, nsILookAndFeel::nsColorID& aColorID);
   nsresult GetSystemFont(PRUint8 aWidgetType, nsSystemFontID& aFont);
 
   // HITheme drawing routines
   void DrawFrame(CGContextRef context, HIThemeFrameKind inKind,
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -1356,18 +1356,20 @@ nsNativeThemeCocoa::DrawWidgetBackground
     }
       break;
 
     case NS_THEME_MENUPOPUP: {
       HIThemeMenuDrawInfo mdi = {
         version: 0,
         menuType: IsDisabled(aFrame) ? kThemeMenuTypeInactive : kThemeMenuTypePopUp
       };
-
-      HIThemeDrawMenuBackground(&macRect, &mdi, cgContext, HITHEME_ORIENTATION);
+      // The rounded corners draw outside the frame.
+      CGRect deflatedRect = CGRectMake(macRect.origin.x, macRect.origin.y + 4,
+                                       macRect.size.width, macRect.size.height - 8);
+      HIThemeDrawMenuBackground(&deflatedRect, &mdi, cgContext, HITHEME_ORIENTATION);
     }
       break;
 
     case NS_THEME_MENUITEM: {
       // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain?
       HIThemeMenuItemDrawInfo drawInfo = {
         version: 0,
         itemType: kThemeMenuItemPlain,
@@ -2194,8 +2196,17 @@ nsNativeThemeCocoa::ThemeDrawsFocusForWi
   return PR_FALSE;
 }
 
 PRBool
 nsNativeThemeCocoa::ThemeNeedsComboboxDropmarker()
 {
   return PR_FALSE;
 }
+
+nsTransparencyMode
+nsNativeThemeCocoa::GetWidgetTransparency(PRUint8 aWidgetType)
+{
+  if (aWidgetType == NS_THEME_MENUPOPUP)
+    return eTransparencyTransparent;
+
+  return eTransparencyOpaque;
+}
--- a/widget/src/gtk2/nsNativeThemeGTK.cpp
+++ b/widget/src/gtk2/nsNativeThemeGTK.cpp
@@ -1309,8 +1309,14 @@ nsNativeThemeGTK::ThemeDrawsFocusForWidg
   return PR_FALSE;
 }
 
 PRBool
 nsNativeThemeGTK::ThemeNeedsComboboxDropmarker()
 {
   return PR_FALSE;
 }
+
+nsTransparencyMode
+nsNativeThemeGTK::GetWidgetTransparency(PRUint8 aWidgetType)
+{
+  return eTransparencyOpaque;
+}
--- a/widget/src/gtk2/nsNativeThemeGTK.h
+++ b/widget/src/gtk2/nsNativeThemeGTK.h
@@ -87,16 +87,18 @@ public:
 
   NS_IMETHOD_(PRBool) WidgetIsContainer(PRUint8 aWidgetType);
   
   NS_IMETHOD_(PRBool) ThemeDrawsFocusForWidget(nsPresContext* aPresContext,
                                                nsIFrame* aFrame, PRUint8 aWidgetType);
 
   PRBool ThemeNeedsComboboxDropmarker();
 
+  virtual nsTransparencyMode GetWidgetTransparency(PRUint8 aWidgetType);
+
   nsNativeThemeGTK();
   virtual ~nsNativeThemeGTK();
 
 private:
   PRBool GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
                               GtkThemeWidgetType& aGtkWidgetType,
                               GtkWidgetState* aState, gint* aWidgetFlags);
 
--- a/widget/src/qt/nsNativeThemeQt.cpp
+++ b/widget/src/qt/nsNativeThemeQt.cpp
@@ -558,16 +558,22 @@ nsNativeThemeQt::ThemeDrawsFocusForWidge
 }
 
 PRBool
 nsNativeThemeQt::ThemeNeedsComboboxDropmarker()
 {
     return PR_TRUE;
 }
 
+nsTransparencyMode
+nsNativeThemeQt::GetWidgetTransparency(PRUint8 aWidgetType)
+{
+  return eTransparencyOpaque;
+}
+
 void
 nsNativeThemeQt::InitButtonStyle(PRUint8 aWidgetType,
                                  nsIFrame* aFrame,
                                  QRect rect,
                                  QStyleOptionButton &opt)
 {
     PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
--- a/widget/src/qt/nsNativeThemeQt.h
+++ b/widget/src/qt/nsNativeThemeQt.h
@@ -94,16 +94,18 @@ public:
                                               PRUint8 aWidgetType,
                                               nsMargin* aResult);
 
   NS_IMETHOD_(PRBool) ThemeDrawsFocusForWidget(nsPresContext* aPresContext,
                                                nsIFrame* aFrame, PRUint8 aWidgetType);
 
   PRBool ThemeNeedsComboboxDropmarker();
 
+  virtual nsTransparencyMode GetWidgetTransparency(PRUint8 aWidgetType);
+
   nsNativeThemeQt();
   virtual ~nsNativeThemeQt();
 
 private:
 
   inline PRInt32 GetAppUnitsPerDevPixel(nsIRenderingContext* aContext){
     nsCOMPtr<nsIDeviceContext> dctx = nsnull;
     aContext->GetDeviceContext(*getter_AddRefs(dctx));
--- a/widget/src/windows/nsNativeThemeWin.cpp
+++ b/widget/src/windows/nsNativeThemeWin.cpp
@@ -1645,16 +1645,22 @@ nsNativeThemeWin::ThemeDrawsFocusForWidg
 }
 
 PRBool
 nsNativeThemeWin::ThemeNeedsComboboxDropmarker()
 {
   return PR_TRUE;
 }
 
+nsTransparencyMode
+nsNativeThemeWin::GetWidgetTransparency(PRUint8 aWidgetType)
+{
+  return eTransparencyOpaque;
+}
+
 /* Windows 9x/NT/2000/Classic XP Theme Support */
 
 PRBool 
 nsNativeThemeWin::ClassicThemeSupportsWidget(nsPresContext* aPresContext,
                                       nsIFrame* aFrame,
                                       PRUint8 aWidgetType)
 {
   switch (aWidgetType) {
--- a/widget/src/windows/nsNativeThemeWin.h
+++ b/widget/src/windows/nsNativeThemeWin.h
@@ -70,16 +70,18 @@ public:
                                    PRUint8 aWidgetType,
                                    nsRect* aOverflowRect);
 
   NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
                                   PRUint8 aWidgetType,
                                   nsSize* aResult,
                                   PRBool* aIsOverridable);
 
+  virtual nsTransparencyMode GetWidgetTransparency(PRUint8 aWidgetType);
+
   NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType, 
                                 nsIAtom* aAttribute, PRBool* aShouldRepaint);
 
   NS_IMETHOD ThemeChanged();
 
   PRBool ThemeSupportsWidget(nsPresContext* aPresContext, 
                              nsIFrame* aFrame,
                              PRUint8 aWidgetType);