LCOV - code coverage report
Current view: top level - widget/gtk - nsLookAndFeel.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 343 562 61.0 %
Date: 2017-07-14 16:53:18 Functions: 13 21 61.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim:expandtab:shiftwidth=4:tabstop=4:
       3             :  */
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : // for strtod()
       9             : #include <stdlib.h>
      10             : 
      11             : #include "nsLookAndFeel.h"
      12             : 
      13             : #include <gtk/gtk.h>
      14             : #include <gdk/gdk.h>
      15             : 
      16             : #include <pango/pango.h>
      17             : #include <pango/pango-fontmap.h>
      18             : 
      19             : #include <fontconfig/fontconfig.h>
      20             : #include "gfxPlatformGtk.h"
      21             : #include "ScreenHelperGTK.h"
      22             : 
      23             : #include "gtkdrawing.h"
      24             : #include "nsStyleConsts.h"
      25             : #include "gfxFontConstants.h"
      26             : #include "WidgetUtils.h"
      27             : 
      28             : #include <dlfcn.h>
      29             : 
      30             : #include "mozilla/gfx/2D.h"
      31             : 
      32             : #if MOZ_WIDGET_GTK != 2
      33             : #include <cairo-gobject.h>
      34             : #include "WidgetStyleCache.h"
      35             : #include "prenv.h"
      36             : #endif
      37             : 
      38             : using mozilla::LookAndFeel;
      39             : 
      40             : #define GDK_COLOR_TO_NS_RGB(c) \
      41             :     ((nscolor) NS_RGB(c.red>>8, c.green>>8, c.blue>>8))
      42             : #define GDK_RGBA_TO_NS_RGBA(c) \
      43             :     ((nscolor) NS_RGBA((int)((c).red*255), (int)((c).green*255), \
      44             :                        (int)((c).blue*255), (int)((c).alpha*255)))
      45             : 
      46           2 : nsLookAndFeel::nsLookAndFeel()
      47             :     : nsXPLookAndFeel(),
      48             : #if (MOZ_WIDGET_GTK == 2)
      49             :       mStyle(nullptr),
      50             : #endif
      51             :       mDefaultFontCached(false), mButtonFontCached(false),
      52             :       mFieldFontCached(false), mMenuFontCached(false),
      53           2 :       mInitialized(false)
      54             : {
      55           2 : }
      56             : 
      57           0 : nsLookAndFeel::~nsLookAndFeel()
      58             : {
      59             : #if (MOZ_WIDGET_GTK == 2)
      60             :     g_object_unref(mStyle);
      61             : #endif
      62           0 : }
      63             : 
      64             : #if MOZ_WIDGET_GTK != 2
      65             : // Modifies color |*aDest| as if a pattern of color |aSource| was painted with
      66             : // CAIRO_OPERATOR_OVER to a surface with color |*aDest|.
      67             : static void
      68           2 : ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) {
      69           2 :     gdouble sourceCoef = aSource.alpha;
      70           2 :     gdouble destCoef = aDest->alpha * (1.0 - sourceCoef);
      71           2 :     gdouble resultAlpha = sourceCoef + destCoef;
      72           2 :     if (resultAlpha != 0.0) { // don't divide by zero
      73           2 :         destCoef /= resultAlpha;
      74           2 :         sourceCoef /= resultAlpha;
      75           2 :         aDest->red = sourceCoef * aSource.red + destCoef * aDest->red;
      76           2 :         aDest->green = sourceCoef * aSource.green + destCoef * aDest->green;
      77           2 :         aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue;
      78           2 :         aDest->alpha = resultAlpha;
      79             :     }
      80           2 : }
      81             : 
      82             : static void
      83           0 : GetLightAndDarkness(const GdkRGBA& aColor,
      84             :                     double* aLightness, double* aDarkness)
      85             : {
      86           0 :     double sum = aColor.red + aColor.green + aColor.blue;
      87           0 :     *aLightness = sum * aColor.alpha;
      88           0 :     *aDarkness = (3.0 - sum) * aColor.alpha;
      89           0 : }
      90             : 
      91             : static bool
      92           0 : GetGradientColors(const GValue* aValue,
      93             :                   GdkRGBA* aLightColor, GdkRGBA* aDarkColor)
      94             : {
      95           0 :     if (!G_TYPE_CHECK_VALUE_TYPE(aValue, CAIRO_GOBJECT_TYPE_PATTERN))
      96           0 :         return false;
      97             : 
      98           0 :     auto pattern = static_cast<cairo_pattern_t*>(g_value_get_boxed(aValue));
      99           0 :     if (!pattern)
     100           0 :         return false;
     101             : 
     102             :     // Just picking the lightest and darkest colors as simple samples rather
     103             :     // than trying to blend, which could get messy if there are many stops.
     104           0 :     if (CAIRO_STATUS_SUCCESS !=
     105           0 :         cairo_pattern_get_color_stop_rgba(pattern, 0, nullptr, &aDarkColor->red,
     106             :                                           &aDarkColor->green, &aDarkColor->blue,
     107             :                                           &aDarkColor->alpha))
     108           0 :         return false;
     109             : 
     110             :     double maxLightness, maxDarkness;
     111           0 :     GetLightAndDarkness(*aDarkColor, &maxLightness, &maxDarkness);
     112           0 :     *aLightColor = *aDarkColor;
     113             : 
     114             :     GdkRGBA stop;
     115           0 :     for (int index = 1;
     116             :          CAIRO_STATUS_SUCCESS ==
     117           0 :              cairo_pattern_get_color_stop_rgba(pattern, index, nullptr,
     118             :                                                &stop.red, &stop.green,
     119             :                                                &stop.blue, &stop.alpha);
     120             :          ++index) {
     121             :         double lightness, darkness;
     122           0 :         GetLightAndDarkness(stop, &lightness, &darkness);
     123           0 :         if (lightness > maxLightness) {
     124           0 :             maxLightness = lightness;
     125           0 :             *aLightColor = stop;
     126             :         }
     127           0 :         if (darkness > maxDarkness) {
     128           0 :             maxDarkness = darkness;
     129           0 :             *aDarkColor = stop;
     130             :         }
     131             :     }
     132             : 
     133           0 :     return true;
     134             : }
     135             : 
     136             : static bool
     137           2 : GetUnicoBorderGradientColors(GtkStyleContext* aContext,
     138             :                              GdkRGBA* aLightColor, GdkRGBA* aDarkColor)
     139             : {
     140             :     // Ubuntu 12.04 has GTK engine Unico-1.0.2, which overrides render_frame,
     141             :     // providing its own border code.  Ubuntu 14.04 has
     142             :     // Unico-1.0.3+14.04.20140109, which does not override render_frame, and
     143             :     // so does not need special attention.  The earlier Unico can be detected
     144             :     // by the -unico-border-gradient style property it registers.
     145             :     // gtk_style_properties_lookup_property() is checked first to avoid the
     146             :     // warning from gtk_style_context_get_property() when the property does
     147             :     // not exist.  (gtk_render_frame() of GTK+ 3.16 no longer uses the
     148             :     // engine.)
     149           2 :     const char* propertyName = "-unico-border-gradient";
     150           2 :     if (!gtk_style_properties_lookup_property(propertyName, nullptr, nullptr))
     151           2 :         return false;
     152             : 
     153             :     // -unico-border-gradient is used only when the CSS node's engine is Unico.
     154             :     GtkThemingEngine* engine;
     155           0 :     GtkStateFlags state = gtk_style_context_get_state(aContext);
     156           0 :     gtk_style_context_get(aContext, state, "engine", &engine, nullptr);
     157           0 :     if (strcmp(g_type_name(G_TYPE_FROM_INSTANCE(engine)), "UnicoEngine") != 0)
     158           0 :         return false;
     159             : 
     160             :     // draw_border() of Unico engine uses -unico-border-gradient
     161             :     // in preference to border-color.
     162           0 :     GValue value = G_VALUE_INIT;
     163           0 :     gtk_style_context_get_property(aContext, propertyName, state, &value);
     164             : 
     165           0 :     bool result = GetGradientColors(&value, aLightColor, aDarkColor);
     166             : 
     167           0 :     g_value_unset(&value);
     168           0 :     return result;
     169             : }
     170             : 
     171             : // Sets |aLightColor| and |aDarkColor| to colors from |aContext|.  Returns
     172             : // true if |aContext| uses these colors to render a visible border.
     173             : // If returning false, then the colors returned are a fallback from the
     174             : // border-color value even though |aContext| does not use these colors to
     175             : // render a border.
     176             : static bool
     177           2 : GetBorderColors(GtkStyleContext* aContext,
     178             :                 GdkRGBA* aLightColor, GdkRGBA* aDarkColor)
     179             : {
     180             :     // Determine whether the border on this style context is visible.
     181           2 :     GtkStateFlags state = gtk_style_context_get_state(aContext);
     182             :     GtkBorderStyle borderStyle;
     183             :     gtk_style_context_get(aContext, state, GTK_STYLE_PROPERTY_BORDER_STYLE,
     184           2 :                           &borderStyle, nullptr);
     185           4 :     bool visible = borderStyle != GTK_BORDER_STYLE_NONE &&
     186           4 :         borderStyle != GTK_BORDER_STYLE_HIDDEN;
     187           2 :     if (visible) {
     188             :         // GTK has an initial value of zero for border-widths, and so themes
     189             :         // need to explicitly set border-widths to make borders visible.
     190             :         GtkBorder border;
     191           2 :         gtk_style_context_get_border(aContext, GTK_STATE_FLAG_NORMAL, &border);
     192           4 :         visible = border.top != 0 || border.right != 0 ||
     193           2 :             border.bottom != 0 || border.left != 0;
     194             :     }
     195             : 
     196           4 :     if (visible &&
     197           2 :         GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor))
     198           0 :         return true;
     199             : 
     200             :     // The initial value for the border-color is the foreground color, and so
     201             :     // this will usually return a color distinct from the background even if
     202             :     // there is no visible border detected.
     203           2 :     gtk_style_context_get_border_color(aContext, state, aDarkColor);
     204             :     // TODO GTK3 - update aLightColor
     205             :     // for GTK_BORDER_STYLE_INSET/OUTSET/GROVE/RIDGE border styles.
     206             :     // https://bugzilla.mozilla.org/show_bug.cgi?id=978172#c25
     207           2 :     *aLightColor = *aDarkColor;
     208           2 :     return visible;
     209             : }
     210             : 
     211             : static bool
     212           2 : GetBorderColors(GtkStyleContext* aContext,
     213             :                 nscolor* aLightColor, nscolor* aDarkColor)
     214             : {
     215             :     GdkRGBA lightColor, darkColor;
     216           2 :     bool ret = GetBorderColors(aContext, &lightColor, &darkColor);
     217           2 :     *aLightColor = GDK_RGBA_TO_NS_RGBA(lightColor);
     218           2 :     *aDarkColor = GDK_RGBA_TO_NS_RGBA(darkColor);
     219           2 :     return ret;
     220             : }
     221             : #endif
     222             : 
     223             : nsresult
     224          54 : nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
     225             : {
     226          54 :     EnsureInit();
     227             : 
     228             : #if (MOZ_WIDGET_GTK == 3)
     229             :     GdkRGBA gdk_color;
     230             : #endif
     231          54 :     nsresult res = NS_OK;
     232             : 
     233          54 :     switch (aID) {
     234             :         // These colors don't seem to be used for anything anymore in Mozilla
     235             :         // (except here at least TextSelectBackground and TextSelectForeground)
     236             :         // The CSS2 colors below are used.
     237             : #if (MOZ_WIDGET_GTK == 2)
     238             :     case eColorID_WindowBackground:
     239             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
     240             :         break;
     241             :     case eColorID_WindowForeground:
     242             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
     243             :         break;
     244             :     case eColorID_WidgetBackground:
     245             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     246             :         break;
     247             :     case eColorID_WidgetForeground:
     248             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
     249             :         break;
     250             :     case eColorID_WidgetSelectBackground:
     251             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
     252             :         break;
     253             :     case eColorID_WidgetSelectForeground:
     254             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]);
     255             :         break;
     256             : #else
     257             :     case eColorID_WindowBackground:
     258             :     case eColorID_WidgetBackground:
     259             :     case eColorID_TextBackground:
     260             :     case eColorID_activecaption: // active window caption background
     261             :     case eColorID_appworkspace: // MDI background color
     262             :     case eColorID_background: // desktop background
     263             :     case eColorID_window:
     264             :     case eColorID_windowframe:
     265             :     case eColorID__moz_dialog:
     266             :     case eColorID__moz_combobox:
     267           7 :         aColor = sMozWindowBackground;
     268           7 :         break;
     269             :     case eColorID_WindowForeground:
     270             :     case eColorID_WidgetForeground:
     271             :     case eColorID_TextForeground: 
     272             :     case eColorID_captiontext: // text in active window caption, size box, and scrollbar arrow box (!)
     273             :     case eColorID_windowtext:
     274             :     case eColorID__moz_dialogtext:
     275           2 :         aColor = sMozWindowText;
     276           2 :         break;
     277             :     case eColorID_WidgetSelectBackground:
     278             :     case eColorID_TextSelectBackground:
     279             :     case eColorID_IMESelectedRawTextBackground:
     280             :     case eColorID_IMESelectedConvertedTextBackground:
     281             :     case eColorID__moz_dragtargetzone:
     282             :     case eColorID__moz_cellhighlight:
     283             :     case eColorID__moz_html_cellhighlight:
     284             :     case eColorID_highlight: // preference selected item,
     285           6 :         aColor = sTextSelectedBackground;
     286           6 :         break;
     287             :     case eColorID_WidgetSelectForeground:
     288             :     case eColorID_TextSelectForeground:
     289             :     case eColorID_IMESelectedRawTextForeground:
     290             :     case eColorID_IMESelectedConvertedTextForeground:
     291             :     case eColorID_highlighttext:
     292             :     case eColorID__moz_cellhighlighttext:
     293             :     case eColorID__moz_html_cellhighlighttext:
     294           6 :         aColor = sTextSelectedText;
     295           6 :         break;
     296             : #endif
     297             :     case eColorID_Widget3DHighlight:
     298           0 :         aColor = NS_RGB(0xa0,0xa0,0xa0);
     299           0 :         break;
     300             :     case eColorID_Widget3DShadow:
     301           0 :         aColor = NS_RGB(0x40,0x40,0x40);
     302           0 :         break;
     303             : #if (MOZ_WIDGET_GTK == 2)
     304             :     case eColorID_TextBackground:
     305             :         // not used?
     306             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
     307             :         break;
     308             :     case eColorID_TextForeground: 
     309             :         // not used?
     310             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
     311             :         break;
     312             :     case eColorID_TextSelectBackground:
     313             :     case eColorID_IMESelectedRawTextBackground:
     314             :     case eColorID_IMESelectedConvertedTextBackground:
     315             :         // still used
     316             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
     317             :         break;
     318             :     case eColorID_TextSelectForeground:
     319             :     case eColorID_IMESelectedRawTextForeground:
     320             :     case eColorID_IMESelectedConvertedTextForeground:
     321             :         // still used
     322             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
     323             :         break;
     324             : #endif
     325             :     case eColorID_IMERawInputBackground:
     326             :     case eColorID_IMEConvertedTextBackground:
     327           0 :         aColor = NS_TRANSPARENT;
     328           0 :         break;
     329             :     case eColorID_IMERawInputForeground:
     330             :     case eColorID_IMEConvertedTextForeground:
     331           0 :         aColor = NS_SAME_AS_FOREGROUND_COLOR;
     332           0 :         break;
     333             :     case eColorID_IMERawInputUnderline:
     334             :     case eColorID_IMEConvertedTextUnderline:
     335           0 :         aColor = NS_SAME_AS_FOREGROUND_COLOR;
     336           0 :         break;
     337             :     case eColorID_IMESelectedRawTextUnderline:
     338             :     case eColorID_IMESelectedConvertedTextUnderline:
     339           0 :         aColor = NS_TRANSPARENT;
     340           0 :         break;
     341             :     case eColorID_SpellCheckerUnderline:
     342           0 :       aColor = NS_RGB(0xff, 0, 0);
     343           0 :       break;
     344             : 
     345             : #if (MOZ_WIDGET_GTK == 2)
     346             :         // css2  http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
     347             :     case eColorID_activeborder:
     348             :         // active window border
     349             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     350             :         break;
     351             :     case eColorID_activecaption:
     352             :         // active window caption background
     353             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     354             :         break;
     355             :     case eColorID_appworkspace:
     356             :         // MDI background color
     357             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     358             :         break;
     359             :     case eColorID_background:
     360             :         // desktop background
     361             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     362             :         break;
     363             :     case eColorID_captiontext:
     364             :         // text in active window caption, size box, and scrollbar arrow box (!)
     365             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
     366             :         break;
     367             :     case eColorID_graytext:
     368             :         // disabled text in windows, menus, etc.
     369             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
     370             :         break;
     371             :     case eColorID_highlight:
     372             :         // background of selected item
     373             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
     374             :         break;
     375             :     case eColorID_highlighttext:
     376             :         // text of selected item
     377             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
     378             :         break;
     379             :     case eColorID_inactiveborder:
     380             :         // inactive window border
     381             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     382             :         break;
     383             :     case eColorID_inactivecaption:
     384             :         // inactive window caption
     385             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_INSENSITIVE]);
     386             :         break;
     387             :     case eColorID_inactivecaptiontext:
     388             :         // text in inactive window caption
     389             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
     390             :         break;
     391             : #else
     392             :         // css2  http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
     393             :     case eColorID_activeborder: {
     394             :         // active window border
     395           0 :         GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
     396             :         gtk_style_context_get_border_color(style,
     397           0 :                                            GTK_STATE_FLAG_NORMAL, &gdk_color);
     398           0 :         aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
     399           0 :         ReleaseStyleContext(style);
     400           0 :         break;
     401             :     }
     402             :     case eColorID_inactiveborder: {
     403             :         // inactive window border
     404           0 :         GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
     405             :         gtk_style_context_get_border_color(style,
     406             :                                            GTK_STATE_FLAG_INSENSITIVE,
     407           0 :                                            &gdk_color);
     408           0 :         aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
     409           0 :         ReleaseStyleContext(style);
     410           0 :         break;
     411             :     }
     412             :     case eColorID_graytext: // disabled text in windows, menus, etc.
     413             :     case eColorID_inactivecaptiontext: // text in inactive window caption
     414           2 :         aColor = sMenuTextInactive;
     415           2 :         break;
     416             :     case eColorID_inactivecaption: {
     417             :         // inactive window caption
     418           0 :         GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
     419             :         gtk_style_context_get_background_color(style,
     420             :                                                GTK_STATE_FLAG_INSENSITIVE, 
     421           0 :                                                &gdk_color);
     422           0 :         aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
     423           0 :         ReleaseStyleContext(style);
     424           0 :         break;
     425             :     }
     426             : #endif
     427             :     case eColorID_infobackground:
     428             :         // tooltip background color
     429           0 :         aColor = sInfoBackground;
     430           0 :         break;
     431             :     case eColorID_infotext:
     432             :         // tooltip text color
     433           1 :         aColor = sInfoText;
     434           1 :         break;
     435             :     case eColorID_menu:
     436             :         // menu background
     437           1 :         aColor = sMenuBackground;
     438           1 :         break;
     439             :     case eColorID_menutext:
     440             :         // menu text
     441           1 :         aColor = sMenuText;
     442           1 :         break;
     443             :     case eColorID_scrollbar:
     444             :         // scrollbar gray area
     445             : #if (MOZ_WIDGET_GTK == 2)
     446             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_ACTIVE]);
     447             : #else
     448           0 :         aColor = sMozScrollbar;
     449             : #endif
     450           0 :         break;
     451             : 
     452             :     case eColorID_threedlightshadow:
     453             :         // 3-D highlighted inner edge color
     454             :         // always same as background in GTK code
     455             :     case eColorID_threedface:
     456             :     case eColorID_buttonface:
     457             :         // 3-D face color
     458             : #if (MOZ_WIDGET_GTK == 3)
     459           4 :         aColor = sMozWindowBackground;
     460             : #else
     461             :         aColor = sButtonBackground;
     462             : #endif
     463           4 :         break;
     464             : 
     465             :     case eColorID_buttontext:
     466             :         // text on push buttons
     467           2 :         aColor = sButtonText;
     468           2 :         break;
     469             : 
     470             :     case eColorID_buttonhighlight:
     471             :         // 3-D highlighted edge color
     472             :     case eColorID_threedhighlight:
     473             :         // 3-D highlighted outer edge color
     474           2 :         aColor = sFrameOuterLightBorder;
     475           2 :         break;
     476             : 
     477             :     case eColorID_buttonshadow:
     478             :         // 3-D shadow edge color
     479             :     case eColorID_threedshadow:
     480             :         // 3-D shadow inner edge color
     481           2 :         aColor = sFrameInnerDarkBorder;
     482           2 :         break;
     483             : 
     484             : #if (MOZ_WIDGET_GTK == 2)
     485             :     case eColorID_threeddarkshadow:
     486             :         // 3-D shadow outer edge color
     487             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
     488             :         break;
     489             : 
     490             :     case eColorID_window:
     491             :     case eColorID_windowframe:
     492             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     493             :         break;
     494             : 
     495             :     case eColorID_windowtext:
     496             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
     497             :         break;
     498             : 
     499             :     case eColorID__moz_eventreerow:
     500             :     case eColorID__moz_field:
     501             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
     502             :         break;
     503             :     case eColorID__moz_fieldtext:
     504             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
     505             :         break;
     506             :     case eColorID__moz_dialog:
     507             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
     508             :         break;
     509             :     case eColorID__moz_dialogtext:
     510             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
     511             :         break;
     512             :     case eColorID__moz_dragtargetzone:
     513             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
     514             :         break; 
     515             :     case eColorID__moz_buttondefault:
     516             :         // default button border color
     517             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
     518             :         break;
     519             :     case eColorID__moz_buttonhoverface:
     520             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_PRELIGHT]);
     521             :         break;
     522             :     case eColorID__moz_buttonhovertext:
     523             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_PRELIGHT]);
     524             :         break;
     525             :     case eColorID__moz_cellhighlight:
     526             :     case eColorID__moz_html_cellhighlight:
     527             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_ACTIVE]);
     528             :         break;
     529             :     case eColorID__moz_cellhighlighttext:
     530             :     case eColorID__moz_html_cellhighlighttext:
     531             :         aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_ACTIVE]);
     532             :         break;
     533             : #else
     534             :     case eColorID_threeddarkshadow:
     535             :         // Hardcode to black
     536           1 :         aColor = NS_RGB(0x00,0x00,0x00);
     537           1 :         break;
     538             : 
     539             :     case eColorID__moz_eventreerow:
     540             :     case eColorID__moz_field:
     541           2 :         aColor = sMozFieldBackground;
     542           2 :         break;
     543             :     case eColorID__moz_fieldtext:
     544           2 :         aColor = sMozFieldText;
     545           2 :         break;
     546             :     case eColorID__moz_buttondefault: {
     547             :         // default button border color
     548           0 :         GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
     549             :         gtk_style_context_get_border_color(style,
     550           0 :                                            GTK_STATE_FLAG_NORMAL, &gdk_color);
     551           0 :         aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
     552           0 :         ReleaseStyleContext(style);
     553           0 :         break;
     554             :     }
     555             :     case eColorID__moz_buttonhoverface: {
     556           2 :         GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
     557             :         gtk_style_context_get_background_color(style,
     558             :                                                GTK_STATE_FLAG_PRELIGHT, 
     559           2 :                                                &gdk_color);
     560           2 :         aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
     561           2 :         ReleaseStyleContext(style);
     562           2 :         break;
     563             :     }
     564             :     case eColorID__moz_buttonhovertext:
     565           2 :         aColor = sButtonHoverText;
     566           2 :         break;
     567             : #endif
     568             :     case eColorID__moz_menuhover:
     569           1 :         aColor = sMenuHover;
     570           1 :         break;
     571             :     case eColorID__moz_menuhovertext:
     572           1 :         aColor = sMenuHoverText;
     573           1 :         break;
     574             :     case eColorID__moz_oddtreerow:
     575           1 :         aColor = sOddCellBackground;
     576           1 :         break;
     577             :     case eColorID__moz_nativehyperlinktext:
     578           1 :         aColor = sNativeHyperLinkText;
     579           1 :         break;
     580             :     case eColorID__moz_comboboxtext:
     581           2 :         aColor = sComboBoxText;
     582           2 :         break;
     583             : #if (MOZ_WIDGET_GTK == 2)
     584             :     case eColorID__moz_combobox:
     585             :         aColor = sComboBoxBackground;
     586             :         break;
     587             : #endif
     588             :     case eColorID__moz_menubartext:
     589           1 :         aColor = sMenuBarText;
     590           1 :         break;
     591             :     case eColorID__moz_menubarhovertext:
     592           1 :         aColor = sMenuBarHoverText;
     593           1 :         break;
     594             :     case eColorID__moz_gtk_info_bar_text:
     595             : #if (MOZ_WIDGET_GTK == 3)
     596           1 :         aColor = sInfoBarText;
     597             : #else
     598             :         aColor = sInfoText;
     599             : #endif
     600           1 :         break;
     601             :     default:
     602             :         /* default color is BLACK */
     603           0 :         aColor = 0;
     604           0 :         res    = NS_ERROR_FAILURE;
     605           0 :         break;
     606             :     }
     607             : 
     608          54 :     return res;
     609             : }
     610             : 
     611             : #if (MOZ_WIDGET_GTK == 2)
     612             : static void darken_gdk_color(GdkColor *src, GdkColor *dest)
     613             : {
     614             :     gdouble red;
     615             :     gdouble green;
     616             :     gdouble blue;
     617             : 
     618             :     red = (gdouble) src->red / 65535.0;
     619             :     green = (gdouble) src->green / 65535.0;
     620             :     blue = (gdouble) src->blue / 65535.0;
     621             : 
     622             :     red *= 0.93;
     623             :     green *= 0.93;
     624             :     blue *= 0.93;
     625             : 
     626             :     dest->red = red * 65535.0;
     627             :     dest->green = green * 65535.0;
     628             :     dest->blue = blue * 65535.0;
     629             : }
     630             : #endif
     631             : 
     632           8 : static int32_t CheckWidgetStyle(GtkWidget* aWidget, const char* aStyle, int32_t aResult) {
     633           8 :     gboolean value = FALSE;
     634           8 :     gtk_widget_style_get(aWidget, aStyle, &value, nullptr);
     635           8 :     return value ? aResult : 0;
     636             : }
     637             : 
     638           2 : static int32_t ConvertGTKStepperStyleToMozillaScrollArrowStyle(GtkWidget* aWidget)
     639             : {
     640           2 :     if (!aWidget)
     641           0 :         return mozilla::LookAndFeel::eScrollArrowStyle_Single;
     642             :   
     643             :     return
     644           2 :         CheckWidgetStyle(aWidget, "has-backward-stepper",
     645           2 :                          mozilla::LookAndFeel::eScrollArrow_StartBackward) |
     646           2 :         CheckWidgetStyle(aWidget, "has-forward-stepper",
     647           2 :                          mozilla::LookAndFeel::eScrollArrow_EndForward) |
     648           2 :         CheckWidgetStyle(aWidget, "has-secondary-backward-stepper",
     649             :                          mozilla::LookAndFeel::eScrollArrow_EndBackward) |
     650           2 :         CheckWidgetStyle(aWidget, "has-secondary-forward-stepper",
     651           2 :                          mozilla::LookAndFeel::eScrollArrow_StartForward);
     652             : }
     653             : 
     654             : nsresult
     655         937 : nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
     656             : {
     657         937 :     nsresult res = NS_OK;
     658             : 
     659             :     // Set these before they can get overrided in the nsXPLookAndFeel. 
     660         937 :     switch (aID) {
     661             :     case eIntID_ScrollButtonLeftMouseButtonAction:
     662           0 :         aResult = 0;
     663           0 :         return NS_OK;
     664             :     case eIntID_ScrollButtonMiddleMouseButtonAction:
     665           0 :         aResult = 1;
     666           0 :         return NS_OK;
     667             :     case eIntID_ScrollButtonRightMouseButtonAction:
     668           0 :         aResult = 2;
     669           0 :         return NS_OK;
     670             :     default:
     671         937 :         break;
     672             :     }
     673             : 
     674         937 :     res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
     675         937 :     if (NS_SUCCEEDED(res))
     676           0 :         return res;
     677         937 :     res = NS_OK;
     678             : 
     679             :     // We use delayed initialization by EnsureInit() here
     680             :     // to make sure mozilla::Preferences is available (Bug 115807).
     681             :     // eIntID_UseAccessibilityTheme is requested before user preferences
     682             :     // are read, and so EnsureInit(), which depends on preference values,
     683             :     // is deliberately delayed until required.
     684         937 :     switch (aID) {
     685             :     case eIntID_CaretBlinkTime:
     686             :         {
     687             :             GtkSettings *settings;
     688             :             gint blink_time;
     689             :             gboolean blink;
     690             : 
     691           0 :             settings = gtk_settings_get_default ();
     692             :             g_object_get (settings,
     693             :                           "gtk-cursor-blink-time", &blink_time,
     694             :                           "gtk-cursor-blink", &blink,
     695           0 :                           nullptr);
     696             :  
     697           0 :             if (blink)
     698           0 :                 aResult = (int32_t) blink_time;
     699             :             else
     700           0 :                 aResult = 0;
     701           0 :             break;
     702             :         }
     703             :     case eIntID_CaretWidth:
     704           0 :         aResult = 1;
     705           0 :         break;
     706             :     case eIntID_ShowCaretDuringSelection:
     707          28 :         aResult = 0;
     708          28 :         break;
     709             :     case eIntID_SelectTextfieldsOnKeyFocus:
     710             :         {
     711             :             GtkWidget *entry;
     712             :             GtkSettings *settings;
     713             :             gboolean select_on_focus;
     714             : 
     715           0 :             entry = gtk_entry_new();
     716           0 :             g_object_ref_sink(entry);
     717           0 :             settings = gtk_widget_get_settings(entry);
     718             :             g_object_get(settings, 
     719             :                          "gtk-entry-select-on-focus",
     720             :                          &select_on_focus,
     721           0 :                          nullptr);
     722             :             
     723           0 :             if(select_on_focus)
     724           0 :                 aResult = 1;
     725             :             else
     726           0 :                 aResult = 0;
     727             : 
     728           0 :             gtk_widget_destroy(entry);
     729           0 :             g_object_unref(entry);
     730             :         }
     731           0 :         break;
     732             :     case eIntID_ScrollToClick:
     733             :         {
     734             :             GtkSettings *settings;
     735           0 :             gboolean warps_slider = FALSE;
     736             : 
     737           0 :             settings = gtk_settings_get_default ();
     738           0 :             if (g_object_class_find_property (G_OBJECT_GET_CLASS(settings),
     739             :                                               "gtk-primary-button-warps-slider")) {
     740             :                 g_object_get (settings,
     741             :                               "gtk-primary-button-warps-slider",
     742             :                               &warps_slider,
     743           0 :                               nullptr);
     744             :             }
     745             : 
     746           0 :             if (warps_slider)
     747           0 :                 aResult = 1;
     748             :             else
     749           0 :                 aResult = 0;
     750             :         }
     751           0 :         break;
     752             :     case eIntID_SubmenuDelay:
     753             :         {
     754             :             GtkSettings *settings;
     755             :             gint delay;
     756             : 
     757           0 :             settings = gtk_settings_get_default ();
     758           0 :             g_object_get (settings, "gtk-menu-popup-delay", &delay, nullptr);
     759           0 :             aResult = (int32_t) delay;
     760           0 :             break;
     761             :         }
     762             :     case eIntID_TooltipDelay:
     763             :         {
     764           4 :             aResult = 500;
     765           4 :             break;
     766             :         }
     767             :     case eIntID_MenusCanOverlapOSBar:
     768             :         // we want XUL popups to be able to overlap the task bar.
     769          44 :         aResult = 1;
     770          44 :         break;
     771             :     case eIntID_SkipNavigatingDisabledMenuItem:
     772           0 :         aResult = 1;
     773           0 :         break;
     774             :     case eIntID_DragThresholdX:
     775             :     case eIntID_DragThresholdY:
     776             :         {
     777           0 :             GtkWidget* box = gtk_hbox_new(FALSE, 5);
     778           0 :             gint threshold = 0;
     779           0 :             g_object_get(gtk_widget_get_settings(box),
     780             :                          "gtk-dnd-drag-threshold", &threshold,
     781           0 :                          nullptr);
     782           0 :             g_object_ref_sink(box);
     783             :             
     784           0 :             aResult = threshold;
     785             :         }
     786           0 :         break;
     787             :     case eIntID_ScrollArrowStyle: {
     788           2 :         GtkWidget* scrollbar = GetWidget(MOZ_GTK_SCROLLBAR_HORIZONTAL);
     789           2 :         aResult = ConvertGTKStepperStyleToMozillaScrollArrowStyle(scrollbar);
     790           2 :         break;
     791             :     }
     792             :     case eIntID_ScrollSliderStyle:
     793           2 :         aResult = eScrollThumbStyle_Proportional;
     794           2 :         break;
     795             :     case eIntID_TreeOpenDelay:
     796           0 :         aResult = 1000;
     797           0 :         break;
     798             :     case eIntID_TreeCloseDelay:
     799           0 :         aResult = 1000;
     800           0 :         break;
     801             :     case eIntID_TreeLazyScrollDelay:
     802           0 :         aResult = 150;
     803           0 :         break;
     804             :     case eIntID_TreeScrollDelay:
     805           0 :         aResult = 100;
     806           0 :         break;
     807             :     case eIntID_TreeScrollLinesMax:
     808           0 :         aResult = 3;
     809           0 :         break;
     810             :     case eIntID_DWMCompositor:
     811             :     case eIntID_WindowsClassic:
     812             :     case eIntID_WindowsDefaultTheme:
     813             :     case eIntID_WindowsThemeIdentifier:
     814             :     case eIntID_OperatingSystemVersionIdentifier:
     815           6 :         aResult = 0;
     816           6 :         res = NS_ERROR_NOT_IMPLEMENTED;
     817           6 :         break;
     818             :     case eIntID_TouchEnabled:
     819             : #if MOZ_WIDGET_GTK == 3
     820           2 :         aResult = mozilla::widget::WidgetUtils::IsTouchDeviceSupportPresent();
     821           2 :         break;
     822             : #else
     823             :         aResult = 0;
     824             :         res = NS_ERROR_NOT_IMPLEMENTED;
     825             : #endif
     826             :         break;
     827             :     case eIntID_MacGraphiteTheme:
     828           2 :         aResult = 0;
     829           2 :         res = NS_ERROR_NOT_IMPLEMENTED;
     830           2 :         break;
     831             :     case eIntID_AlertNotificationOrigin:
     832           0 :         aResult = NS_ALERT_TOP;
     833           0 :         break;
     834             :     case eIntID_IMERawInputUnderlineStyle:
     835             :     case eIntID_IMEConvertedTextUnderlineStyle:
     836           0 :         aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
     837           0 :         break;
     838             :     case eIntID_IMESelectedRawTextUnderlineStyle:
     839             :     case eIntID_IMESelectedConvertedTextUnderline:
     840           0 :         aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
     841           0 :         break;
     842             :     case eIntID_SpellCheckerUnderlineStyle:
     843           0 :         aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
     844           0 :         break;
     845             :     case eIntID_MenuBarDrag:
     846           2 :         EnsureInit();
     847           2 :         aResult = sMenuSupportsDrag;
     848           2 :         break;
     849             :     case eIntID_ScrollbarButtonAutoRepeatBehavior:
     850           0 :         aResult = 1;
     851           0 :         break;
     852             :     case eIntID_SwipeAnimationEnabled:
     853           2 :         aResult = 0;
     854           2 :         break;
     855             :     case eIntID_ColorPickerAvailable:
     856           2 :         aResult = 1;
     857           2 :         break;
     858             :     case eIntID_ContextMenuOffsetVertical:
     859             :     case eIntID_ContextMenuOffsetHorizontal:
     860           0 :         aResult = 2;
     861           0 :         break;
     862             :     default:
     863         841 :         aResult = 0;
     864         841 :         res     = NS_ERROR_FAILURE;
     865             :     }
     866             : 
     867         937 :     return res;
     868             : }
     869             : 
     870             : nsresult
     871           0 : nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
     872             : {
     873           0 :     nsresult res = NS_OK;
     874           0 :     res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
     875           0 :     if (NS_SUCCEEDED(res))
     876           0 :         return res;
     877           0 :     res = NS_OK;
     878             : 
     879           0 :     switch (aID) {
     880             :     case eFloatID_IMEUnderlineRelativeSize:
     881           0 :         aResult = 1.0f;
     882           0 :         break;
     883             :     case eFloatID_SpellCheckerUnderlineRelativeSize:
     884           0 :         aResult = 1.0f;
     885           0 :         break;
     886             :     case eFloatID_CaretAspectRatio:
     887           0 :         EnsureInit();
     888           0 :         aResult = sCaretRatio;
     889           0 :         break;
     890             :     default:
     891           0 :         aResult = -1.0;
     892           0 :         res = NS_ERROR_FAILURE;
     893             :     }
     894           0 :     return res;
     895             : }
     896             : 
     897             : static void
     898           2 : GetSystemFontInfo(GtkWidget *aWidget,
     899             :                   nsString *aFontName,
     900             :                   gfxFontStyle *aFontStyle)
     901             : {
     902           2 :     GtkSettings *settings = gtk_widget_get_settings(aWidget);
     903             : 
     904           2 :     aFontStyle->style       = NS_FONT_STYLE_NORMAL;
     905             : 
     906             :     gchar *fontname;
     907           2 :     g_object_get(settings, "gtk-font-name", &fontname, nullptr);
     908             : 
     909             :     PangoFontDescription *desc;
     910           2 :     desc = pango_font_description_from_string(fontname);
     911             : 
     912           2 :     aFontStyle->systemFont = true;
     913             : 
     914           2 :     g_free(fontname);
     915             : 
     916           2 :     NS_NAMED_LITERAL_STRING(quote, "\"");
     917           4 :     NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc));
     918           2 :     *aFontName = quote + family + quote;
     919             : 
     920           2 :     aFontStyle->weight = pango_font_description_get_weight(desc);
     921             : 
     922             :     // FIXME: Set aFontStyle->stretch correctly!
     923           2 :     aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
     924             : 
     925           2 :     float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE;
     926             : 
     927             :     // |size| is now either pixels or pango-points (not Mozilla-points!)
     928             : 
     929           2 :     if (!pango_font_description_get_size_is_absolute(desc)) {
     930             :         // |size| is in pango-points, so convert to pixels.
     931           2 :         size *= float(gfxPlatformGtk::GetDPI()) / POINTS_PER_INCH_FLOAT;
     932             :     }
     933             : 
     934             :     // Scale fonts up on HiDPI displays.
     935             :     // This would be done automatically with cairo, but we manually manage
     936             :     // the display scale for platform consistency.
     937           2 :     size *= ScreenHelperGTK::GetGTKMonitorScaleFactor();
     938             : 
     939             :     // |size| is now pixels
     940             : 
     941           2 :     aFontStyle->size = size;
     942             : 
     943           2 :     pango_font_description_free(desc);
     944           2 : }
     945             : 
     946             : static void
     947           2 : GetSystemFontInfo(LookAndFeel::FontID aID,
     948             :                   nsString *aFontName,
     949             :                   gfxFontStyle *aFontStyle)
     950             : {
     951           2 :     if (aID == LookAndFeel::eFont_Widget) {
     952           1 :         GtkWidget *label = gtk_label_new("M");
     953           1 :         GtkWidget *parent = gtk_fixed_new();
     954           1 :         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
     955             : 
     956           1 :         gtk_container_add(GTK_CONTAINER(parent), label);
     957           1 :         gtk_container_add(GTK_CONTAINER(window), parent);
     958             : 
     959           1 :         gtk_widget_ensure_style(label);
     960           1 :         GetSystemFontInfo(label, aFontName, aFontStyle);
     961           1 :         gtk_widget_destroy(window);  // no unref, windows are different
     962             : 
     963           1 :     } else if (aID == LookAndFeel::eFont_Button) {
     964           0 :         GtkWidget *label = gtk_label_new("M");
     965           0 :         GtkWidget *parent = gtk_fixed_new();
     966           0 :         GtkWidget *button = gtk_button_new();
     967           0 :         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
     968             : 
     969           0 :         gtk_container_add(GTK_CONTAINER(button), label);
     970           0 :         gtk_container_add(GTK_CONTAINER(parent), button);
     971           0 :         gtk_container_add(GTK_CONTAINER(window), parent);
     972             : 
     973           0 :         gtk_widget_ensure_style(label);
     974           0 :         GetSystemFontInfo(label, aFontName, aFontStyle);
     975           0 :         gtk_widget_destroy(window);  // no unref, windows are different
     976             : 
     977           1 :     } else if (aID == LookAndFeel::eFont_Field) {
     978           0 :         GtkWidget *entry = gtk_entry_new();
     979           0 :         GtkWidget *parent = gtk_fixed_new();
     980           0 :         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
     981             : 
     982           0 :         gtk_container_add(GTK_CONTAINER(parent), entry);
     983           0 :         gtk_container_add(GTK_CONTAINER(window), parent);
     984             : 
     985           0 :         gtk_widget_ensure_style(entry);
     986           0 :         GetSystemFontInfo(entry, aFontName, aFontStyle);
     987           0 :         gtk_widget_destroy(window);  // no unref, windows are different
     988             : 
     989             :     } else {
     990           1 :         MOZ_ASSERT(aID == LookAndFeel::eFont_Menu, "unexpected font ID");
     991           1 :         GtkWidget *accel_label = gtk_accel_label_new("M");
     992           1 :         GtkWidget *menuitem = gtk_menu_item_new();
     993           1 :         GtkWidget *menu = gtk_menu_new();
     994           1 :         g_object_ref_sink(menu);
     995             : 
     996           1 :         gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
     997           1 :         gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(menu), menuitem);
     998             : 
     999           1 :         gtk_widget_ensure_style(accel_label);
    1000           1 :         GetSystemFontInfo(accel_label, aFontName, aFontStyle);
    1001           1 :         g_object_unref(menu);
    1002             :     }
    1003           2 : }
    1004             : 
    1005             : bool
    1006           6 : nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
    1007             :                            gfxFontStyle& aFontStyle,
    1008             :                            float aDevPixPerCSSPixel)
    1009             : {
    1010           6 :   nsString *cachedFontName = nullptr;
    1011           6 :   gfxFontStyle *cachedFontStyle = nullptr;
    1012           6 :   bool *isCached = nullptr;
    1013             : 
    1014           6 :   switch (aID) {
    1015             :     case eFont_Menu:         // css2
    1016             :     case eFont_PullDownMenu: // css3
    1017           3 :       cachedFontName = &mMenuFontName;
    1018           3 :       cachedFontStyle = &mMenuFontStyle;
    1019           3 :       isCached = &mMenuFontCached;
    1020           3 :       aID = eFont_Menu;
    1021           3 :       break;
    1022             : 
    1023             :     case eFont_Field:        // css3
    1024             :     case eFont_List:         // css3
    1025           0 :       cachedFontName = &mFieldFontName;
    1026           0 :       cachedFontStyle = &mFieldFontStyle;
    1027           0 :       isCached = &mFieldFontCached;
    1028           0 :       aID = eFont_Field;
    1029           0 :       break;
    1030             : 
    1031             :     case eFont_Button:       // css3
    1032           0 :       cachedFontName = &mButtonFontName;
    1033           0 :       cachedFontStyle = &mButtonFontStyle;
    1034           0 :       isCached = &mButtonFontCached;
    1035           0 :       break;
    1036             : 
    1037             :     case eFont_Caption:      // css2
    1038             :     case eFont_Icon:         // css2
    1039             :     case eFont_MessageBox:   // css2
    1040             :     case eFont_SmallCaption: // css2
    1041             :     case eFont_StatusBar:    // css2
    1042             :     case eFont_Window:       // css3
    1043             :     case eFont_Document:     // css3
    1044             :     case eFont_Workspace:    // css3
    1045             :     case eFont_Desktop:      // css3
    1046             :     case eFont_Info:         // css3
    1047             :     case eFont_Dialog:       // css3
    1048             :     case eFont_Tooltips:     // moz
    1049             :     case eFont_Widget:       // moz
    1050           3 :       cachedFontName = &mDefaultFontName;
    1051           3 :       cachedFontStyle = &mDefaultFontStyle;
    1052           3 :       isCached = &mDefaultFontCached;
    1053           3 :       aID = eFont_Widget;
    1054           3 :       break;
    1055             :   }
    1056             : 
    1057           6 :   if (!*isCached) {
    1058           2 :     GetSystemFontInfo(aID, cachedFontName, cachedFontStyle);
    1059           2 :     *isCached = true;
    1060             :   }
    1061             : 
    1062           6 :   aFontName = *cachedFontName;
    1063           6 :   aFontStyle = *cachedFontStyle;
    1064           6 :   return true;
    1065             : }
    1066             : 
    1067             : void
    1068          56 : nsLookAndFeel::EnsureInit()
    1069             : {
    1070             :     GdkColor colorValue;
    1071             :     GdkColor *colorValuePtr;
    1072             : 
    1073          56 :     if (mInitialized)
    1074          54 :         return;
    1075           2 :     mInitialized = true;
    1076             : 
    1077             : #if (MOZ_WIDGET_GTK == 2)
    1078             :     NS_ASSERTION(!mStyle, "already initialized");
    1079             :     // GtkInvisibles come with a refcount that is not floating
    1080             :     // (since their initialization code calls g_object_ref_sink) and
    1081             :     // their destroy code releases that reference (which means they
    1082             :     // have to be explicitly destroyed, since calling unref enough
    1083             :     // to cause destruction would lead to *another* unref).
    1084             :     // However, this combination means that it's actually still ok
    1085             :     // to use the normal pattern, which is to g_object_ref_sink
    1086             :     // after construction, and then destroy *and* unref when we're
    1087             :     // done.  (Though we could skip the g_object_ref_sink and the
    1088             :     // corresponding g_object_unref, but that's particular to
    1089             :     // GtkInvisibles and GtkWindows.)
    1090             :     GtkWidget *widget = gtk_invisible_new();
    1091             :     g_object_ref_sink(widget); // effectively g_object_ref (see above)
    1092             : 
    1093             :     gtk_widget_ensure_style(widget);
    1094             :     mStyle = gtk_style_copy(gtk_widget_get_style(widget));
    1095             : 
    1096             :     gtk_widget_destroy(widget);
    1097             :     g_object_unref(widget);
    1098             :         
    1099             :     // tooltip foreground and background
    1100             :     GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
    1101             :                                                 "gtk-tooltips", "GtkWindow",
    1102             :                                                 GTK_TYPE_WINDOW);
    1103             :     if (style) {
    1104             :         sInfoBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
    1105             :         sInfoText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
    1106             :     }
    1107             : 
    1108             :     // menu foreground & menu background
    1109             :     GtkWidget *accel_label = gtk_accel_label_new("M");
    1110             :     GtkWidget *menuitem = gtk_menu_item_new();
    1111             :     GtkWidget *menu = gtk_menu_new();
    1112             : 
    1113             :     g_object_ref_sink(menu);
    1114             : 
    1115             :     gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
    1116             :     gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
    1117             : 
    1118             :     gtk_widget_set_style(accel_label, nullptr);
    1119             :     gtk_widget_set_style(menu, nullptr);
    1120             :     gtk_widget_realize(menu);
    1121             :     gtk_widget_realize(accel_label);
    1122             : 
    1123             :     style = gtk_widget_get_style(accel_label);
    1124             :     if (style) {
    1125             :         sMenuText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
    1126             :     }
    1127             : 
    1128             :     style = gtk_widget_get_style(menu);
    1129             :     if (style) {
    1130             :         sMenuBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
    1131             :     }
    1132             :     
    1133             :     style = gtk_widget_get_style(menuitem);
    1134             :     if (style) {
    1135             :         sMenuHover = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_PRELIGHT]);
    1136             :         sMenuHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_PRELIGHT]);
    1137             :     }
    1138             : 
    1139             :     g_object_unref(menu);
    1140             : #else
    1141             :     GdkRGBA color;
    1142             :     GtkStyleContext *style;
    1143             : 
    1144             :     // Gtk manages a screen's CSS in the settings object so we
    1145             :     // ask Gtk to create it explicitly. Otherwise we may end up
    1146             :     // with wrong color theme, see Bug 972382
    1147           2 :     GtkSettings *settings = gtk_settings_get_for_screen(gdk_screen_get_default());
    1148             : 
    1149             :     // Dark themes interacts poorly with widget styling (see bug 1216658).
    1150             :     // We disable dark themes by default for all processes (chrome, web content)
    1151             :     // but allow user to overide it by prefs.
    1152           2 :     const gchar* dark_setting = "gtk-application-prefer-dark-theme";
    1153             :     gboolean darkThemeDefault;
    1154           2 :     g_object_get(settings, dark_setting, &darkThemeDefault, nullptr);
    1155             : 
    1156             :     // To avoid triggering reload of theme settings unnecessarily, only set the
    1157             :     // setting when necessary.
    1158           2 :     if (darkThemeDefault) {
    1159             :         bool allowDarkTheme;
    1160           0 :         if (XRE_IsContentProcess()) {
    1161             :             allowDarkTheme =
    1162             :                 mozilla::Preferences::GetBool("widget.content.allow-gtk-dark-theme",
    1163           0 :                                               false);
    1164             :         } else {
    1165           0 :             allowDarkTheme = (PR_GetEnv("MOZ_ALLOW_GTK_DARK_THEME") != nullptr) ||
    1166           0 :                 mozilla::Preferences::GetBool("widget.chrome.allow-gtk-dark-theme",
    1167             :                                               false);
    1168             :         }
    1169           0 :         if (!allowDarkTheme) {
    1170           0 :             g_object_set(settings, dark_setting, FALSE, nullptr);
    1171             :         }
    1172             :     }
    1173             : 
    1174             :     // Allow content Gtk theme override by pref, it's useful when styled Gtk+
    1175             :     // widgets break web content.
    1176           2 :     if (XRE_IsContentProcess()) {
    1177             :         auto contentThemeName =
    1178           2 :             mozilla::Preferences::GetCString("widget.content.gtk-theme-override");
    1179           1 :         if (!contentThemeName.IsEmpty()) {
    1180           0 :             g_object_set(settings, "gtk-theme-name", contentThemeName.get(), nullptr);
    1181             :         }
    1182             :     }
    1183             : 
    1184             :     // Scrollbar colors
    1185           2 :     style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
    1186           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1187           2 :     sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
    1188           2 :     ReleaseStyleContext(style);
    1189             : 
    1190             :     // Window colors
    1191           2 :     style = ClaimStyleContext(MOZ_GTK_WINDOW);
    1192           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1193           2 :     sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
    1194           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1195           2 :     sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
    1196           2 :     ReleaseStyleContext(style);
    1197             : 
    1198             :     // tooltip foreground and background
    1199           2 :     style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
    1200           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1201           2 :     sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
    1202           2 :     ReleaseStyleContext(style);
    1203             : 
    1204           2 :     style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
    1205           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1206           2 :     sInfoText = GDK_RGBA_TO_NS_RGBA(color);
    1207           2 :     ReleaseStyleContext(style);
    1208             : 
    1209           2 :     style = ClaimStyleContext(MOZ_GTK_MENUITEM);
    1210             :     {
    1211             :         GtkStyleContext* accelStyle =
    1212           2 :             CreateStyleForWidget(gtk_accel_label_new("M"), style);
    1213           2 :         gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_NORMAL, &color);
    1214           2 :         sMenuText = GDK_RGBA_TO_NS_RGBA(color);
    1215           2 :         gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_INSENSITIVE, &color);
    1216           2 :         sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
    1217           2 :         g_object_unref(accelStyle);
    1218             :     }
    1219           2 :     ReleaseStyleContext(style);
    1220             : 
    1221           2 :     style = ClaimStyleContext(MOZ_GTK_MENUPOPUP);
    1222           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1223           2 :     sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
    1224           2 :     ReleaseStyleContext(style);
    1225             : 
    1226           2 :     style = ClaimStyleContext(MOZ_GTK_MENUITEM);
    1227           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
    1228           2 :     sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
    1229           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
    1230           2 :     sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
    1231           2 :     ReleaseStyleContext(style);
    1232             : #endif
    1233             : 
    1234             :     // button styles
    1235           2 :     GtkWidget *parent = gtk_fixed_new();
    1236           2 :     GtkWidget *button = gtk_button_new();
    1237           2 :     GtkWidget *label = gtk_label_new("M");
    1238             : #if (MOZ_WIDGET_GTK == 2)
    1239             :     GtkWidget *combobox = gtk_combo_box_new();
    1240             :     GtkWidget *comboboxLabel = gtk_label_new("M");
    1241             :     gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel);
    1242             : #endif
    1243           2 :     GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
    1244           2 :     GtkWidget *treeView = gtk_tree_view_new();
    1245           2 :     GtkWidget *linkButton = gtk_link_button_new("http://example.com/");
    1246           2 :     GtkWidget *menuBar = gtk_menu_bar_new();
    1247           2 :     GtkWidget *menuBarItem = gtk_menu_item_new();
    1248           2 :     GtkWidget *entry = gtk_entry_new();
    1249           2 :     GtkWidget *textView = gtk_text_view_new();
    1250             : 
    1251           2 :     gtk_container_add(GTK_CONTAINER(button), label);
    1252           2 :     gtk_container_add(GTK_CONTAINER(parent), button);
    1253           2 :     gtk_container_add(GTK_CONTAINER(parent), treeView);
    1254           2 :     gtk_container_add(GTK_CONTAINER(parent), linkButton);
    1255             : #if (MOZ_WIDGET_GTK == 2)
    1256             :     gtk_container_add(GTK_CONTAINER(parent), combobox);
    1257             : #endif
    1258           2 :     gtk_container_add(GTK_CONTAINER(parent), menuBar);
    1259           2 :     gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuBarItem);
    1260           2 :     gtk_container_add(GTK_CONTAINER(window), parent);
    1261           2 :     gtk_container_add(GTK_CONTAINER(parent), entry);
    1262           2 :     gtk_container_add(GTK_CONTAINER(parent), textView);
    1263             :     
    1264             : #if (MOZ_WIDGET_GTK == 2)
    1265             :     gtk_widget_set_style(button, nullptr);
    1266             :     gtk_widget_set_style(label, nullptr);
    1267             :     gtk_widget_set_style(treeView, nullptr);
    1268             :     gtk_widget_set_style(linkButton, nullptr);
    1269             :     gtk_widget_set_style(combobox, nullptr);
    1270             :     gtk_widget_set_style(comboboxLabel, nullptr);
    1271             :     gtk_widget_set_style(menuBar, nullptr);
    1272             :     gtk_widget_set_style(entry, nullptr);
    1273             : 
    1274             :     gtk_widget_realize(button);
    1275             :     gtk_widget_realize(label);
    1276             :     gtk_widget_realize(treeView);
    1277             :     gtk_widget_realize(linkButton);
    1278             :     gtk_widget_realize(combobox);
    1279             :     gtk_widget_realize(comboboxLabel);
    1280             :     gtk_widget_realize(menuBar);
    1281             :     gtk_widget_realize(entry);
    1282             : 
    1283             :     style = gtk_widget_get_style(label);
    1284             :     if (style) {
    1285             :         sButtonText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
    1286             :     }
    1287             : 
    1288             :     style = gtk_widget_get_style(comboboxLabel);
    1289             :     if (style) {
    1290             :         sComboBoxText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
    1291             :     }
    1292             :     style = gtk_widget_get_style(combobox);
    1293             :     if (style) {
    1294             :         sComboBoxBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
    1295             :     }
    1296             : 
    1297             :     style = gtk_widget_get_style(menuBar);
    1298             :     if (style) {
    1299             :         sMenuBarText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
    1300             :         sMenuBarHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_SELECTED]);
    1301             :     }
    1302             : 
    1303             :     // GTK's guide to fancy odd row background colors:
    1304             :     // 1) Check if a theme explicitly defines an odd row color
    1305             :     // 2) If not, check if it defines an even row color, and darken it
    1306             :     //    slightly by a hardcoded value (gtkstyle.c)
    1307             :     // 3) If neither are defined, take the base background color and
    1308             :     //    darken that by a hardcoded value
    1309             :     colorValuePtr = nullptr;
    1310             :     gtk_widget_style_get(treeView,
    1311             :                          "odd-row-color", &colorValuePtr,
    1312             :                          nullptr);
    1313             : 
    1314             :     if (colorValuePtr) {
    1315             :         colorValue = *colorValuePtr;
    1316             :     } else {
    1317             :         gtk_widget_style_get(treeView,
    1318             :                              "even-row-color", &colorValuePtr,
    1319             :                              nullptr);
    1320             :         if (colorValuePtr)
    1321             :             darken_gdk_color(colorValuePtr, &colorValue);
    1322             :         else
    1323             :             darken_gdk_color(&treeView->style->base[GTK_STATE_NORMAL], &colorValue);
    1324             :     }
    1325             : 
    1326             :     sOddCellBackground = GDK_COLOR_TO_NS_RGB(colorValue);
    1327             :     if (colorValuePtr)
    1328             :         gdk_color_free(colorValuePtr);
    1329             : 
    1330             :     style = gtk_widget_get_style(button);
    1331             :     if (style) {
    1332             :         sButtonBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
    1333             :         sFrameOuterLightBorder =
    1334             :             GDK_COLOR_TO_NS_RGB(style->light[GTK_STATE_NORMAL]);
    1335             :         sFrameInnerDarkBorder =
    1336             :             GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]);
    1337             :     }
    1338             : #else
    1339             :     // Text colors
    1340             :     GdkRGBA bgColor;
    1341             :     // If the text window background is translucent, then the background of
    1342             :     // the textview root node is visible.
    1343           2 :     style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW);
    1344             :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
    1345           2 :                                            &bgColor);
    1346           2 :     ReleaseStyleContext(style);
    1347             : 
    1348           2 :     style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
    1349             :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
    1350           2 :                                            &color);
    1351           2 :     ApplyColorOver(color, &bgColor);
    1352           2 :     sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor);
    1353           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1354           2 :     sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
    1355             : 
    1356             :     // Selected text and background
    1357             :     gtk_style_context_get_background_color(style,
    1358             :         static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
    1359           2 :         &color);
    1360           2 :     sTextSelectedBackground = GDK_RGBA_TO_NS_RGBA(color);
    1361             :     gtk_style_context_get_color(style,
    1362             :         static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
    1363           2 :         &color);
    1364           2 :     sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
    1365           2 :     ReleaseStyleContext(style);
    1366             : 
    1367             :     // Button text color
    1368           2 :     style = ClaimStyleContext(MOZ_GTK_BUTTON);
    1369             :     {
    1370             :         GtkStyleContext* labelStyle =
    1371           2 :             CreateStyleForWidget(gtk_label_new("M"), style);
    1372           2 :         gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
    1373           2 :         sButtonText = GDK_RGBA_TO_NS_RGBA(color);
    1374           2 :         gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color);
    1375           2 :         sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
    1376           2 :         g_object_unref(labelStyle);
    1377             :     }
    1378           2 :     ReleaseStyleContext(style);
    1379             : 
    1380             :     // Combobox text color
    1381           2 :     style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
    1382           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1383           2 :     sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
    1384           2 :     ReleaseStyleContext(style);
    1385             : 
    1386             :     // Menubar text and hover text colors    
    1387           2 :     style = ClaimStyleContext(MOZ_GTK_MENUBARITEM);
    1388           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1389           2 :     sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
    1390           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
    1391           2 :     sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
    1392           2 :     ReleaseStyleContext(style);
    1393             : 
    1394             :     // GTK's guide to fancy odd row background colors:
    1395             :     // 1) Check if a theme explicitly defines an odd row color
    1396             :     // 2) If not, check if it defines an even row color, and darken it
    1397             :     //    slightly by a hardcoded value (gtkstyle.c)
    1398             :     // 3) If neither are defined, take the base background color and
    1399             :     //    darken that by a hardcoded value
    1400           2 :     style = ClaimStyleContext(MOZ_GTK_TREEVIEW);
    1401             : 
    1402             :     // Get odd row background color
    1403           2 :     gtk_style_context_save(style);
    1404           2 :     gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
    1405           2 :     gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1406           2 :     sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
    1407           2 :     gtk_style_context_restore(style);
    1408           2 :     ReleaseStyleContext(style);
    1409             : 
    1410             :     // GtkFrame has a "border" subnode on which Adwaita draws the border.
    1411             :     // Some themes do not draw on this node but draw a border on the widget
    1412             :     // root node, so check the root node if no border is found on the border
    1413             :     // node.
    1414           2 :     style = ClaimStyleContext(MOZ_GTK_FRAME_BORDER);
    1415             :     bool themeUsesColors =
    1416           2 :         GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
    1417           2 :     ReleaseStyleContext(style);
    1418           2 :     if (!themeUsesColors) {
    1419           0 :         style = ClaimStyleContext(MOZ_GTK_FRAME);
    1420           0 :         GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
    1421           0 :         ReleaseStyleContext(style);
    1422             :     }
    1423             : 
    1424             :     // GtkInfoBar
    1425             :     // TODO - Use WidgetCache for it?
    1426           2 :     GtkWidget* infoBar = gtk_info_bar_new();
    1427           2 :     GtkWidget* infoBarContent = gtk_info_bar_get_content_area(GTK_INFO_BAR(infoBar));
    1428           2 :     GtkWidget* infoBarLabel = gtk_label_new(nullptr);
    1429           2 :     gtk_container_add(GTK_CONTAINER(parent), infoBar);
    1430           2 :     gtk_container_add(GTK_CONTAINER(infoBarContent), infoBarLabel);
    1431           2 :     style = gtk_widget_get_style_context(infoBarLabel);
    1432           2 :     gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
    1433           2 :     gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
    1434           2 :     sInfoBarText = GDK_RGBA_TO_NS_RGBA(color);
    1435             : #endif
    1436             :     // Some themes have a unified menu bar, and support window dragging on it
    1437           2 :     gboolean supports_menubar_drag = FALSE;
    1438             :     GParamSpec *param_spec =
    1439           2 :         gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(menuBar),
    1440           2 :                                              "window-dragging");
    1441           2 :     if (param_spec) {
    1442           2 :         if (g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(param_spec), G_TYPE_BOOLEAN)) {
    1443             :             gtk_widget_style_get(menuBar,
    1444             :                                  "window-dragging", &supports_menubar_drag,
    1445           2 :                                  nullptr);
    1446             :         }
    1447             :     }
    1448           2 :     sMenuSupportsDrag = supports_menubar_drag;
    1449             : 
    1450           2 :     colorValuePtr = nullptr;
    1451           2 :     gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr);
    1452           2 :     if (colorValuePtr) {
    1453           0 :         colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB
    1454           0 :         sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue);
    1455           0 :         gdk_color_free(colorValuePtr);
    1456             :     } else {
    1457           2 :         sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE);
    1458             :     }
    1459             : 
    1460             :     // invisible character styles
    1461             :     guint value;
    1462           2 :     g_object_get (entry, "invisible-char", &value, nullptr);
    1463           2 :     sInvisibleCharacter = char16_t(value);
    1464             : 
    1465             :     // caret styles
    1466           2 :     gtk_widget_style_get(entry,
    1467             :                          "cursor-aspect-ratio", &sCaretRatio,
    1468           2 :                          nullptr);
    1469             : 
    1470           2 :     gtk_widget_destroy(window);
    1471             : }
    1472             : 
    1473             : // virtual
    1474             : char16_t
    1475           0 : nsLookAndFeel::GetPasswordCharacterImpl()
    1476             : {
    1477           0 :     EnsureInit();
    1478           0 :     return sInvisibleCharacter;
    1479             : }
    1480             : 
    1481             : void
    1482           0 : nsLookAndFeel::RefreshImpl()
    1483             : {
    1484           0 :     nsXPLookAndFeel::RefreshImpl();
    1485           0 :     moz_gtk_refresh();
    1486             : 
    1487           0 :     mDefaultFontCached = false;
    1488           0 :     mButtonFontCached = false;
    1489           0 :     mFieldFontCached = false;
    1490           0 :     mMenuFontCached = false;
    1491             : 
    1492             : #if (MOZ_WIDGET_GTK == 2)
    1493             :     g_object_unref(mStyle);
    1494             :     mStyle = nullptr;
    1495             : #endif
    1496             : 
    1497           0 :     mInitialized = false;
    1498           0 : }
    1499             : 
    1500             : bool
    1501           0 : nsLookAndFeel::GetEchoPasswordImpl() {
    1502           0 :     return false;
    1503             : }

Generated by: LCOV version 1.13