diff --git a/toolkit/themes/gnomestripe/global/menu.css b/toolkit/themes/gnomestripe/global/menu.css index bcd5a1567cd3..763c36ed4e94 100644 --- a/toolkit/themes/gnomestripe/global/menu.css +++ b/toolkit/themes/gnomestripe/global/menu.css @@ -202,14 +202,14 @@ menuitem[type="radio"] { /* ::::: menuseparator ::::: */ menuseparator { - margin: 2px 3px; + -moz-appearance: menuseparator !important; + margin: 2px 0; border-top: 1px solid ThreeDShadow; border-bottom: 1px solid ThreeDHighlight; } menulist > menupopup > menuseparator, .menulist-menupopup > menuseparator { - margin: 2px 0; border-top: 1px solid #000000; border-bottom: none; } diff --git a/widget/src/gtk2/gtk2drawing.c b/widget/src/gtk2/gtk2drawing.c index 3e34daec458d..c2debcaeea87 100644 --- a/widget/src/gtk2/gtk2drawing.c +++ b/widget/src/gtk2/gtk2drawing.c @@ -85,6 +85,7 @@ static GtkWidget* gTreeHeaderCellWidget; static GtkWidget* gTreeHeaderSortArrowWidget; static GtkWidget* gExpanderWidget; static GtkWidget* gToolbarSeparatorWidget; +static GtkWidget* gMenuSeparatorWidget; static GtkShadowType gMenuBarShadowType; static GtkShadowType gToolbarShadowType; @@ -375,6 +376,19 @@ ensure_menu_item_widget() return MOZ_GTK_SUCCESS; } +static gint +ensure_menu_separator_widget() +{ + if (!gMenuSeparatorWidget) { + ensure_menu_popup_widget(); + gMenuSeparatorWidget = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), + gMenuSeparatorWidget); + gtk_widget_realize(gMenuSeparatorWidget); + } + return MOZ_GTK_SUCCESS; +} + static gint ensure_check_menu_item_widget() { @@ -1641,6 +1655,55 @@ moz_gtk_menu_popup_paint(GdkDrawable* drawable, GdkRectangle* rect, return MOZ_GTK_SUCCESS; } +static gint +moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect, + GdkRectangle* cliprect) +{ + GtkStyle* style; + gboolean wide_separators; + gint separator_height; + guint horizontal_padding; + gint paint_height; + + ensure_menu_separator_widget(); + + style = gMenuSeparatorWidget->style; + + gtk_widget_style_get(gMenuSeparatorWidget, + "wide-separators", &wide_separators, + "separator-height", &separator_height, + "horizontal-padding", &horizontal_padding, + NULL); + + TSOffsetStyleGCs(style, rect->x, rect->y); + + if (wide_separators) { + if (separator_height > rect->height) + separator_height = rect->height; + + gtk_paint_box(style, drawable, + GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT, + cliprect, gMenuSeparatorWidget, "hseparator", + rect->x + horizontal_padding + style->xthickness, + rect->y + (rect->height - separator_height - style->ythickness) / 2, + rect->width - 2 * (horizontal_padding + style->xthickness), + separator_height); + } else { + paint_height = style->ythickness; + if (paint_height > rect->height) + paint_height = rect->height; + + gtk_paint_hline(style, drawable, + GTK_STATE_NORMAL, cliprect, gMenuSeparatorWidget, + "menuitem", + rect->x + horizontal_padding + style->xthickness, + rect->x + rect->width - horizontal_padding - style->xthickness - 1, + rect->y + (rect->height - style->ythickness) / 2); + } + + return MOZ_GTK_SUCCESS; +} + static gint moz_gtk_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect, GdkRectangle* cliprect, GtkWidgetState* state, @@ -1990,6 +2053,7 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, case MOZ_GTK_TAB: case MOZ_GTK_EXPANDER: case MOZ_GTK_TOOLBAR_SEPARATOR: + case MOZ_GTK_MENUSEPARATOR: /* These widgets have no borders.*/ case MOZ_GTK_TOOLTIP: case MOZ_GTK_WINDOW: @@ -2062,6 +2126,27 @@ moz_gtk_get_expander_size(gint* size) return MOZ_GTK_SUCCESS; } +gint +moz_gtk_get_menu_separator_height(gint *size) +{ + gboolean wide_separators; + gint separator_height; + + ensure_menu_separator_widget(); + + gtk_widget_style_get(gMenuSeparatorWidget, + "wide-separators", &wide_separators, + "separator-height", &separator_height, + NULL); + + if (wide_separators) + *size = separator_height + gMenuSeparatorWidget->style->ythickness; + else + *size = gMenuSeparatorWidget->style->ythickness * 2; + + return MOZ_GTK_SUCCESS; +} + gint moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height) { @@ -2213,6 +2298,9 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable, case MOZ_GTK_MENUPOPUP: return moz_gtk_menu_popup_paint(drawable, rect, cliprect); break; + case MOZ_GTK_MENUSEPARATOR: + return moz_gtk_menu_separator_paint(drawable, rect, cliprect); + break; case MOZ_GTK_MENUITEM: return moz_gtk_menu_item_paint(drawable, rect, cliprect, state, flags); break; @@ -2281,6 +2369,7 @@ moz_gtk_shutdown() gTreeHeaderSortArrowWidget = NULL; gExpanderWidget = NULL; gToolbarSeparatorWidget = NULL; + gMenuSeparatorWidget = NULL; is_initialized = FALSE; diff --git a/widget/src/gtk2/gtkdrawing.h b/widget/src/gtk2/gtkdrawing.h index fd8e4e3fffcf..1ca7f7c065f6 100644 --- a/widget/src/gtk2/gtkdrawing.h +++ b/widget/src/gtk2/gtkdrawing.h @@ -182,6 +182,7 @@ typedef enum { MOZ_GTK_MENUITEM, MOZ_GTK_CHECKMENUITEM, MOZ_GTK_RADIOMENUITEM, + MOZ_GTK_MENUSEPARATOR, /* Paints the background of a window, dialog or page. */ MOZ_GTK_WINDOW } GtkThemeWidgetType; @@ -322,6 +323,14 @@ gint moz_gtk_get_toolbar_separator_width(gint* size); */ gint moz_gtk_get_expander_size(gint* size); +/** + * Get the desired height of a menu separator + * size: [OUT] the desired height + * + * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise + */ +gint moz_gtk_get_menu_separator_height(gint* size); + /** * Retrieve an actual GTK scrollbar widget for style analysis. It will not * be modified. diff --git a/widget/src/gtk2/nsNativeThemeGTK.cpp b/widget/src/gtk2/nsNativeThemeGTK.cpp index f00f293f173a..1442456ca062 100644 --- a/widget/src/gtk2/nsNativeThemeGTK.cpp +++ b/widget/src/gtk2/nsNativeThemeGTK.cpp @@ -275,6 +275,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame, if (aWidgetType == NS_THEME_MENUITEM || aWidgetType == NS_THEME_CHECKMENUITEM || aWidgetType == NS_THEME_RADIOMENUITEM || + aWidgetType == NS_THEME_MENUSEPARATOR || aWidgetType == NS_THEME_MENUARROW) { PRBool isTopLevel = PR_FALSE; nsIMenuFrame *menuFrame; @@ -503,6 +504,9 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame, case NS_THEME_MENUITEM: aGtkWidgetType = MOZ_GTK_MENUITEM; break; + case NS_THEME_MENUSEPARATOR: + aGtkWidgetType = MOZ_GTK_MENUSEPARATOR; + break; case NS_THEME_MENUARROW: aGtkWidgetType = MOZ_GTK_MENUARROW; break; @@ -904,6 +908,16 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext, *aIsOverridable = PR_FALSE; } break; + case NS_THEME_MENUSEPARATOR: + { + gint separator_height; + + moz_gtk_get_menu_separator_height(&separator_height); + aResult->height = separator_height; + + *aIsOverridable = PR_FALSE; + } + break; case NS_THEME_CHECKBOX: case NS_THEME_CHECKBOX_SMALL: case NS_THEME_RADIO: @@ -991,6 +1005,7 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType, aWidgetType == NS_THEME_MENUPOPUP || aWidgetType == NS_THEME_TOOLTIP || aWidgetType == NS_THEME_TREEVIEW_HEADER_SORTARROW || + aWidgetType == NS_THEME_MENUSEPARATOR || aWidgetType == NS_THEME_WINDOW || aWidgetType == NS_THEME_DIALOG) { *aShouldRepaint = PR_FALSE; @@ -1114,6 +1129,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, case NS_THEME_MENUPOPUP: case NS_THEME_MENUITEM: case NS_THEME_MENUARROW: + case NS_THEME_MENUSEPARATOR: case NS_THEME_CHECKMENUITEM: case NS_THEME_RADIOMENUITEM: case NS_THEME_WINDOW: