--- a/widget/gtk/nsLookAndFeel.cpp
+++ b/widget/gtk/nsLookAndFeel.cpp
@@ -152,40 +152,65 @@ GetUnicoBorderGradientColors(GtkStyleCon
gtk_style_context_get_property(aContext, propertyName, state, &value);
bool result = GetGradientColors(&value, aLightColor, aDarkColor);
g_value_unset(&value);
return result;
}
-
-static void
+// Sets |aLightColor| and |aDarkColor| to colors from |aContext|. Returns
+// true if |aContext| uses these colors to render a visible border.
+// If returning false, then the colors returned are a fallback from the
+// border-color value even though |aContext| does not use these colors to
+// render a border.
+static bool
GetBorderColors(GtkStyleContext* aContext,
GdkRGBA* aLightColor, GdkRGBA* aDarkColor)
{
- if (GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor))
- return;
+ // Determine whether the border on this style context is visible.
+ GtkStateFlags state = gtk_style_context_get_state(aContext);
+ GtkBorderStyle borderStyle;
+ gtk_style_context_get(aContext, state, GTK_STYLE_PROPERTY_BORDER_STYLE,
+ &borderStyle, nullptr);
+ bool visible = borderStyle != GTK_BORDER_STYLE_NONE &&
+ borderStyle != GTK_BORDER_STYLE_HIDDEN;
+ if (visible) {
+ // GTK has an initial value of zero for border-widths, and so themes
+ // need to explicitly set border-widths to make borders visible.
+ GtkBorder border;
+ gtk_style_context_get_border(aContext, GTK_STATE_FLAG_NORMAL, &border);
+ visible = border.top != 0 || border.right != 0 ||
+ border.bottom != 0 || border.left != 0;
+ }
- GtkStateFlags state = gtk_style_context_get_state(aContext);
+ if (visible &&
+ GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor))
+ return true;
+
+ // The initial value for the border-color is the foreground color, and so
+ // this will usually return a color distinct from the background even if
+ // there is no visible border detected.
gtk_style_context_get_border_color(aContext, state, aDarkColor);
// TODO GTK3 - update aLightColor
// for GTK_BORDER_STYLE_INSET/OUTSET/GROVE/RIDGE border styles.
// https://bugzilla.mozilla.org/show_bug.cgi?id=978172#c25
*aLightColor = *aDarkColor;
+ return visible;
}
-static void
+static bool
GetBorderColors(GtkStyleContext* aContext,
nscolor* aLightColor, nscolor* aDarkColor)
{
GdkRGBA lightColor, darkColor;
- GetBorderColors(aContext, &lightColor, &darkColor);
+ bool ret = GetBorderColors(aContext, &lightColor, &darkColor);
*aLightColor = GDK_RGBA_TO_NS_RGBA(lightColor);
*aDarkColor = GDK_RGBA_TO_NS_RGBA(darkColor);
+ return ret;
}
#endif
nsresult
nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
{
#if (MOZ_WIDGET_GTK == 3)
GdkRGBA gdk_color;
@@ -1335,19 +1360,29 @@ nsLookAndFeel::Init()
gtk_style_context_save(style);
gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_restore(style);
gtk_widget_path_free(path);
+ // GtkFrame has a "border" subnode on which Adwaita draws the border.
+ // Some themes do not draw on this node but draw a border on the widget
+ // root node, so check the root node if no border is found on the border
+ // node.
style = ClaimStyleContext(MOZ_GTK_FRAME_BORDER);
- GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+ bool themeUsesColors =
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
ReleaseStyleContext(style);
+ if (!themeUsesColors) {
+ style = ClaimStyleContext(MOZ_GTK_FRAME);
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+ ReleaseStyleContext(style);
+ }
// GtkInfoBar
// TODO - Use WidgetCache for it?
GtkWidget* infoBar = gtk_info_bar_new();
GtkWidget* infoBarContent = gtk_info_bar_get_content_area(GTK_INFO_BAR(infoBar));
GtkWidget* infoBarLabel = gtk_label_new(nullptr);
gtk_container_add(GTK_CONTAINER(parent), infoBar);
gtk_container_add(GTK_CONTAINER(infoBarContent), infoBarLabel);