--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -773,16 +773,17 @@ mozilla::Maybe<nsUXThemeClass> nsNativeT
return Some(eUXSpin);
case NS_THEME_STATUSBAR:
case NS_THEME_STATUSBARPANEL:
case NS_THEME_RESIZERPANEL:
case NS_THEME_RESIZER:
return Some(eUXStatus);
case NS_THEME_MENULIST:
case NS_THEME_MENULIST_BUTTON:
+ case NS_THEME_MENULIST_BUTTON_ORIG:
return Some(eUXCombobox);
case NS_THEME_TREEHEADERCELL:
case NS_THEME_TREEHEADERSORTARROW:
return Some(eUXHeader);
case NS_THEME_LISTBOX:
case NS_THEME_LISTITEM:
case NS_THEME_TREEVIEW:
case NS_THEME_TREETWISTYOPEN:
@@ -1278,16 +1279,53 @@ nsNativeThemeWin::GetThemePartAndState(n
aState = TS_HOVER;
else
aState = TS_NORMAL;
}
return NS_OK;
}
case NS_THEME_MENULIST_BUTTON: {
+ if (mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ nsIContent* content = aFrame->GetContent();
+ bool isHTML = content && content->IsHTMLElement();
+ bool isChrome = aFrame->GetContent()->IsInChromeDocument();
+ bool useDropBorder = isHTML || (isChrome && IsMenuListEditable(aFrame));
+ EventStates eventState = GetContentState(aFrame, aWidgetType);
+
+ /* On Vista/Win7, we use CBP_DROPBORDER instead of DROPFRAME for HTML
+ * content or for editable menulists; this gives us the thin outline,
+ * instead of the gradient-filled background */
+ if (useDropBorder)
+ aPart = CBP_DROPBORDER;
+ else
+ aPart = CBP_DROPFRAME;
+
+ if (IsDisabled(aFrame, eventState)) {
+ aState = TS_DISABLED;
+ } else if (IsReadOnly(aFrame)) {
+ aState = TS_NORMAL;
+ } else if (IsOpenButton(aFrame)) {
+ aState = TS_ACTIVE;
+ } else {
+ if (useDropBorder && (eventState.HasState(NS_EVENT_STATE_FOCUS) || IsFocused(aFrame)))
+ aState = TS_ACTIVE;
+ else if (eventState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE))
+ aState = TS_ACTIVE;
+ else if (eventState.HasState(NS_EVENT_STATE_HOVER))
+ aState = TS_HOVER;
+ else
+ aState = TS_NORMAL;
+ }
+
+ return NS_OK;
+ }
+ MOZ_FALLTHROUGH;
+ }
+ case NS_THEME_MENULIST_BUTTON_ORIG: {
bool isHTML = IsHTMLContent(aFrame);
nsIFrame* parentFrame = aFrame->GetParent();
bool isMenulist = !isHTML && parentFrame->IsMenuFrame();
bool isOpen = false;
// HTML select and XUL menulist dropdown buttons get state from the parent.
if (isHTML || isMenulist)
aFrame = parentFrame;
@@ -1800,17 +1838,19 @@ RENDER_AGAIN:
renderRect.left = glyphSize.cx;
renderRect.right = renderRect.left + glyphSize.cx;
}
DrawThemeBGRTLAware(theme, hdc, part, state, &renderRect, &clipRect,
IsFrameRTL(aFrame));
}
// The following widgets need to be RTL-aware
else if (aWidgetType == NS_THEME_RESIZER ||
- aWidgetType == NS_THEME_MENULIST_BUTTON)
+ aWidgetType == NS_THEME_MENULIST_BUTTON_ORIG ||
+ (aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ !mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")))
{
DrawThemeBGRTLAware(theme, hdc, part, state,
&widgetRect, &clipRect, IsFrameRTL(aFrame));
}
else if (aWidgetType == NS_THEME_NUMBER_INPUT ||
aWidgetType == NS_THEME_TEXTFIELD ||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
@@ -2089,17 +2129,19 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
aResult->left = aResult->right = popupSize.cx;
ScaleForFrameDPI(aResult, aFrame);
return ok;
}
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
aWidgetType == NS_THEME_TEXTFIELD ||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
- aWidgetType == NS_THEME_MENULIST)
+ aWidgetType == NS_THEME_MENULIST ||
+ (aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")))
{
// If we have author-specified padding for these elements, don't do the
// fixups below.
if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING))
return false;
}
/* textfields need extra pixels on all sides, otherwise they wrap their
@@ -2110,17 +2152,19 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
*/
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
aWidgetType == NS_THEME_TEXTFIELD ||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
aResult->top = aResult->bottom = 2;
aResult->left = aResult->right = 2;
ScaleForFrameDPI(aResult, aFrame);
return ok;
- } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) {
+ } else if (IsHTMLContent(aFrame) && (aWidgetType == NS_THEME_MENULIST ||
+ (aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")))) {
/* For content menulist controls, we need an extra pixel so that we have
* room to draw our focus rectangle stuff. Otherwise, the focus rect might
* overlap the control's border.
*/
aResult->top = aResult->bottom = 1;
aResult->left = aResult->right = 1;
ScaleForFrameDPI(aResult, aFrame);
return ok;
@@ -2187,17 +2231,19 @@ nsNativeThemeWin::GetWidgetOverflow(nsDe
* This is fairly minor, as by default there is nothing in that area, and
* a border only shows up if the widget is being hovered.
*/
#if 0
/* We explicitly draw dropdown buttons in HTML content 1px bigger up, right,
* and bottom so that they overlap the dropdown's border like they're
* supposed to.
*/
- if (aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ if (((aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) ||
+ aWidgetType == NS_THEME_MENULIST_BUTTON_ORIG) &&
IsHTMLContent(aFrame) &&
!IsWidgetStyled(aFrame->GetParent()->PresContext(),
aFrame->GetParent(),
NS_THEME_MENULIST))
{
int32_t p2a = aContext->AppUnitsPerDevPixel();
/* Note: no overflow on the left */
nsMargin m(p2a, p2a, p2a, 0);
@@ -2277,16 +2323,22 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_DOWN:
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
case NS_THEME_SCROLLBAR_HORIZONTAL:
case NS_THEME_SCROLLBAR_VERTICAL:
case NS_THEME_MENULIST_BUTTON: {
+ if (mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ break;
+ }
+ MOZ_FALLTHROUGH;
+ }
+ case NS_THEME_MENULIST_BUTTON_ORIG: {
rv = ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable);
ScaleForFrameDPI(aResult, aFrame);
return rv;
}
case NS_THEME_MENUITEM:
case NS_THEME_CHECKMENUITEM:
case NS_THEME_RADIOMENUITEM:
if(!IsTopLevelMenu(aFrame))
@@ -2490,17 +2542,18 @@ nsNativeThemeWin::WidgetStateChanged(nsI
aWidgetType == NS_THEME_WINDOW_BUTTON_MAXIMIZE ||
aWidgetType == NS_THEME_WINDOW_BUTTON_RESTORE) {
*aShouldRepaint = true;
return NS_OK;
}
// We need to repaint the dropdown arrow in vista HTML combobox controls when
// the control is closed to get rid of the hover effect.
- if ((aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) &&
+ if ((aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON ||
+ aWidgetType == NS_THEME_MENULIST_BUTTON) &&
IsHTMLContent(aFrame))
{
*aShouldRepaint = true;
return NS_OK;
}
// XXXdwh Not sure what can really be done here. Can at least guess for
// specific widgets that they're highly unlikely to have certain states.
@@ -2566,17 +2619,19 @@ nsNativeThemeWin::ThemeSupportsWidget(ns
return false;
}
bool
nsNativeThemeWin::WidgetIsContainer(uint8_t aWidgetType)
{
// XXXdwh At some point flesh all of this out.
- if (aWidgetType == NS_THEME_MENULIST_BUTTON ||
+ if ((aWidgetType == NS_THEME_MENULIST_BUTTON &&
+ !mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) ||
+ aWidgetType == NS_THEME_MENULIST_BUTTON_ORIG ||
aWidgetType == NS_THEME_RADIO ||
aWidgetType == NS_THEME_CHECKBOX)
return false;
return true;
}
bool
nsNativeThemeWin::ThemeDrawsFocusForWidget(uint8_t aWidgetType)
@@ -2716,16 +2771,17 @@ nsNativeThemeWin::ClassicThemeSupportsWi
case NS_THEME_SCROLLBAR_VERTICAL:
case NS_THEME_SCROLLBAR_HORIZONTAL:
case NS_THEME_SCROLLBAR_NON_DISAPPEARING:
case NS_THEME_SCALE_HORIZONTAL:
case NS_THEME_SCALE_VERTICAL:
case NS_THEME_SCALETHUMB_HORIZONTAL:
case NS_THEME_SCALETHUMB_VERTICAL:
case NS_THEME_MENULIST_BUTTON:
+ case NS_THEME_MENULIST_BUTTON_ORIG:
case NS_THEME_INNER_SPIN_BUTTON:
case NS_THEME_SPINNER_UPBUTTON:
case NS_THEME_SPINNER_DOWNBUTTON:
case NS_THEME_LISTBOX:
case NS_THEME_TREEVIEW:
case NS_THEME_MENULIST_TEXTFIELD:
case NS_THEME_MENULIST:
case NS_THEME_TOOLTIP:
@@ -2776,16 +2832,22 @@ nsNativeThemeWin::ClassicGetWidgetBorder
break;
case NS_THEME_STATUSBAR:
(*aResult).bottom = (*aResult).left = (*aResult).right = 0;
(*aResult).top = 2;
break;
case NS_THEME_LISTBOX:
case NS_THEME_TREEVIEW:
case NS_THEME_MENULIST:
+ case NS_THEME_MENULIST_BUTTON: {
+ if (!mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ break;
+ }
+ MOZ_FALLTHROUGH;
+ }
case NS_THEME_MENULIST_TEXTFIELD:
case NS_THEME_TAB:
case NS_THEME_NUMBER_INPUT:
case NS_THEME_TEXTFIELD:
case NS_THEME_TEXTFIELD_MULTILINE:
case NS_THEME_FOCUS_OUTLINE:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
break;
@@ -2925,17 +2987,23 @@ nsNativeThemeWin::ClassicGetMinimumWidge
(*aResult).height = 20;
*aIsOverridable = false;
break;
case NS_THEME_SCALETHUMB_VERTICAL:
(*aResult).width = 20;
(*aResult).height = 12;
*aIsOverridable = false;
break;
- case NS_THEME_MENULIST_BUTTON:
+ case NS_THEME_MENULIST_BUTTON: {
+ if (mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ break;
+ }
+ MOZ_FALLTHROUGH;
+ }
+ case NS_THEME_MENULIST_BUTTON_ORIG:
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
break;
case NS_THEME_MENULIST:
case NS_THEME_BUTTON:
case NS_THEME_GROUPBOX:
case NS_THEME_LISTBOX:
case NS_THEME_TREEVIEW:
case NS_THEME_NUMBER_INPUT:
@@ -3205,16 +3273,22 @@ nsresult nsNativeThemeWin::ClassicGetThe
case NS_THEME_TABPANEL:
case NS_THEME_TABPANELS:
case NS_THEME_MENUBAR:
case NS_THEME_MENUPOPUP:
case NS_THEME_GROUPBOX:
// these don't use DrawFrameControl
return NS_OK;
case NS_THEME_MENULIST_BUTTON: {
+ if (mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ return NS_OK;
+ }
+ MOZ_FALLTHROUGH;
+ }
+ case NS_THEME_MENULIST_BUTTON_ORIG: {
aPart = DFC_SCROLL;
aState = DFCS_SCROLLCOMBOBOX;
nsIFrame* parentFrame = aFrame->GetParent();
bool isHTML = IsHTMLContent(aFrame);
bool isMenulist = !isHTML && parentFrame->IsMenuFrame();
bool isOpen = false;
@@ -3588,30 +3662,41 @@ RENDER_AGAIN:
case NS_THEME_RADIO:
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_DOWN:
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
case NS_THEME_INNER_SPIN_BUTTON:
case NS_THEME_SPINNER_UPBUTTON:
case NS_THEME_SPINNER_DOWNBUTTON:
- case NS_THEME_MENULIST_BUTTON:
+ case NS_THEME_MENULIST_BUTTON_ORIG:
case NS_THEME_RESIZER: {
int32_t oldTA;
// setup DC to make DrawFrameControl draw correctly
oldTA = ::SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
::DrawFrameControl(hdc, &widgetRect, part, state);
::SetTextAlign(hdc, oldTA);
break;
}
// Draw controls with 2px 3D inset border
case NS_THEME_NUMBER_INPUT:
case NS_THEME_TEXTFIELD:
case NS_THEME_TEXTFIELD_MULTILINE:
case NS_THEME_LISTBOX:
+ case NS_THEME_MENULIST_BUTTON: {
+ if (!mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ int32_t oldTA;
+ // setup DC to make DrawFrameControl draw correctly
+ oldTA = ::SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
+ ::DrawFrameControl(hdc, &widgetRect, part, state);
+ ::SetTextAlign(hdc, oldTA);
+ break;
+ }
+ MOZ_FALLTHROUGH;
+ }
case NS_THEME_MENULIST:
case NS_THEME_MENULIST_TEXTFIELD: {
// Draw inset edge
::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
EventStates eventState = GetContentState(aFrame, aWidgetType);
// Fill in background
if (IsDisabled(aFrame, eventState) ||
@@ -4015,17 +4100,26 @@ nsNativeThemeWin::GetWidgetNativeDrawing
case NS_THEME_MENUBAR:
case NS_THEME_MENUPOPUP:
case NS_THEME_MENUITEM:
break;
// the dropdown button /almost/ renders correctly with scaling,
// except that the graphic in the dropdown button (the downward arrow)
// doesn't get scaled up.
- case NS_THEME_MENULIST_BUTTON:
+ case NS_THEME_MENULIST_BUTTON: {
+ if (mozilla::Preferences::GetBool("layout.css.webkit-appearance.enabled")) {
+ return
+ gfxWindowsNativeDrawing::CANNOT_DRAW_TO_COLOR_ALPHA |
+ gfxWindowsNativeDrawing::CAN_AXIS_ALIGNED_SCALE |
+ gfxWindowsNativeDrawing::CANNOT_COMPLEX_TRANSFORM;
+ }
+ MOZ_FALLTHROUGH;
+ }
+ case NS_THEME_MENULIST_BUTTON_ORIG:
// these are definitely no; they're all graphics that don't get scaled up
case NS_THEME_CHECKBOX:
case NS_THEME_RADIO:
case NS_THEME_GROUPBOX:
case NS_THEME_CHECKMENUITEM:
case NS_THEME_RADIOMENUITEM:
case NS_THEME_MENUCHECKBOX:
case NS_THEME_MENURADIO: