Bug 333910 - nsITheme for menu/scrollbox arrows, r=mstange,gijs
authorstefanh@inbox.com
Mon, 08 Sep 2014 10:45:00 +0100
changeset 208622 af792af2f5c7f64fdc60a50f157cb610702fe933
parent 208471 1ee2c06d271fd585845af22bcb41f4f97a09da34
child 208623 e54edf3b633c08bbb908e5c4823f4f5fe50e22d0
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmstange, gijs
bugs333910
milestone35.0a1
Bug 333910 - nsITheme for menu/scrollbox arrows, r=mstange,gijs
browser/themes/osx/customizableui/panelUIOverlay.css
toolkit/themes/osx/global/global.css
toolkit/themes/osx/global/jar.mn
toolkit/themes/osx/global/menu.css
toolkit/themes/osx/global/menu/menu-arrow.png
toolkit/themes/osx/global/menu/menu-arrow@2x.png
toolkit/themes/osx/global/scrollbox.css
widget/cocoa/nsNativeThemeCocoa.h
widget/cocoa/nsNativeThemeCocoa.mm
--- a/browser/themes/osx/customizableui/panelUIOverlay.css
+++ b/browser/themes/osx/customizableui/panelUIOverlay.css
@@ -134,25 +134,25 @@ menu.subviewbutton,
 menuitem.subviewbutton:not(.panel-subview-footer) {
   padding-top: 2px;
   padding-bottom: 2px;
 }
 
 /* Override OSX-specific toolkit styles for the bookmarks panel */
 menu.subviewbutton > .menu-right {
   -moz-margin-end: 0;
-}
-menu.subviewbutton > .menu-right > image {
-  -moz-image-region: rect(0, 9px, 10px, 0);
+  -moz-appearance: none;
 }
 
-@media (min-resolution: 2dppx) {
-  menu.subviewbutton > .menu-right > image {
-    -moz-image-region: rect(0, 18px, 20px, 0);
-  }
+menu.subviewbutton > .menu-right > image {
+ /* We don't want the arrow to highlight when the .subviewbutton is hovered,
+  * so we set the -moz-appearance rule on the image
+  * (which doesn't inherit the _moz-menuactive attribute) instead.
+  */
+  -moz-appearance: menuarrow;
 }
 
 .widget-overflow-list .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   -moz-margin-start: 4px;
 }
 
 .PanelUI-subView menuseparator,
 .cui-widget-panelview menuseparator {
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -308,36 +308,47 @@ notification > button > .button-box > .b
   background-position: right bottom;
 }
 
 /* autorepeatbuttons in menus */
 
 .popup-internal-box > autorepeatbutton {
   height: 15px;
   position: relative;
+  list-style-image: none;
   /* Here we're using a little magic.
    * The arrow button is supposed to overlay the scrollbox, blocking
    * everything under it from reaching the screen. However, the menu background
    * is slightly transparent, so how can we block something completely without
    * messing up the transparency? It's easy: The native theming of the
    * "menuitem" appearance uses CGContextClearRect before drawing, which
    * clears everything under it.
    * Without help from native theming this effect wouldn't be achievable.
    */
   -moz-appearance: menuitem;
 }
 
 .popup-internal-box > .autorepeatbutton-up {
+  padding-top: 1px; /* 4px padding-top from the .popup-internal-box. */
   margin-bottom: -15px;
 }
 
+.popup-internal-box > .autorepeatbutton-up > .autorepeatbutton-icon {
+  -moz-appearance: button-arrow-up;
+}
+
 .popup-internal-box > .autorepeatbutton-down {
+  padding-top: 5px;
   margin-top: -15px;
 }
 
+.popup-internal-box > .autorepeatbutton-down > .autorepeatbutton-icon {
+  -moz-appearance: button-arrow-down;
+}
+
 .popup-internal-box > autorepeatbutton[disabled="true"] {
   visibility: collapse;
 }
 
 /* :::::: Close button icons ::::: */
 
 .close-icon {
   list-style-image: url("chrome://global/skin/icons/close.png");
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -176,18 +176,16 @@ toolkit.jar:
   skin/classic/global/media/throbber.png                             (media/throbber.png)
   skin/classic/global/media/stalled.png                              (media/stalled.png)
   skin/classic/global/media/volume-empty.png                         (media/volume-empty.png)
   skin/classic/global/media/volume-empty@2x.png                      (media/volume-empty@2x.png)
   skin/classic/global/media/volume-full.png                          (media/volume-full.png)
   skin/classic/global/media/volume-full@2x.png                       (media/volume-full@2x.png)
   skin/classic/global/media/clicktoplay-bgtexture.png                (media/clicktoplay-bgtexture.png)
   skin/classic/global/media/videoClickToPlayButton.svg               (media/videoClickToPlayButton.svg)
-  skin/classic/global/menu/menu-arrow.png                            (menu/menu-arrow.png)
-  skin/classic/global/menu/menu-arrow@2x.png                         (menu/menu-arrow@2x.png)
   skin/classic/global/menu/shared-menu-check.png                     (../../shared/menu-check.png)
   skin/classic/global/menu/shared-menu-check@2x.png                  (../../shared/menu-check@2x.png)
 * skin/classic/global/in-content/common.css                          (in-content/common.css)
   skin/classic/global/in-content/check.png                           (../../shared/in-content/check.png)
   skin/classic/global/in-content/check@2x.png                        (../../shared/in-content/check@2x.png)
   skin/classic/global/in-content/dropdown.png                        (../../shared/in-content/dropdown.png)
   skin/classic/global/in-content/dropdown@2x.png                     (../../shared/in-content/dropdown@2x.png)
   skin/classic/global/in-content/dropdown-disabled.png               (../../shared/in-content/dropdown-disabled.png)
--- a/toolkit/themes/osx/global/menu.css
+++ b/toolkit/themes/osx/global/menu.css
@@ -71,57 +71,32 @@ menuitem[src] > .menu-iconic-left > .men
   width: 16px;
 }
 
 /* ..... menu arrow box ..... */
 
 .menu-right,
 .menu-accel-container {
   -moz-margin-start: 21px;
+  -moz-margin-end: -9px;
   -moz-box-pack: end;
 }
 
-.menu-accel-container {
-  -moz-margin-end: -9px;
+/* The native menuarrow we use is 9px wide on 10.7+ and 8px wide on 10.6,
+ * so it needs to be 'pulled in' one pixel more by the negative margin in
+ * order to align properly: */
+@media not all and (-moz-mac-lion-theme) {
+  .menu-right {
+    -moz-margin-end: -10px;
+  }
 }
 
 .menu-right {
-  -moz-margin-end: -10px;
-  width: 9px;
-  list-style-image: url("chrome://global/skin/menu/menu-arrow.png");
-  -moz-image-region: rect(0, 9px, 10px, 0);
-}
-
-.menu-right[_moz-menuactive="true"]:not([disabled="true"]) {
-  -moz-image-region: rect(0, 18px, 10px, 9px);
-}
-
-.menu-right[disabled="true"] {
-  -moz-image-region: rect(0, 27px, 10px, 18px);
-}
-
-.menu-right:-moz-locale-dir(rtl) {
-  transform: scaleX(-1);
-}
-
-@media (min-resolution: 2dppx) {
-  .menu-right > image {
-    list-style-image: url("chrome://global/skin/menu/menu-arrow@2x.png");
-    -moz-image-region: rect(0, 18px, 20px, 0);
-    width: 9px;
-    height: 10px;
-  }
-
-  .menu-right[_moz-menuactive="true"]:not([disabled="true"]) > image {
-    -moz-image-region: rect(0, 36px, 20px, 18px);
-  }
-
-  .menu-right[disabled="true"] > image {
-    -moz-image-region: rect(0, 54px, 20px, 36px);
-  }
+  list-style-image: none;
+  -moz-appearance: menuarrow;
 }
 
 /* ::::: menu/menuitems in menubar ::::: */
 
 menubar > menu {
   -moz-appearance: none;
   padding: 2px 5px 2px 7px;
   margin: 1px 0;
deleted file mode 100644
index b80f2e37d826847c57d34da10c955df3c2b88964..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 98eee11ba779834f2a2f302fbf9407686f01cb3e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/themes/osx/global/scrollbox.css
+++ b/toolkit/themes/osx/global/scrollbox.css
@@ -26,71 +26,37 @@
  
 .autorepeatbutton-down[orient="horizontal"][disabled="true"],
 .scrollbutton-down[orient="horizontal"][disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-rit-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical enabled */
-.autorepeatbutton-up:not([orient="horizontal"]) {
-  padding-bottom: 5px;
-}
-
-.autorepeatbutton-down:not([orient="horizontal"]) {
-  padding-top: 5px;
-}
-
-.autorepeatbutton-up:not([orient="horizontal"]) > .autorepeatbutton-icon {
-  transform: rotate(-90deg);
-}
-
-.autorepeatbutton-down:not([orient="horizontal"]) > .autorepeatbutton-icon {
-  transform: rotate(90deg);
-}
-
+.autorepeatbutton-up:not([orient="horizontal"]),
 .scrollbutton-up {
   list-style-image: url("chrome://global/skin/arrow/arrow-up-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
+.autorepeatbutton-down:not([orient="horizontal"]),
 .scrollbutton-down {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-sharp.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 /* Vertical disabled */
 .autorepeatbutton-up[disabled="true"]:not([orient="horizontal"]),
-.autorepeatbutton-down[disabled="true"]:not([orient="horizontal"]) {
-  -moz-image-region: rect(0, 27px, 10px, 18px);
-}
-
 .scrollbutton-up[disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
+.autorepeatbutton-down[disabled="true"]:not([orient="horizontal"]),
 .scrollbutton-down[disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
   -moz-image-region: auto; /* cut off inheritance */
 }
 
 .scrollbutton-up > .toolbarbutton-text,
 .scrollbutton-down > .toolbarbutton-text {
   display: none;
 }
-
-autorepeatbutton {
-  list-style-image: url("chrome://global/skin/menu/menu-arrow.png");
-  -moz-image-region: rect(0, 9px, 10px, 0);
-  -moz-box-align: center;
-  -moz-box-pack: center;
-  padding: 1px;
-}
-
-@media (min-resolution: 2dppx) {
-  autorepeatbutton > .autorepeatbutton-icon {
-    list-style-image: url("chrome://global/skin/menu/menu-arrow@2x.png");
-    -moz-image-region: rect(0, 18px, 20px, 0);
-    width: 9px;
-    height: 10px;
-  }
-}
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -99,17 +99,18 @@ protected:
                            mozilla::EventStates inState, nsIFrame* aFrame);
   void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect,
                        nsIFrame* aFrame, mozilla::EventStates inState);
   void DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
                       mozilla::EventStates inState, uint8_t aWidgetType,
                       nsIFrame* aFrame);
   void DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect,
                     mozilla::EventStates inState, nsIFrame* aFrame,
-                    const NSSize& aIconSize, const NSString* aImageName);
+                    const NSSize& aIconSize, const NSString* aImageName,
+                    bool aCenterHorizontally);
   void DrawButton(CGContextRef context, ThemeButtonKind inKind,
                   const HIRect& inBoxRect, bool inIsDefault, 
                   ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
                   mozilla::EventStates inState, nsIFrame* aFrame);
   void DrawFocusOutline(CGContextRef cgContext, const HIRect& inBoxRect,
                         mozilla::EventStates inState, uint8_t aWidgetType,
                         nsIFrame* aFrame);
   void DrawDropdown(CGContextRef context, const HIRect& inBoxRect,
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -1032,33 +1032,42 @@ nsNativeThemeCocoa::DrawSearchField(CGCo
                        IsFrameRTL(aFrame));
 
   [cell setContext:nullptr];
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 static const NSSize kCheckmarkSize = NSMakeSize(11, 11);
+static const NSSize kMenuarrowSize = nsCocoaFeatures::OnLionOrLater() ?
+                                     NSMakeSize(9, 10) : NSMakeSize(8, 10);
+static const NSSize kMenuScrollArrowSize = NSMakeSize(10, 8);
 static const NSString* kCheckmarkImage = @"image.MenuOnState";
+static const NSString* kMenuarrowRightImage = @"image.MenuSubmenu";
+static const NSString* kMenuarrowLeftImage = @"image.MenuSubmenuLeft";
+static const NSString* kMenuDownScrollArrowImage = @"image.MenuScrollDown";
+static const NSString* kMenuUpScrollArrowImage = @"image.MenuScrollUp";
 static const CGFloat kMenuIconIndent = 6.0f;
 
 void
 nsNativeThemeCocoa::DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect,
                                  EventStates inState, nsIFrame* aFrame,
-                                 const NSSize& aIconSize, const NSString* aImageName)
+                                 const NSSize& aIconSize, const NSString* aImageName,
+                                 bool aCenterHorizontally)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   // Adjust size and position of our drawRect.
   CGFloat paddingX = std::max(CGFloat(0.0), aRect.size.width - aIconSize.width);
   CGFloat paddingY = std::max(CGFloat(0.0), aRect.size.height - aIconSize.height);
   CGFloat paddingStartX = std::min(paddingX, kMenuIconIndent);
   CGFloat paddingEndX = std::max(CGFloat(0.0), paddingX - kMenuIconIndent);
   CGRect drawRect = CGRectMake(
-    aRect.origin.x + (IsFrameRTL(aFrame) ? paddingEndX : paddingStartX),
+    aRect.origin.x + (aCenterHorizontally ? ceil(paddingX / 2) :
+                      IsFrameRTL(aFrame) ? paddingEndX : paddingStartX),
     aRect.origin.y + ceil(paddingY / 2),
     aIconSize.width, aIconSize.height);
 
   BOOL isDisabled = IsDisabled(aFrame, inState);
   BOOL isActive = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
 
   // On 10.6 and at least on 10.7.0, Apple doesn’t seem to have implemented all
   // keys and values used on 10.7.5 and later. We can however draw menu icons
@@ -2341,21 +2350,28 @@ nsNativeThemeCocoa::DrawWidgetBackground
       
       // 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_MENUARROW: {
+      bool isRTL = IsFrameRTL(aFrame);
+      DrawMenuIcon(cgContext, macRect, eventState, aFrame, kMenuarrowSize,
+                   isRTL ? kMenuarrowLeftImage : kMenuarrowRightImage, true);
+    }
+      break;
+
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM: {
       SurfaceFormat format  = thebesCtx->GetDrawTarget()->GetFormat();
       bool isTransparent = (format == SurfaceFormat::R8G8B8A8) ||
-                      (format == SurfaceFormat::B8G8R8A8);
+                           (format == SurfaceFormat::B8G8R8A8);
       if (isTransparent) {
         // Clear the background to get correct transparency.
         CGContextClearRect(cgContext, macRect);
       }
 
       // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain?
       HIThemeMenuItemDrawInfo drawInfo;
       memset(&drawInfo, 0, sizeof(drawInfo));
@@ -2367,17 +2383,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
                            static_cast<ThemeMenuState>(kThemeMenuSelected) :
                            static_cast<ThemeMenuState>(kThemeMenuActive));
 
       // XXX pass in the menu rect instead of always using the item rect
       HIRect ignored;
       HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored);
 
       if (aWidgetType == NS_THEME_CHECKMENUITEM) {
-        DrawMenuIcon(cgContext, macRect, eventState, aFrame, kCheckmarkSize, kCheckmarkImage);
+        DrawMenuIcon(cgContext, macRect, eventState, aFrame, kCheckmarkSize, kCheckmarkImage, false);
       }
     }
       break;
 
     case NS_THEME_MENUSEPARATOR: {
       ThemeMenuState menuState;
       if (IsDisabled(aFrame, eventState)) {
         menuState = kThemeMenuDisabled;
@@ -2387,16 +2403,23 @@ nsNativeThemeCocoa::DrawWidgetBackground
                     kThemeMenuSelected : kThemeMenuActive;
       }
 
       HIThemeMenuItemDrawInfo midi = { 0, kThemeMenuItemPlain, menuState };
       HIThemeDrawMenuSeparator(&macRect, &macRect, &midi, cgContext, HITHEME_ORIENTATION);
     }
       break;
 
+    case NS_THEME_BUTTON_ARROW_UP:
+    case NS_THEME_BUTTON_ARROW_DOWN:
+      DrawMenuIcon(cgContext, macRect, eventState, aFrame, kMenuScrollArrowSize,
+                   aWidgetType == NS_THEME_BUTTON_ARROW_UP ?
+                   kMenuUpScrollArrowImage : kMenuDownScrollArrowImage, true);
+      break;
+
     case NS_THEME_TOOLTIP:
       if (nsCocoaFeatures::OnYosemiteOrLater()) {
         CGContextSetRGBFillColor(cgContext, 0.945, 0.942, 0.945, 0.950);
       } else {
         CGContextSetRGBFillColor(cgContext, 0.996, 1.000, 0.792, 0.950);
       }
       CGContextFillRect(cgContext, macRect);
       break;
@@ -3085,16 +3108,31 @@ nsNativeThemeCocoa::GetMinimumWidgetSize
   switch (aWidgetType) {
     case NS_THEME_BUTTON:
     {
       aResult->SizeTo(pushButtonSettings.minimumSizes[miniControlSize].width,
                       pushButtonSettings.naturalSizes[miniControlSize].height);
       break;
     }
 
+    case NS_THEME_BUTTON_ARROW_UP:
+    case NS_THEME_BUTTON_ARROW_DOWN:
+    {
+      aResult->SizeTo(kMenuScrollArrowSize.width, kMenuScrollArrowSize.height);
+      *aIsOverridable = false;
+      break;
+    }
+
+    case NS_THEME_MENUARROW:
+    {
+      aResult->SizeTo(kMenuarrowSize.width, kMenuarrowSize.height);
+      *aIsOverridable = false;
+      break;
+    }
+
     case NS_THEME_MOZ_MAC_HELP_BUTTON:
     {
       aResult->SizeTo(kHelpButtonSize.width, kHelpButtonSize.height);
       *aIsOverridable = false;
       break;
     }
 
     case NS_THEME_TOOLBAR_BUTTON:
@@ -3466,28 +3504,31 @@ nsNativeThemeCocoa::ThemeSupportsWidget(
     case NS_THEME_LISTBOX:
 
     case NS_THEME_DIALOG:
     case NS_THEME_WINDOW:
     case NS_THEME_WINDOW_BUTTON_BOX:
     case NS_THEME_WINDOW_TITLEBAR:
     case NS_THEME_CHECKMENUITEM:
     case NS_THEME_MENUPOPUP:
+    case NS_THEME_MENUARROW:
     case NS_THEME_MENUITEM:
     case NS_THEME_MENUSEPARATOR:
     case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
     case NS_THEME_TOOLTIP:
     
     case NS_THEME_CHECKBOX:
     case NS_THEME_CHECKBOX_CONTAINER:
     case NS_THEME_RADIO:
     case NS_THEME_RADIO_CONTAINER:
     case NS_THEME_GROUPBOX:
     case NS_THEME_MOZ_MAC_HELP_BUTTON:
     case NS_THEME_BUTTON:
+    case NS_THEME_BUTTON_ARROW_UP:
+    case NS_THEME_BUTTON_ARROW_DOWN:
     case NS_THEME_BUTTON_BEVEL:
     case NS_THEME_TOOLBAR_BUTTON:
     case NS_THEME_SPINNER:
     case NS_THEME_SPINNER_UP_BUTTON:
     case NS_THEME_SPINNER_DOWN_BUTTON:
     case NS_THEME_TOOLBAR:
     case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
     case NS_THEME_STATUSBAR:
@@ -3611,18 +3652,21 @@ nsNativeThemeCocoa::ThemeNeedsComboboxDr
 
 bool
 nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType)
 {
   switch (aWidgetType) {
     case NS_THEME_DIALOG:
     case NS_THEME_GROUPBOX:
     case NS_THEME_TAB_PANELS:
+    case NS_THEME_BUTTON_ARROW_UP:
+    case NS_THEME_BUTTON_ARROW_DOWN:
     case NS_THEME_CHECKMENUITEM:
     case NS_THEME_MENUPOPUP:
+    case NS_THEME_MENUARROW:
     case NS_THEME_MENUITEM:
     case NS_THEME_MENUSEPARATOR:
     case NS_THEME_TOOLTIP:
     case NS_THEME_SPINNER:
     case NS_THEME_SPINNER_UP_BUTTON:
     case NS_THEME_SPINNER_DOWN_BUTTON:
     case NS_THEME_TOOLBAR_SEPARATOR:
     case NS_THEME_TOOLBOX: