mozilla-gtk3_20.patch
branchfirefox48
changeset 926 6ab8b16f232c
parent 919 6838f0c032f8
equal deleted inserted replaced
925:05d175c5957e 926:6ab8b16f232c
     1 diff -up firefox-46.0.1/widget/gtk/gtk3drawing.c.gtk3-20 firefox-46.0.1/widget/gtk/gtk3drawing.c
     1 diff -up firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20 firefox-48.0/widget/gtk/gtk3drawing.cpp
     2 --- firefox-46.0.1/widget/gtk/gtk3drawing.c.gtk3-20	2016-05-03 07:31:12.000000000 +0200
     2 --- firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20	2016-07-25 22:22:07.000000000 +0200
     3 +++ firefox-46.0.1/widget/gtk/gtk3drawing.c	2016-05-20 15:05:08.750151522 +0200
     3 +++ firefox-48.0/widget/gtk/gtk3drawing.cpp	2016-07-29 09:15:11.822285857 +0200
     4 @@ -17,34 +17,86 @@
     4 @@ -18,15 +18,9 @@
     5  
     5  
     6  #include <math.h>
     6  #include <math.h>
     7  
     7  
     8 +#define MOZ_WIDGET_STYLES 4
     8 -static GtkWidget* gProtoWindow;
     9 +
       
    10 +typedef struct {
       
    11 +    GtkWidget*            widget;
       
    12 +
       
    13 +    union {
       
    14 +        struct {
       
    15 +            GtkStyleContext*  style;
       
    16 +            GtkStyleContext*  styleSelection;
       
    17 +        } entry;
       
    18 +
       
    19 +        struct {
       
    20 +            GtkStyleContext*  style;
       
    21 +        } button;
       
    22 +
       
    23 +        struct {
       
    24 +            GtkStyleContext*  style;
       
    25 +            GtkStyleContext*  styleBackground;
       
    26 +        } tooltip;
       
    27 +
       
    28 +        struct {
       
    29 +            GtkStyleContext*  style;
       
    30 +            GtkStyleContext*  styleContents;
       
    31 +            GtkStyleContext*  styleTrough;
       
    32 +            GtkStyleContext*  styleSlider;
       
    33 +        } scroll;
       
    34 +
       
    35 +        struct {
       
    36 +            GtkStyleContext*  style;
       
    37 +            GtkStyleContext*  styleCheck;
       
    38 +            GtkStyleContext*  styleLabel;
       
    39 +        } check;
       
    40 +
       
    41 +        struct {
       
    42 +            GtkStyleContext*  style;
       
    43 +            GtkStyleContext*  styleTrough;
       
    44 +            GtkStyleContext*  styleProgress;
       
    45 +        } progress;
       
    46 +
       
    47 +        struct {
       
    48 +            GtkStyleContext*  style;
       
    49 +            GtkStyleContext*  styleEntry;
       
    50 +            GtkStyleContext*  styleButtonUp;
       
    51 +            GtkStyleContext*  styleButtonDown;
       
    52 +        } spin;
       
    53 +
       
    54 +        struct {
       
    55 +            GtkStyleContext*  style[MOZ_WIDGET_STYLES];
       
    56 +        } all;
       
    57 +    };
       
    58 +} MozGtkWidget;
       
    59 +
       
    60  static GtkWidget* gProtoWindow;
       
    61  static GtkWidget* gProtoLayout;
     9  static GtkWidget* gProtoLayout;
    62 -static GtkWidget* gButtonWidget;
    10 -static GtkWidget* gButtonWidget;
    63 +static MozGtkWidget gButton;
    11 -static GtkWidget* gToggleButtonWidget;
    64  static GtkWidget* gToggleButtonWidget;
    12 -static GtkWidget* gButtonArrowWidget;
    65  static GtkWidget* gButtonArrowWidget;
       
    66 -static GtkWidget* gCheckboxWidget;
       
    67 -static GtkWidget* gRadiobuttonWidget;
       
    68 -static GtkWidget* gHorizScrollbarWidget;
       
    69 -static GtkWidget* gVertScrollbarWidget;
       
    70 -static GtkWidget* gSpinWidget;
    13 -static GtkWidget* gSpinWidget;
    71 +static MozGtkWidget gCheckbox;
       
    72 +static MozGtkWidget gRadiobutton;
       
    73 +static MozGtkWidget gVertScrollbar;
       
    74 +static MozGtkWidget gHorizScrollbar;
       
    75 +static MozGtkWidget gSpin;
       
    76  static GtkWidget* gHScaleWidget;
    14  static GtkWidget* gHScaleWidget;
    77  static GtkWidget* gVScaleWidget;
    15  static GtkWidget* gVScaleWidget;
    78 -static GtkWidget* gEntryWidget;
    16 -static GtkWidget* gEntryWidget;
    79 +static MozGtkWidget gEntry;
       
    80  static GtkWidget* gComboBoxWidget;
    17  static GtkWidget* gComboBoxWidget;
    81  static GtkWidget* gComboBoxButtonWidget;
    18  static GtkWidget* gComboBoxButtonWidget;
    82  static GtkWidget* gComboBoxArrowWidget;
    19  static GtkWidget* gComboBoxArrowWidget;
    83  static GtkWidget* gComboBoxSeparatorWidget;
    20 @@ -35,30 +29,15 @@ static GtkWidget* gComboBoxEntryWidget;
    84  static GtkWidget* gComboBoxEntryWidget;
    21  static GtkWidget* gComboBoxEntryTextareaWidget;
    85 -static GtkWidget* gComboBoxEntryTextareaWidget;
       
    86 +static MozGtkWidget gComboBoxEntryTextarea;
       
    87  static GtkWidget* gComboBoxEntryButtonWidget;
    22  static GtkWidget* gComboBoxEntryButtonWidget;
    88  static GtkWidget* gComboBoxEntryArrowWidget;
    23  static GtkWidget* gComboBoxEntryArrowWidget;
    89  static GtkWidget* gHandleBoxWidget;
    24 -static GtkWidget* gHandleBoxWidget;
    90  static GtkWidget* gToolbarWidget;
    25 -static GtkWidget* gToolbarWidget;
    91  static GtkWidget* gFrameWidget;
    26 -static GtkWidget* gFrameWidget;
    92  static GtkWidget* gStatusbarWidget;
       
    93 -static GtkWidget* gProgressWidget;
    27 -static GtkWidget* gProgressWidget;
    94 +static MozGtkWidget gProgressBar;
       
    95  static GtkWidget* gTabWidget;
    28  static GtkWidget* gTabWidget;
       
    29 -static GtkWidget* gTextViewWidget;
    96 -static GtkWidget* gTooltipWidget;
    30 -static GtkWidget* gTooltipWidget;
    97 +static MozGtkWidget gTooltip;
    31 -static GtkWidget* gMenuBarWidget;
    98  static GtkWidget* gMenuBarWidget;
    32 -static GtkWidget* gMenuBarItemWidget;
    99  static GtkWidget* gMenuBarItemWidget;
    33 -static GtkWidget* gMenuPopupWidget;
   100  static GtkWidget* gMenuPopupWidget;
    34 -static GtkWidget* gMenuItemWidget;
   101 @@ -78,6 +130,37 @@ static gboolean is_initialized;
    35  static GtkWidget* gImageMenuItemWidget;
   102  #define GTK_STATE_FLAG_CHECKED (1 << 11)
    36  static GtkWidget* gCheckMenuItemWidget;
   103  #endif
    37  static GtkWidget* gTreeViewWidget;
   104  
    38  static GtkTreeViewColumn* gMiddleTreeViewColumn;
   105 +void moz_gtk_widget_free(MozGtkWidget *aMozWidget)
    39  static GtkWidget* gTreeHeaderCellWidget;
   106 +{
    40  static GtkWidget* gTreeHeaderSortArrowWidget;
   107 +    // This was removed as a child of gProtoWindow
    41 -static GtkWidget* gExpanderWidget;
   108 +    if (aMozWidget->widget) {
    42 -static GtkWidget* gToolbarSeparatorWidget;
   109 +        aMozWidget->widget = NULL;
    43 -static GtkWidget* gMenuSeparatorWidget;
   110 +    }
    44  static GtkWidget* gHPanedWidget;
   111 +
    45  static GtkWidget* gVPanedWidget;
   112 +    for(int i = 0; i < MOZ_WIDGET_STYLES; i++) {
    46 -static GtkWidget* gScrolledWindowWidget;
   113 +        if (aMozWidget->all.style[i]) {
    47 -static GtkWidget* gInfoBar;
   114 +            g_object_unref(aMozWidget->all.style[i]);
    48  
   115 +            aMozWidget->all.style[i] = NULL;
    49  static style_prop_t style_prop_func;
   116 +        }
    50  static gboolean have_arrow_scaling;
   117 +    }
    51 @@ -94,15 +73,6 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
   118 +}
       
   119 +
       
   120 +// TODO - weak dep!! (dlsym)
       
   121 +#if GTK_CHECK_VERSION(3, 19, 2)
       
   122 +#define moz_gtk_path_set_class_name    gtk_widget_path_iter_set_object_name
       
   123 +#else
       
   124 +#define moz_gtk_path_set_class_name    gtk_widget_path_iter_add_class
       
   125 +#endif
       
   126 +//gtk_widget_path_iter_get_state
       
   127 +
       
   128 +static void
       
   129 +moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags,
       
   130 +                         GtkBorder *border);
       
   131 +
       
   132 +static void
       
   133 +moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags,
       
   134 +                          GtkBorder *padding);
       
   135 +
       
   136  static GtkStateFlags
       
   137  GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
       
   138  {
       
   139 @@ -97,6 +180,41 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
       
   140      return stateFlags;
    52      return stateFlags;
   141  }
    53  }
   142  
    54  
   143 +GtkStyleContext *
    55 -/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
   144 +moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent)
    56 -   that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
   145 +{
    57 -   things they may want to do. */
   146 +  GtkWidgetPath *path;
    58 -static void
   147 +  GtkStyleContext *context;
    59 -moz_gtk_set_widget_name(GtkWidget* widget)
   148 +
    60 -{
   149 +  if (parent)
    61 -    gtk_widget_set_name(widget, "MozillaGtkWidget");
   150 +    path = gtk_widget_path_copy (gtk_style_context_get_path (parent));
    62 -}
   151 +  else
    63 -
   152 +    path = gtk_widget_path_new ();
    64  gint
   153 +
    65  moz_gtk_enable_style_props(style_prop_t styleGetProp)
   154 +  gtk_widget_path_append_type (path, node->type);
    66  {
   155 +  if (node->name)
    67 @@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t
   156 +    moz_gtk_path_set_class_name(path, -1, node->name);
    68  }
   157 +  if (node->class1)
    69  
   158 +    gtk_widget_path_iter_add_class(path, -1, node->class1);
       
   159 +  if (node->class2)
       
   160 +    gtk_widget_path_iter_add_class(path, -1, node->class2);
       
   161 +
       
   162 +  context = gtk_style_context_new ();
       
   163 +  gtk_style_context_set_path (context, path);
       
   164 +  gtk_style_context_set_parent (context, parent);
       
   165 +
       
   166 +  if(!gtk_check_version(3, 14, 0)) {
       
   167 +      /* Unfortunately, we have to explicitly set the state again here
       
   168 +       * for it to take effect
       
   169 +       */
       
   170 +      gtk_style_context_set_state (context, gtk_widget_path_iter_get_state (path, -1));
       
   171 +  }
       
   172 +
       
   173 +  gtk_widget_path_unref (path);
       
   174 +
       
   175 +  return context;
       
   176 +}
       
   177 +
       
   178  /* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
       
   179     that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
       
   180     things they may want to do. */
       
   181 @@ -141,9 +259,16 @@ setup_widget_prototype(GtkWidget* widget
       
   182  static gint
    70  static gint
   183  ensure_button_widget()
    71 -ensure_window_widget()
   184  {
    72 -{
       
    73 -    if (!gProtoWindow) {
       
    74 -        gProtoWindow = GetWidget(MOZ_GTK_WINDOW);
       
    75 -    }
       
    76 -    return MOZ_GTK_SUCCESS;
       
    77 -}
       
    78 -
       
    79 -static gint
       
    80  setup_widget_prototype(GtkWidget* widget)
       
    81  {
       
    82      if (!gProtoLayout) {
       
    83 @@ -130,16 +91,6 @@ setup_widget_prototype(GtkWidget* widget
       
    84  }
       
    85  
       
    86  static gint
       
    87 -ensure_button_widget()
       
    88 -{
   185 -    if (!gButtonWidget) {
    89 -    if (!gButtonWidget) {
   186 -        gButtonWidget = gtk_button_new_with_label("M");
    90 -        gButtonWidget = gtk_button_new_with_label("M");
   187 -        setup_widget_prototype(gButtonWidget);
    91 -        setup_widget_prototype(gButtonWidget);
   188 +    if (!gButton.widget) {
    92 -    }
   189 +        GtkCssNode path[] = { 
    93 -    return MOZ_GTK_SUCCESS;
   190 +            { GTK_TYPE_BUTTON, "button", NULL, NULL }
    94 -}
   191 +        };
    95 -
   192 +
    96 -static gint
   193 +        gButton.widget = gtk_button_new_with_label("M");
    97  ensure_hpaned_widget()
   194 +        setup_widget_prototype(gButton.widget);
    98  {
   195 +        gtk_widget_show(gButton.widget);
    99      if (!gHPanedWidget) {
   196 +
   100 @@ -160,40 +111,6 @@ ensure_vpaned_widget()
   197 +        gButton.button.style = moz_gtk_style_create(&path[0], NULL);
   101  }
   198      }
   102  
   199      return MOZ_GTK_SUCCESS;
       
   200  }
       
   201 @@ -195,9 +320,21 @@ ensure_button_arrow_widget()
       
   202  static gint
   103  static gint
   203  ensure_checkbox_widget()
   104 -ensure_toggle_button_widget()
   204  {
   105 -{
   205 -    if (!gCheckboxWidget) {
   106 -    if (!gToggleButtonWidget) {
   206 -        gCheckboxWidget = gtk_check_button_new_with_label("M");
   107 -        gToggleButtonWidget = gtk_toggle_button_new();
   207 -        setup_widget_prototype(gCheckboxWidget);
   108 -        setup_widget_prototype(gToggleButtonWidget);
   208 +   if (!gCheckbox.widget) {
   109 -  }
   209 +        GtkCssNode path[] = {
   110 -  return MOZ_GTK_SUCCESS;
   210 +           { GTK_TYPE_TOGGLE_BUTTON, "checkbutton", NULL, NULL },
   111 -}
   211 +           { G_TYPE_NONE, "check", NULL, NULL },
   112 -
   212 +           { G_TYPE_NONE, "label", NULL, NULL }
   113 -static gint
   213 +        };
   114 -ensure_button_arrow_widget()
   214 +
   115 -{
   215 +        gCheckbox.widget = gtk_check_button_new_with_label("M");
   116 -    if (!gButtonArrowWidget) {
   216 +        setup_widget_prototype(gCheckbox.widget);
   117 -        ensure_toggle_button_widget();
   217 +
   118 -
   218 +        gCheckbox.check.style = moz_gtk_style_create(&path[0], NULL);
   119 -        gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
   219 +        gCheckbox.check.styleCheck = moz_gtk_style_create(&path[1],
   120 -        gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget);
   220 +                                       gCheckbox.check.style);
   121 -        gtk_widget_realize(gButtonArrowWidget);
   221 +        gCheckbox.check.styleLabel = moz_gtk_style_create(&path[2],
   122 -        gtk_widget_show(gButtonArrowWidget);
   222 +                                       gCheckbox.check.style);
       
   223      }
       
   224      return MOZ_GTK_SUCCESS;
       
   225  }
       
   226 @@ -205,9 +342,21 @@ ensure_checkbox_widget()
       
   227  static gint
       
   228  ensure_radiobutton_widget()
       
   229  {
       
   230 -    if (!gRadiobuttonWidget) {
       
   231 -        gRadiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M");
       
   232 -        setup_widget_prototype(gRadiobuttonWidget);
       
   233 +    if (!gRadiobutton.widget) {
       
   234 +        GtkCssNode path[] = {
       
   235 +           { GTK_TYPE_TOGGLE_BUTTON, "radiobutton", NULL, NULL },
       
   236 +           { G_TYPE_NONE, "radio", NULL, NULL },
       
   237 +           { G_TYPE_NONE, "label", NULL, NULL }
       
   238 +        };
       
   239 +
       
   240 +        gRadiobutton.widget = gtk_radio_button_new_with_label(NULL, "M");
       
   241 +        setup_widget_prototype(gRadiobutton.widget);
       
   242 +
       
   243 +        gRadiobutton.check.style = moz_gtk_style_create(&path[0], NULL);
       
   244 +        gRadiobutton.check.styleCheck = moz_gtk_style_create(&path[1],
       
   245 +                                          gRadiobutton.check.style);
       
   246 +        gRadiobutton.check.styleLabel = moz_gtk_style_create(&path[2],
       
   247 +                                          gRadiobutton.check.style);
       
   248      }
       
   249      return MOZ_GTK_SUCCESS;
       
   250  }
       
   251 @@ -215,25 +364,62 @@ ensure_radiobutton_widget()
       
   252  static gint
       
   253  ensure_scrollbar_widget()
       
   254  {
       
   255 -    if (!gVertScrollbarWidget) {
       
   256 -        gVertScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
       
   257 -        setup_widget_prototype(gVertScrollbarWidget);
       
   258 -    }
   123 -    }
   259 -    if (!gHorizScrollbarWidget) {
   124 -    return MOZ_GTK_SUCCESS;
   260 -        gHorizScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
   125 -}
   261 -        setup_widget_prototype(gHorizScrollbarWidget);
   126 -
   262 -    }
   127 -static gint
   263 +    if (!gVertScrollbar.widget && !gHorizScrollbar.widget) {
   128 -ensure_spin_widget()
   264 +        GtkCssNode path[] = {
   129 -{
   265 +            { GTK_TYPE_SCROLLBAR, "scrollbar", "horizontal", "bottom"},
       
   266 +            { GTK_TYPE_SCROLLBAR, "scrollbar", "vertical", "right" },
       
   267 +            { G_TYPE_NONE, "contents", NULL, NULL },
       
   268 +            { G_TYPE_NONE, "trough", NULL, NULL },
       
   269 +            { G_TYPE_NONE, "slider", NULL, NULL }
       
   270 +        };
       
   271 +
       
   272 +        gHorizScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
       
   273 +        setup_widget_prototype(gHorizScrollbar.widget);
       
   274 +
       
   275 +        gHorizScrollbar.scroll.style = moz_gtk_style_create(path, NULL);
       
   276 +        gHorizScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, 
       
   277 +                                               gHorizScrollbar.scroll.style);
       
   278 +        gHorizScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, 
       
   279 +                                               gHorizScrollbar.scroll.styleContents);
       
   280 +        gHorizScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, 
       
   281 +                                               gHorizScrollbar.scroll.styleTrough);
       
   282 +
       
   283 +        gVertScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
       
   284 +        setup_widget_prototype(gVertScrollbar.widget);
       
   285 +
       
   286 +        gVertScrollbar.scroll.style = moz_gtk_style_create(path+1, NULL);
       
   287 +        gVertScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, 
       
   288 +                                              gVertScrollbar.scroll.style);
       
   289 +        gVertScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, 
       
   290 +                                              gVertScrollbar.scroll.styleContents);
       
   291 +        gVertScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, 
       
   292 +                                              gVertScrollbar.scroll.styleTrough);
       
   293 +
       
   294 +     }
       
   295      return MOZ_GTK_SUCCESS;
       
   296  }
       
   297  
       
   298  static gint
       
   299  ensure_spin_widget()
       
   300  {
       
   301 -  if (!gSpinWidget) {
   130 -  if (!gSpinWidget) {
   302 -    gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
   131 -    gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
   303 -    setup_widget_prototype(gSpinWidget);
   132 -    setup_widget_prototype(gSpinWidget);
   304 -  }
   133 -  }
   305 -  return MOZ_GTK_SUCCESS;
   134 -  return MOZ_GTK_SUCCESS;
   306 +    if (!gSpin.widget) {
   135 -}
   307 +        GtkCssNode path[] = {
   136 -
   308 +            { GTK_TYPE_SPIN_BUTTON, "spinbutton", "horizontal", NULL },
   137 -static gint
   309 +            { GTK_TYPE_SPIN_BUTTON, "spinbutton", "vertical", NULL },
   138  ensure_scale_widget()
   310 +            { GTK_TYPE_ENTRY, "entry", NULL, NULL },
   139  {
   311 +            { G_TYPE_NONE, "button", "up", NULL },
   140    if (!gHScaleWidget) {
   312 +            { G_TYPE_NONE, "button", "down", NULL }
   141 @@ -207,16 +124,6 @@ ensure_scale_widget()
   313 +        };
   142    return MOZ_GTK_SUCCESS;
   314 +
   143  }
   315 +        gSpin.widget = gtk_spin_button_new(NULL, 1, 0);
   144  
   316 +        setup_widget_prototype(gSpin.widget);
   145 -static gint
   317 +
   146 -ensure_entry_widget()
   318 +        gSpin.spin.style = moz_gtk_style_create(path, NULL);
   147 -{
   319 +        gSpin.spin.styleButtonUp = moz_gtk_style_create(path+3, gSpin.spin.style);
       
   320 +        gSpin.spin.styleButtonDown = moz_gtk_style_create(path+4, gSpin.spin.style);
       
   321 +        gSpin.spin.styleEntry = moz_gtk_style_create(path+2, gSpin.spin.style);
       
   322 +    }
       
   323 +    return MOZ_GTK_SUCCESS;
       
   324  }
       
   325  
       
   326  static gint
       
   327 @@ -253,9 +439,19 @@ ensure_scale_widget()
       
   328  static gint
       
   329  ensure_entry_widget()
       
   330  {
       
   331 -    if (!gEntryWidget) {
   148 -    if (!gEntryWidget) {
   332 -        gEntryWidget = gtk_entry_new();
   149 -        gEntryWidget = gtk_entry_new();
   333 -        setup_widget_prototype(gEntryWidget);
   150 -        setup_widget_prototype(gEntryWidget);
   334 +    if (!gEntry.widget) {
   151 -    }
   335 +        GtkCssNode path[] = { 
   152 -    return MOZ_GTK_SUCCESS;
   336 +            { GTK_TYPE_ENTRY, "entry", NULL, NULL },
   153 -}
   337 +            { G_TYPE_NONE, "selection", NULL, NULL }
   154 -
   338 +        };
   155  /* We need to have pointers to the inner widgets (button, separator, arrow)
   339 +
   156   * of the ComboBox to get the correct rendering from theme engines which
   340 +        gEntry.widget = gtk_entry_new();
   157   * special cases their look. Since the inner layout can change, we ask GTK
   341 +        setup_widget_prototype(gEntry.widget);
   158 @@ -225,7 +132,7 @@ ensure_entry_widget()
   342 +        gtk_widget_show(gEntry.widget);
   159   * g_object_add_weak_pointer().
   343 +
   160   * Note that if we don't find the inner widgets (which shouldn't happen), we
   344 +        gEntry.entry.style = moz_gtk_style_create(&path[0], NULL);
   161   * fallback to use generic "non-inner" widgets, and they don't need that kind
   345 +        gEntry.entry.styleSelection = moz_gtk_style_create(&path[1], 
   162 - * of weak pointer since they are explicit children of gProtoWindow and as
   346 +                                                           gEntry.entry.style);
   163 + * of weak pointer since they are explicit children of gProtoLayout and as
       
   164   * such GTK holds a strong reference to them. */
       
   165  static void
       
   166  moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data)
       
   167 @@ -297,16 +204,14 @@ ensure_combo_box_widgets()
       
   168          /* Shouldn't be reached with current internal gtk implementation; we
       
   169           * use a generic toggle button as last resort fallback to avoid
       
   170           * crashing. */
       
   171 -        ensure_toggle_button_widget();
       
   172 -        gComboBoxButtonWidget = gToggleButtonWidget;
       
   173 +        gComboBoxButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
   347      }
   174      }
   348      return MOZ_GTK_SUCCESS;
   175  
   349  }
   176      if (!gComboBoxArrowWidget) {
   350 @@ -387,9 +583,9 @@ moz_gtk_get_combo_box_entry_inner_widget
   177          /* Shouldn't be reached with current internal gtk implementation;
   351          g_object_add_weak_pointer(G_OBJECT(widget),
   178           * we gButtonArrowWidget as last resort fallback to avoid
   352                                    (gpointer) &gComboBoxEntryButtonWidget);
   179           * crashing. */
   353      } else if (GTK_IS_ENTRY(widget)) {
   180 -        ensure_button_arrow_widget();
   354 -        gComboBoxEntryTextareaWidget = widget;
   181 -        gComboBoxArrowWidget = gButtonArrowWidget;
   355 +        gComboBoxEntryTextarea.widget = widget;
   182 +        gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
   356          g_object_add_weak_pointer(G_OBJECT(widget),
   183      }
   357 -                                  (gpointer) &gComboBoxEntryTextareaWidget);
   184  
   358 +                                  (gpointer) &gComboBoxEntryTextarea.widget);
   185      /* We don't test the validity of gComboBoxSeparatorWidget since there
   359      } else
   186 @@ -316,15 +221,6 @@ ensure_combo_box_widgets()
   360          return;
   187      return MOZ_GTK_SUCCESS;
   361      gtk_widget_realize(widget);
   188  }
   362 @@ -411,7 +607,7 @@ ensure_combo_box_entry_widgets()
   189  
   363  {
   190 -static void
   364      GtkWidget* buttonChild;
   191 -ensure_info_bar()
   365  
   192 -{
   366 -    if (gComboBoxEntryTextareaWidget &&
   193 -  if (!gInfoBar) {
   367 +    if (gComboBoxEntryTextarea.widget &&
   194 -      gInfoBar = gtk_info_bar_new();
   368              gComboBoxEntryButtonWidget &&
   195 -      setup_widget_prototype(gInfoBar);
   369              gComboBoxEntryArrowWidget)
   196 -  }
   370          return MOZ_GTK_SUCCESS;
   197 -}
   371 @@ -427,9 +623,9 @@ ensure_combo_box_entry_widgets()
   198 -
   372                           moz_gtk_get_combo_box_entry_inner_widgets,
   199  /* We need to have pointers to the inner widgets (entry, button, arrow) of
       
   200   * the ComboBoxEntry to get the correct rendering from theme engines which
       
   201   * special cases their look. Since the inner layout can change, we ask GTK
       
   202 @@ -333,7 +229,7 @@ ensure_info_bar()
       
   203   * g_object_add_weak_pointer().
       
   204   * Note that if we don't find the inner widgets (which shouldn't happen), we
       
   205   * fallback to use generic "non-inner" widgets, and they don't need that kind
       
   206 - * of weak pointer since they are explicit children of gProtoWindow and as
       
   207 + * of weak pointer since they are explicit children of gProtoLayout and as
       
   208   * such GTK holds a strong reference to them. */
       
   209  static void
       
   210  moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget,
       
   211 @@ -385,8 +281,7 @@ ensure_combo_box_entry_widgets()
   373                           NULL);
   212                           NULL);
   374  
   213  
   375 -    if (!gComboBoxEntryTextareaWidget) {
   214      if (!gComboBoxEntryTextareaWidget) {
   376 +    if (!gComboBoxEntryTextarea.widget) {
   215 -        ensure_entry_widget();
   377          ensure_entry_widget();
       
   378 -        gComboBoxEntryTextareaWidget = gEntryWidget;
   216 -        gComboBoxEntryTextareaWidget = gEntryWidget;
   379 +        gComboBoxEntryTextarea.widget = gEntry.widget;
   217 +        gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
   380      }
   218      }
   381  
   219  
   382      if (gComboBoxEntryButtonWidget) {
   220      if (gComboBoxEntryButtonWidget) {
   383 @@ -507,12 +703,18 @@ ensure_toolbar_separator_widget()
   221 @@ -412,68 +307,19 @@ ensure_combo_box_entry_widgets()
   384  static gint
   222          /* Shouldn't be reached with current internal gtk implementation;
   385  ensure_tooltip_widget()
   223           * we use a generic toggle button as last resort fallback to avoid
   386  {
   224           * crashing. */
       
   225 -        ensure_toggle_button_widget();
       
   226 -        gComboBoxEntryButtonWidget = gToggleButtonWidget;
       
   227 +        gComboBoxEntryButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
       
   228      }
       
   229  
       
   230      if (!gComboBoxEntryArrowWidget) {
       
   231          /* Shouldn't be reached with current internal gtk implementation;
       
   232           * we gButtonArrowWidget as last resort fallback to avoid
       
   233           * crashing. */
       
   234 -        ensure_button_arrow_widget();
       
   235 -        gComboBoxEntryArrowWidget = gButtonArrowWidget;
       
   236 +        gComboBoxEntryArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
       
   237      }
       
   238  
       
   239      return MOZ_GTK_SUCCESS;
       
   240  }
       
   241  
       
   242 -
       
   243 -static gint
       
   244 -ensure_handlebox_widget()
       
   245 -{
       
   246 -    if (!gHandleBoxWidget) {
       
   247 -        gHandleBoxWidget = gtk_handle_box_new();
       
   248 -        setup_widget_prototype(gHandleBoxWidget);
       
   249 -    }
       
   250 -    return MOZ_GTK_SUCCESS;
       
   251 -}
       
   252 -
       
   253 -static gint
       
   254 -ensure_toolbar_widget()
       
   255 -{
       
   256 -    if (!gToolbarWidget) {
       
   257 -        ensure_handlebox_widget();
       
   258 -        gToolbarWidget = gtk_toolbar_new();
       
   259 -        gtk_container_add(GTK_CONTAINER(gHandleBoxWidget), gToolbarWidget);
       
   260 -        gtk_widget_realize(gToolbarWidget);
       
   261 -    }
       
   262 -    return MOZ_GTK_SUCCESS;
       
   263 -}
       
   264 -
       
   265 -static gint
       
   266 -ensure_toolbar_separator_widget()
       
   267 -{
       
   268 -    if (!gToolbarSeparatorWidget) {
       
   269 -        ensure_toolbar_widget();
       
   270 -        gToolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new());
       
   271 -        setup_widget_prototype(gToolbarSeparatorWidget);
       
   272 -    }
       
   273 -    return MOZ_GTK_SUCCESS;
       
   274 -}
       
   275 -
       
   276 -static gint
       
   277 -ensure_tooltip_widget()
       
   278 -{
   387 -    if (!gTooltipWidget) {
   279 -    if (!gTooltipWidget) {
   388 -        gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
   280 -        gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
   389 -        GtkStyleContext* style = gtk_widget_get_style_context(gTooltipWidget);
   281 -        GtkStyleContext* style = gtk_widget_get_style_context(gTooltipWidget);
   390 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
   282 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
   391 -        gtk_widget_realize(gTooltipWidget);
   283 -        gtk_widget_realize(gTooltipWidget);
   392 -        moz_gtk_set_widget_name(gTooltipWidget);
   284 -        moz_gtk_set_widget_name(gTooltipWidget);
   393 +    if (!gTooltip.widget) {
   285 -    }
   394 +        GtkCssNode path[] = { 
   286 -    return MOZ_GTK_SUCCESS;
   395 +            { GTK_TYPE_TOOLTIP, "tooltip", NULL, NULL},
   287 -}
   396 +            { GTK_TYPE_TOOLTIP, "tooltip", "background", NULL},
   288 -
   397 +        };
       
   398 +
       
   399 +        gTooltip.widget = gtk_window_new(GTK_WINDOW_POPUP);
       
   400 +        gtk_widget_realize(gTooltip.widget);
       
   401 +        moz_gtk_set_widget_name(gTooltip.widget);
       
   402 +
       
   403 +        gTooltip.tooltip.style = moz_gtk_style_create(&path[0], NULL);
       
   404 +        gTooltip.tooltip.styleBackground = moz_gtk_style_create(&path[1], NULL);
       
   405      }
       
   406      return MOZ_GTK_SUCCESS;
       
   407  }
       
   408 @@ -530,9 +732,21 @@ ensure_tab_widget()
       
   409  static gint
   289  static gint
   410  ensure_progress_widget()
   290  ensure_tab_widget()
   411  {
   291  {
       
   292 @@ -485,81 +331,11 @@ ensure_tab_widget()
       
   293  }
       
   294  
       
   295  static gint
       
   296 -ensure_progress_widget()
       
   297 -{
   412 -    if (!gProgressWidget) {
   298 -    if (!gProgressWidget) {
   413 -        gProgressWidget = gtk_progress_bar_new();
   299 -        gProgressWidget = gtk_progress_bar_new();
   414 -        setup_widget_prototype(gProgressWidget);
   300 -        setup_widget_prototype(gProgressWidget);
   415 +    if (!gProgressBar.widget) {
   301 -    }
   416 +        GtkCssNode path[] = {
   302 -    return MOZ_GTK_SUCCESS;
   417 +           { GTK_TYPE_LABEL, "progressbar", NULL, NULL },
   303 -}
   418 +           { G_TYPE_NONE, "trough", NULL, NULL },
   304 -
   419 +           { G_TYPE_NONE, "progress", NULL, NULL },
   305 -static gint
   420 +        };
   306 -ensure_frame_widget()
   421 +
   307 -{
   422 +        gProgressBar.widget = gtk_progress_bar_new();
   308 -    if (!gFrameWidget) {
   423 +        setup_widget_prototype(gProgressBar.widget);
   309 -        gFrameWidget = gtk_frame_new(NULL);
   424 +
   310 -        setup_widget_prototype(gFrameWidget);
   425 +        gProgressBar.progress.style = moz_gtk_style_create(&path[0], NULL);
   311 -    }
   426 +        gProgressBar.progress.styleTrough = moz_gtk_style_create(&path[1],
   312 -    return MOZ_GTK_SUCCESS;
   427 +                                              gProgressBar.progress.style);
   313 -}
   428 +        gProgressBar.progress.styleProgress = moz_gtk_style_create(&path[2],
   314 -
   429 +                                                gProgressBar.progress.styleTrough);
   315 -static gint
       
   316 -ensure_menu_bar_widget()
       
   317 -{
       
   318 -    if (!gMenuBarWidget) {
       
   319 -        gMenuBarWidget = gtk_menu_bar_new();
       
   320 -        setup_widget_prototype(gMenuBarWidget);
       
   321 -    }
       
   322 -    return MOZ_GTK_SUCCESS;
       
   323 -}
       
   324 -
       
   325 -static gint
       
   326 -ensure_menu_bar_item_widget()
       
   327 -{
       
   328 -    if (!gMenuBarItemWidget) {
       
   329 -        ensure_menu_bar_widget();
       
   330 -        gMenuBarItemWidget = gtk_menu_item_new();
       
   331 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget),
       
   332 -                              gMenuBarItemWidget);
       
   333 -        gtk_widget_realize(gMenuBarItemWidget);
       
   334 -    }
       
   335 -    return MOZ_GTK_SUCCESS;
       
   336 -}
       
   337 -
       
   338 -static gint
       
   339 -ensure_menu_popup_widget()
       
   340 -{
       
   341 -    if (!gMenuPopupWidget) {
       
   342 -        ensure_window_widget();
       
   343 -        gMenuPopupWidget = gtk_menu_new();
       
   344 -        gtk_menu_attach_to_widget(GTK_MENU(gMenuPopupWidget), gProtoWindow,
       
   345 -                                  NULL);
       
   346 -        gtk_widget_realize(gMenuPopupWidget);
       
   347 -    }
       
   348 -    return MOZ_GTK_SUCCESS;
       
   349 -}
       
   350 -
       
   351 -static gint
       
   352 -ensure_menu_item_widget()
       
   353 -{
       
   354 -    if (!gMenuItemWidget) {
       
   355 -        ensure_menu_popup_widget();
       
   356 -        gMenuItemWidget = gtk_menu_item_new_with_label("M");
       
   357 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
       
   358 -                              gMenuItemWidget);
       
   359 -        gtk_widget_realize(gMenuItemWidget);
       
   360 -    }
       
   361 -    return MOZ_GTK_SUCCESS;
       
   362 -}
       
   363 -
       
   364 -static gint
       
   365  ensure_image_menu_item_widget()
       
   366  {
       
   367      if (!gImageMenuItemWidget) {
       
   368 -        ensure_menu_popup_widget();
       
   369          gImageMenuItemWidget = gtk_image_menu_item_new();
       
   370 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
       
   371 +        gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
       
   372                                gImageMenuItemWidget);
       
   373          gtk_widget_realize(gImageMenuItemWidget);
   430      }
   374      }
   431      return MOZ_GTK_SUCCESS;
   375 @@ -567,25 +343,11 @@ ensure_image_menu_item_widget()
   432  }
   376  }
   433 @@ -638,6 +852,11 @@ static gint
   377  
       
   378  static gint
       
   379 -ensure_menu_separator_widget()
       
   380 -{
       
   381 -    if (!gMenuSeparatorWidget) {
       
   382 -        ensure_menu_popup_widget();
       
   383 -        gMenuSeparatorWidget = gtk_separator_menu_item_new();
       
   384 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
       
   385 -                              gMenuSeparatorWidget);
       
   386 -        gtk_widget_realize(gMenuSeparatorWidget);
       
   387 -    }
       
   388 -    return MOZ_GTK_SUCCESS;
       
   389 -}
       
   390 -
       
   391 -static gint
   434  ensure_check_menu_item_widget()
   392  ensure_check_menu_item_widget()
   435  {
   393  {
   436      if (!gCheckMenuItemWidget) {
   394      if (!gCheckMenuItemWidget) {
   437 +        GtkCssNode path[] = {
   395 -        ensure_menu_popup_widget();
   438 +           { GTK_TYPE_CHECK_MENU_ITEM, "menuitem", NULL, NULL },
   396 -        gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
   439 +           { G_TYPE_NONE, "check", NULL, NULL }
   397 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
   440 +        };
   398 +        gCheckMenuItemWidget = gtk_check_menu_item_new();
   441 +
   399 +        gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
   442          ensure_menu_popup_widget();
   400                                gCheckMenuItemWidget);
   443          gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
   401          gtk_widget_realize(gCheckMenuItemWidget);
   444          gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
   402      }
   445 @@ -752,7 +971,7 @@ moz_gtk_checkbox_get_metrics(gint* indic
   403 @@ -646,37 +408,6 @@ ensure_tree_header_cell_widget()
   446  {
   404      return MOZ_GTK_SUCCESS;
   447      ensure_checkbox_widget();
   405  }
   448  
   406  
   449 -    gtk_widget_style_get (gCheckboxWidget,
   407 -static gint
   450 +    gtk_widget_style_get (gCheckbox.widget,
   408 -ensure_expander_widget()
   451                            "indicator_size", indicator_size,
   409 -{
   452                            "indicator_spacing", indicator_spacing,
   410 -    if (!gExpanderWidget) {
   453                            NULL);
   411 -        gExpanderWidget = gtk_expander_new("M");
   454 @@ -765,7 +984,7 @@ moz_gtk_radio_get_metrics(gint* indicato
   412 -        setup_widget_prototype(gExpanderWidget);
   455  {
   413 -    }
   456      ensure_radiobutton_widget();
   414 -    return MOZ_GTK_SUCCESS;
   457  
   415 -}
   458 -    gtk_widget_style_get (gRadiobuttonWidget,
   416 -
   459 +    gtk_widget_style_get (gRadiobutton.widget,
   417 -static gint
   460                            "indicator_size", indicator_size,
   418 -ensure_scrolled_window_widget()
   461                            "indicator_spacing", indicator_spacing,
   419 -{
   462                            NULL);
   420 -    if (!gScrolledWindowWidget) {
   463 @@ -778,13 +997,13 @@ moz_gtk_get_focus_outline_size(gint* foc
   421 -        gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
       
   422 -        setup_widget_prototype(gScrolledWindowWidget);
       
   423 -    }
       
   424 -    return MOZ_GTK_SUCCESS;
       
   425 -}
       
   426 -
       
   427 -static void
       
   428 -ensure_text_view_widget()
       
   429 -{
       
   430 -    if (gTextViewWidget)
       
   431 -        return;
       
   432 -
       
   433 -    gTextViewWidget = gtk_text_view_new();
       
   434 -    ensure_scrolled_window_widget();
       
   435 -    gtk_container_add(GTK_CONTAINER(gScrolledWindowWidget), gTextViewWidget);
       
   436 -}
       
   437 -
       
   438  gint
       
   439  moz_gtk_init()
       
   440  {
       
   441 @@ -729,26 +460,21 @@ moz_gtk_get_focus_outline_size(gint* foc
   464  {
   442  {
   465      GtkBorder border;
   443      GtkBorder border;
   466      GtkBorder padding;
   444      GtkBorder padding;
   467 -    GtkStyleContext *style;
   445 -    GtkStyleContext *style;
   468 +    GtkStyleContext* style;
   446 -
   469  
   447 -    ensure_entry_widget();
   470      ensure_entry_widget();
       
   471 -    style = gtk_widget_get_style_context(gEntryWidget);
   448 -    style = gtk_widget_get_style_context(gEntryWidget);
   472  
   449 -
   473 -    gtk_style_context_get_border(style, 0, &border);
   450 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY);
   474 -    gtk_style_context_get_padding(style, 0, &padding);
   451      gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
   475 +    style = gEntry.entry.style;
   452      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
   476 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   477 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   478      *focus_h_width = border.left + padding.left;
   453      *focus_h_width = border.left + padding.left;
   479      *focus_v_width = border.top + padding.top;
   454      *focus_v_width = border.top + padding.top;
   480      return MOZ_GTK_SUCCESS;
   455 +    ReleaseStyleContext(style);
   481 @@ -821,7 +1040,7 @@ moz_gtk_button_get_default_overflow(gint
   456      return MOZ_GTK_SUCCESS;
       
   457  }
       
   458  
       
   459  gint
       
   460  moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
       
   461  {
       
   462 -    ensure_menu_item_widget();
       
   463 -
       
   464 -    gtk_style_context_get_style(gtk_widget_get_style_context(gMenuItemWidget),
       
   465 -                                "horizontal-padding", horizontal_padding,
       
   466 -                                NULL);
       
   467 +    gtk_widget_style_get(GetWidget(MOZ_GTK_MENUITEM),
       
   468 +                         "horizontal-padding", horizontal_padding,
       
   469 +                         nullptr);
       
   470  
       
   471      return MOZ_GTK_SUCCESS;
       
   472  }
       
   473 @@ -771,10 +497,11 @@ moz_gtk_button_get_default_overflow(gint
       
   474  {
   482      GtkBorder* default_outside_border;
   475      GtkBorder* default_outside_border;
   483  
   476  
   484      ensure_button_widget();
   477 -    ensure_button_widget();
   485 -    gtk_widget_style_get(gButtonWidget,
   478 -    gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
   486 +    gtk_widget_style_get(gButton.widget,
   479 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
   487                           "default-outside-border", &default_outside_border,
   480 +    gtk_style_context_get_style(style,
   488                           NULL);
   481                                  "default-outside-border", &default_outside_border,
   489  
   482                                  NULL);
   490 @@ -844,7 +1063,7 @@ moz_gtk_button_get_default_border(gint*
   483 +    ReleaseStyleContext(style);
       
   484  
       
   485      if (default_outside_border) {
       
   486          *border_top = default_outside_border->top;
       
   487 @@ -794,10 +521,11 @@ moz_gtk_button_get_default_border(gint*
       
   488  {
   491      GtkBorder* default_border;
   489      GtkBorder* default_border;
   492  
   490  
   493      ensure_button_widget();
   491 -    ensure_button_widget();
   494 -    gtk_widget_style_get(gButtonWidget,
   492 -    gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
   495 +    gtk_widget_style_get(gButton.widget,
   493 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
   496                           "default-border", &default_border,
   494 +    gtk_style_context_get_style(style,
   497                           NULL);
   495                                  "default-border", &default_border,
   498  
   496                                  NULL);
   499 @@ -935,7 +1154,7 @@ moz_gtk_button_paint(cairo_t *cr, GdkRec
   497 +    ReleaseStyleContext(style);
   500  
   498  
   501      if (state->focused) {
   499      if (default_border) {
   502          GtkBorder border;
   500          *border_top = default_border->top;
   503 -        gtk_style_context_get_border(style, state_flags, &border);
   501 @@ -831,17 +559,15 @@ static gint
   504 +        moz_gtk_get_style_border(style, state_flags, &border);
   502  moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
   505          x += border.left;
   503                       GtkTextDirection direction)
   506          y += border.top;
   504  {
   507          width -= (border.left + border.right);
   505 -    GtkStyleContext* style;
   508 @@ -956,15 +1175,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
   506 -
   509      gint indicator_size, indicator_spacing;
   507 -    ensure_window_widget();
   510      gint x, y, width, height;
   508 -    gtk_widget_set_direction(gProtoWindow, direction);
   511      gint focus_x, focus_y, focus_width, focus_height;
   509 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
   512 -    GtkWidget *w;
   510  
   513 -    GtkStyleContext *style;
   511 -    style = gtk_widget_get_style_context(gProtoWindow);	
   514 +    MozGtkWidget *w;
   512      gtk_style_context_save(style);
   515  
   513      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
   516      if (isradio) {
   514      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   517          moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
   515      gtk_style_context_restore(style);
   518 -        w = gRadiobuttonWidget;
   516  
   519 +        w = &gRadiobutton;
   517 +    ReleaseStyleContext(style);
   520      } else {
   518 +
   521          moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
   519      return MOZ_GTK_SUCCESS;
   522 -        w = gCheckboxWidget;
   520  }
   523 +        w = &gCheckbox;
   521  
       
   522 @@ -1118,6 +844,36 @@ moz_gtk_scrollbar_button_paint(cairo_t *
       
   523      return MOZ_GTK_SUCCESS;
       
   524  }
       
   525  
       
   526 +static void
       
   527 +moz_gtk_update_scrollbar_style(GtkStyleContext* style,
       
   528 +                               WidgetNodeType widget,
       
   529 +                               GtkTextDirection direction)
       
   530 +{
       
   531 +    if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
       
   532 +        gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM);
       
   533 +    } else {
       
   534 +        if (direction == GTK_TEXT_DIR_LTR) {
       
   535 +            gtk_style_context_add_class(style, GTK_STYLE_CLASS_RIGHT);
       
   536 +            gtk_style_context_remove_class(style, GTK_STYLE_CLASS_LEFT);
       
   537 +        } else {
       
   538 +            gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT);
       
   539 +            gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RIGHT);
       
   540 +        }
       
   541 +    }
       
   542 +}
       
   543 +
       
   544 +static void
       
   545 +moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
       
   546 +                          GdkRectangle* rect, bool drawFocus)
       
   547 +{
       
   548 +    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   549 +    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   550 +    if (drawFocus) {
       
   551 +        gtk_render_focus(style, cr,
       
   552 +                         rect->x, rect->y, rect->width, rect->height);
       
   553 +    }
       
   554 +}
       
   555 +
       
   556  static gint
       
   557  moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
       
   558                                 cairo_t *cr, GdkRectangle* rect,
       
   559 @@ -1126,26 +882,34 @@ moz_gtk_scrollbar_trough_paint(WidgetNod
       
   560                                 GtkTextDirection direction)
       
   561  {
       
   562      if (flags & MOZ_GTK_TRACK_OPAQUE) {
       
   563 -        GtkStyleContext* style =
       
   564 -            gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow));
       
   565 -        gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   566 +        GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
       
   567 +        gtk_render_background(style, cr,
       
   568 +                              rect->x, rect->y, rect->width, rect->height);
       
   569 +        ReleaseStyleContext(style);
   524      }
   570      }
   525  
   571  
   526      // XXX we should assert rect->height >= indicator_size too
   572 -    GtkStyleContext* style =
   527 @@ -983,11 +1201,9 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
   573 -        ClaimStyleContext(widget == MOZ_GTK_SCROLLBAR_HORIZONTAL ?
   528      focus_width = width + 2 * indicator_spacing;
   574 -                          MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
   529      focus_height = height + 2 * indicator_spacing;
   575 -                          MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
   530    
   576 -                          direction);
   531 -    style = gtk_widget_get_style_context(w);
   577 -    // TODO - integate with ClaimStyleContext()?
   532 -
   578 -    gtk_style_context_set_direction(style, direction);
   533 -    gtk_widget_set_sensitive(w, !state->disabled);
   579 +    bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL);
   534 -    gtk_widget_set_direction(w, direction);
   580 +    GtkStyleContext* style;
       
   581  
       
   582 -    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   583 -    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   584 +    // Draw all child CSS Nodes for Gtk >= 3.20
       
   585 +    if (gtk_check_version(3, 20, 0) == nullptr) {
       
   586 +        style = ClaimStyleContext(widget, direction);
       
   587 +        moz_gtk_update_scrollbar_style(style, widget, direction);
       
   588 +        moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
       
   589 +        ReleaseStyleContext(style);
       
   590  
       
   591 -    if (state->focused) {
       
   592 -        gtk_render_focus(style, cr,
       
   593 -                         rect->x, rect->y, rect->width, rect->height);
       
   594 +        style = ClaimStyleContext(isHorizontal ?
       
   595 +                                  MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
       
   596 +                                  MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
       
   597 +                                  direction);
       
   598 +        moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
       
   599 +        ReleaseStyleContext(style);
       
   600      }
       
   601 +    style = ClaimStyleContext(isHorizontal ?
       
   602 +                              MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
       
   603 +                              MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
       
   604 +                              direction);
       
   605 +    moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
       
   606      ReleaseStyleContext(style);
       
   607  
       
   608      return MOZ_GTK_SUCCESS;
       
   609 @@ -1160,12 +924,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode
       
   610      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   611      GtkBorder margin;
       
   612  
       
   613 -    GtkStyleContext* style = ClaimStyleContext(widget, direction);
       
   614 -
       
   615 -    // TODO - integate those with ClaimStyleContext()?
       
   616 -    gtk_style_context_set_state(style, state_flags);
       
   617 -    gtk_style_context_set_direction(style, direction);
       
   618 -
       
   619 +    GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
       
   620      gtk_style_context_get_margin (style, state_flags, &margin);
       
   621  
       
   622      gtk_render_slider(style, cr,
       
   623 @@ -1185,17 +944,10 @@ static gint
       
   624  moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
       
   625                     GtkTextDirection direction)
       
   626  {
       
   627 -    GtkStyleContext* style;
       
   628 -
       
   629 -    ensure_spin_widget();
       
   630 -    gtk_widget_set_direction(gSpinWidget, direction);
       
   631 -    style = gtk_widget_get_style_context(gSpinWidget);
   535 -    gtk_style_context_save(style);
   632 -    gtk_style_context_save(style);
   536 +    gtk_widget_set_sensitive(w->widget, !state->disabled);
   633 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
   537 +    gtk_widget_set_direction(w->widget, direction);
   634 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction);
   538 +    gtk_style_context_save(w->check.styleCheck);
       
   539  
       
   540      if (selected)
       
   541          state_flags |= checkbox_check_state;
       
   542 @@ -995,13 +1211,15 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   543      if (inconsistent)
       
   544          state_flags |= GTK_STATE_FLAG_INCONSISTENT;
       
   545  
       
   546 -    gtk_style_context_set_state(style, state_flags);
       
   547 +    gtk_style_context_set_state(w->check.styleCheck, state_flags);
       
   548 +
       
   549 +    gtk_render_background(w->check.styleCheck, cr, x, y, width, height);
       
   550 +    gtk_render_frame(w->check.styleCheck, cr, x, y, width, height);
       
   551  
       
   552      if (isradio) {
       
   553 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
       
   554 -        gtk_render_option(style, cr, x, y, width, height);
       
   555 +        gtk_render_option(w->check.styleCheck, cr, x, y, width, height);
       
   556          if (state->focused) {
       
   557 -            gtk_render_focus(style, cr, focus_x, focus_y,
       
   558 +            gtk_render_focus(w->check.styleCheck, cr, focus_x, focus_y,
       
   559                              focus_width, focus_height);
       
   560          }
       
   561      }
       
   562 @@ -1010,15 +1228,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   563          * 'indeterminate' type on checkboxes. In GTK, the shadow type
       
   564          * must also be changed for the state to be drawn.
       
   565          */        
       
   566 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
       
   567 -        gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), inconsistent);
       
   568 -        gtk_render_check(style, cr, x, y, width, height);        
       
   569 +        gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(w->widget), inconsistent);
       
   570 +        gtk_render_check(w->check.styleCheck, cr, x, y, width, height);
       
   571          if (state->focused) {
       
   572 -            gtk_render_focus(style, cr, 
       
   573 +            gtk_render_focus(w->check.styleCheck, cr,
       
   574                               focus_x, focus_y, focus_width, focus_height);
       
   575          }
       
   576      }
       
   577 -    gtk_style_context_restore(style);
       
   578 +    gtk_style_context_restore(w->check.styleCheck);
       
   579  
       
   580      return MOZ_GTK_SUCCESS;
       
   581  }
       
   582 @@ -1035,8 +1252,8 @@ calculate_button_inner_rect(GtkWidget* b
       
   583      style = gtk_widget_get_style_context(button);
       
   584  
       
   585      /* This mirrors gtkbutton's child positioning */
       
   586 -    gtk_style_context_get_border(style, 0, &border);
       
   587 -    gtk_style_context_get_padding(style, 0, &padding);
       
   588 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   589 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   590  
       
   591      inner_rect->x = rect->x + border.left + padding.left;
       
   592      inner_rect->y = rect->y + padding.top + border.top;
       
   593 @@ -1099,9 +1316,9 @@ moz_gtk_scrollbar_button_paint(cairo_t *
       
   594      ensure_scrollbar_widget();
       
   595  
       
   596      if (flags & MOZ_GTK_STEPPER_VERTICAL)
       
   597 -        scrollbar = gVertScrollbarWidget;
       
   598 +        scrollbar = gVertScrollbar.widget;
       
   599      else
       
   600 -        scrollbar = gHorizScrollbarWidget;
       
   601 +        scrollbar = gHorizScrollbar.widget;
       
   602  
       
   603      gtk_widget_set_direction(scrollbar, direction);
       
   604  
       
   605 @@ -1181,25 +1398,22 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW
       
   606                                 GtkTextDirection direction)
       
   607  {
       
   608      GtkStyleContext* style;
       
   609 -    GtkScrollbar *scrollbar;
       
   610  
       
   611      ensure_scrollbar_widget();
       
   612  
       
   613 -    if (widget ==  MOZ_GTK_SCROLLBAR_HORIZONTAL)
       
   614 -        scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
       
   615 -    else
       
   616 -        scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
       
   617 -
       
   618 -    gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
       
   619 -    
       
   620      if (flags & MOZ_GTK_TRACK_OPAQUE) {
       
   621          style = gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow));
       
   622          gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   623      }
       
   624  
       
   625 -    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
       
   626 -    gtk_style_context_save(style);
       
   627 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
       
   628 +     if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
       
   629 +        gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction);
       
   630 +        style = gHorizScrollbar.scroll.style;
       
   631 +    }
       
   632 +    else {
       
   633 +        gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction);
       
   634 +        style = gVertScrollbar.scroll.style;
       
   635 +    }
       
   636  
       
   637      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   635      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   638      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   636      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   639 @@ -1208,7 +1422,6 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW
       
   640          gtk_render_focus(style, cr,
       
   641                           rect->x, rect->y, rect->width, rect->height);
       
   642      }
       
   643 -    gtk_style_context_restore(style);
   637 -    gtk_style_context_restore(style);
   644      return MOZ_GTK_SUCCESS;
   638 -
   645  }
   639 +    ReleaseStyleContext(style);
   646  
   640      return MOZ_GTK_SUCCESS;
   647 @@ -1220,24 +1433,20 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi
   641  }
   648  {
   642  
   649      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   643 @@ -1204,21 +956,14 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
   650      GtkStyleContext* style;
   644                            gboolean isDown, GtkWidgetState* state,
   651 -    GtkScrollbar *scrollbar;
   645                            GtkTextDirection direction)
   652      GtkBorder margin;
   646  {
   653  
   647 -    GdkRectangle arrow_rect;
   654      ensure_scrollbar_widget();
   648 -    GtkStyleContext* style;
   655  
   649 -
   656 -    if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL)
   650 -    ensure_spin_widget();
   657 -        scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
   651 -    style = gtk_widget_get_style_context(gSpinWidget);
   658 -    else
       
   659 -        scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
       
   660 -
       
   661 -    gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
       
   662 -
       
   663 -    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
       
   664 -    gtk_style_context_save(style);
   652 -    gtk_style_context_save(style);
   665 +    if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) {
   653 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
   666 +        style = gHorizScrollbar.scroll.styleSlider;
   654 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
   667 +        gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction);
       
   668 +    }
       
   669 +    else {
       
   670 +        style = gVertScrollbar.scroll.styleSlider; 
       
   671 +        gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction);
       
   672 +    }
       
   673  
       
   674 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
       
   675      gtk_style_context_set_state(style, state_flags);
       
   676 -
       
   677      gtk_style_context_get_margin (style, state_flags, &margin);
       
   678  
       
   679      gtk_render_slider(style, cr,
       
   680 @@ -1248,8 +1457,6 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi
       
   681                       (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
       
   682                       GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
       
   683  
       
   684 -    gtk_style_context_restore(style);
       
   685 -
       
   686      return MOZ_GTK_SUCCESS;
       
   687  }
       
   688  
       
   689 @@ -1260,8 +1467,8 @@ moz_gtk_spin_paint(cairo_t *cr, GdkRecta
       
   690      GtkStyleContext* style;
       
   691  
       
   692      ensure_spin_widget();
       
   693 -    gtk_widget_set_direction(gSpinWidget, direction);
   655 -    gtk_widget_set_direction(gSpinWidget, direction);
   694 -    style = gtk_widget_get_style_context(gSpinWidget);
   656 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction,
   695 +    gtk_widget_set_direction(gSpin.widget, direction);
   657 +                                 GetStateFlagsFromGtkWidgetState(state));
   696 +    style = gSpin.spin.style;
       
   697      gtk_style_context_save(style);
       
   698      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
       
   699      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   700 @@ -1280,11 +1487,10 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
       
   701      GtkStyleContext* style;
       
   702  
       
   703      ensure_spin_widget();
       
   704 -    style = gtk_widget_get_style_context(gSpinWidget);
       
   705 +    style = gSpin.spin.style;
       
   706      gtk_style_context_save(style);
       
   707 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
       
   708      gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
       
   709 -    gtk_widget_set_direction(gSpinWidget, direction);
       
   710 +    gtk_widget_set_direction(gSpin.widget, direction);
       
   711  
   658  
   712      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   659      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   713      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   660      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   714 @@ -1450,15 +1656,13 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec
   661  
   715  static gint
   662 -
   716  moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
   663      /* hard code these values */
   717                      GtkWidgetState* state,
   664 +    GdkRectangle arrow_rect;
   718 -                    GtkWidget* widget, GtkTextDirection direction)
   665      arrow_rect.width = 6;
   719 +                    MozGtkWidget* w, GtkTextDirection direction)
   666      arrow_rect.height = 6;
   720  {
   667      arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
   721      gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
   668 @@ -1229,7 +974,8 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
       
   669                      isDown ? ARROW_DOWN : ARROW_UP,
       
   670                      arrow_rect.x, arrow_rect.y,
       
   671                      arrow_rect.width);
       
   672 -    gtk_style_context_restore(style);
       
   673 +
       
   674 +    ReleaseStyleContext(style);
       
   675      return MOZ_GTK_SUCCESS;
       
   676  }
       
   677  
       
   678 @@ -1295,8 +1041,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G
       
   679    gtk_widget_set_direction(widget, direction);
       
   680  
       
   681    style = gtk_widget_get_style_context(widget);
       
   682 -  gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
       
   683    gtk_style_context_save(style);
       
   684 +  gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
       
   685    gtk_style_context_set_state(style, state_flags);
       
   686    /* determine the thumb size, and position the thumb in the center in the opposite axis 
       
   687    */
       
   688 @@ -1321,20 +1067,12 @@ moz_gtk_gripper_paint(cairo_t *cr, GdkRe
       
   689                        GtkWidgetState* state,
       
   690                        GtkTextDirection direction)
       
   691  {
   722 -    GtkStyleContext* style;
   692 -    GtkStyleContext* style;
   723      int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE
   693 -
   724 +    GtkStyleContext* style = w->entry.style;
   694 -    ensure_handlebox_widget();
   725  
   695 -    gtk_widget_set_direction(gHandleBoxWidget, direction);
   726 -    gtk_widget_set_direction(widget, direction);
   696 -
   727 -
   697 -    style = gtk_widget_get_style_context(gHandleBoxWidget);
   728 -    style = gtk_widget_get_style_context(widget);
   698 -    gtk_style_context_save(style);
   729 +    gtk_widget_set_direction(w->widget, direction);
   699 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
   730  
   700 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
   731      if (draw_focus_outline_only) {
   701 -
   732          // Inflate the given 'rect' with the focus outline size.
   702 +    GtkStyleContext* style =
   733 @@ -1478,10 +1682,9 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
   703 +            ClaimStyleContext(MOZ_GTK_GRIPPER, direction,
   734       * textarea window uses gtk_paint_flat_box when exposed */
   704 +                              GetStateFlagsFromGtkWidgetState(state));
   735  
   705      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   736      /* This gets us a lovely greyish disabledish look */
   706      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   737 -    gtk_widget_set_sensitive(widget, !state->disabled);
   707 -    gtk_style_context_restore(style);
   738 +    gtk_widget_set_sensitive(w->widget, !state->disabled);
   708 -
   739  
   709 +    ReleaseStyleContext(style);
   740      gtk_style_context_save(style);
   710      return MOZ_GTK_SUCCESS;
   741 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_ENTRY);
   711  }
   742    
   712  
   743      /* Now paint the shadow and focus border.
   713 @@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
   744       * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad
   714      return MOZ_GTK_SUCCESS;
   745 @@ -1531,7 +1734,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
   715  }
   746      style = gtk_widget_get_style_context(gScrolledWindowWidget);
   716  
   747      gtk_style_context_save(style);
   717 +static gint
   748      gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);    
   718 +moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
   749 -    gtk_style_context_get_border(style, state_flags, &border);
   719 +                        GtkWidgetState* state,
   750 +    moz_gtk_get_style_border(style, state_flags, &border);
   720 +                        GtkTextDirection direction)
       
   721 +{
       
   722 +    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   723 +
       
   724 +    GtkStyleContext* style_frame =
       
   725 +        ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
       
   726 +    gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height);
       
   727 +
       
   728 +    GtkBorder border, padding;
       
   729 +    gtk_style_context_get_border(style_frame, state_flags, &border);
       
   730 +    gtk_style_context_get_padding(style_frame, state_flags, &padding);
       
   731 +    ReleaseStyleContext(style_frame);
       
   732 +
       
   733 +    GtkStyleContext* style =
       
   734 +        ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
       
   735 +
       
   736 +    gint xthickness = border.left + padding.left;
       
   737 +    gint ythickness = border.top + padding.top;
       
   738 +
       
   739 +    gtk_render_background(style, cr,
       
   740 +                          rect->x + xthickness, rect->y + ythickness,
       
   741 +                          rect->width - 2 * xthickness,
       
   742 +                          rect->height - 2 * ythickness);
       
   743 +
       
   744 +    ReleaseStyleContext(style);
       
   745 +
       
   746 +    return MOZ_GTK_SUCCESS;
       
   747 +}
       
   748 +
       
   749  static gint 
       
   750  moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect,
       
   751                         GtkWidgetState* state,
       
   752 @@ -1447,18 +1217,13 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
       
   753      GtkBorder border;
       
   754  
       
   755      ensure_tree_view_widget();
       
   756 -    ensure_scrolled_window_widget();
       
   757 -
       
   758      gtk_widget_set_direction(gTreeViewWidget, direction);
       
   759 -    gtk_widget_set_direction(gScrolledWindowWidget, direction);
       
   760  
       
   761      /* only handle disabled and normal states, otherwise the whole background
       
   762       * area will be painted differently with other states */
       
   763      state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
       
   764  
       
   765 -    style = gtk_widget_get_style_context(gScrolledWindowWidget);
       
   766 -    gtk_style_context_save(style);
       
   767 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);    
       
   768 +    style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
       
   769      gtk_style_context_get_border(style, state_flags, &border);
   751      xthickness = border.left;
   770      xthickness = border.left;
   752      ythickness = border.top;    
   771      ythickness = border.top;    
   753  
   772 @@ -1473,7 +1238,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
   754 @@ -1702,7 +1905,7 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk
   773                            rect->height - 2 * ythickness);
   755          if (direction == GTK_TEXT_DIR_LTR) {
   774      gtk_render_frame(style, cr, 
   756              GtkBorder padding;
   775                       rect->x, rect->y, rect->width, rect->height); 
   757              GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   776 -    gtk_style_context_restore(style);
   758 -            gtk_style_context_get_padding(style, state_flags, &padding);
   777 +    ReleaseStyleContext(style);
   759 +            moz_gtk_get_style_padding(style, state_flags, &padding);
   778      gtk_style_context_restore(style_tree);
   760              arrow_rect.x -= padding.left;
   779      return MOZ_GTK_SUCCESS;
   761          }
   780  }
   762          else
   781 @@ -1648,20 +1413,9 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
   763 @@ -1804,29 +2007,27 @@ moz_gtk_container_paint(cairo_t *cr, Gdk
   782                      GtkWidgetState* state,
   764                          gboolean isradio, GtkTextDirection direction)
   783                      GtkArrowType arrow_type, GtkTextDirection direction)
   765  {
   784  {
   766      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   767 -    GtkStyleContext* style;
   785 -    GtkStyleContext* style;
   768 -    GtkWidget *widget;
   786 -    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   769 +    MozGtkWidget *widget;
   787      GdkRectangle arrow_rect;
   770  
   788      gdouble arrow_angle;
   771      if (isradio) {
   789  
   772          ensure_radiobutton_widget();
   790 -    ensure_button_arrow_widget();
   773 -        widget = gRadiobuttonWidget;
   791 -    style = gtk_widget_get_style_context(gButtonArrowWidget);
   774 +        widget = &gRadiobutton;
       
   775      } else {
       
   776          ensure_checkbox_widget();
       
   777 -        widget = gCheckboxWidget;
       
   778 +        widget = &gCheckbox;
       
   779      }
       
   780 -    gtk_widget_set_direction(widget, direction);
       
   781 +    gtk_widget_set_direction(widget->widget, direction);
       
   782  
       
   783 -    style = gtk_widget_get_style_context(widget);
       
   784 -    gtk_style_context_save(style);
   792 -    gtk_style_context_save(style);
   785 -    gtk_style_context_set_state(style, state_flags);
   793 -    gtk_style_context_set_state(style, state_flags);
   786 +    gtk_style_context_save(widget->check.style);
   794 -    gtk_widget_set_direction(gButtonArrowWidget, direction);
   787 +    gtk_style_context_set_state(widget->check.style, state_flags);
   795 -
   788    
   796 -    calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
   789      /* this is for drawing a prelight box */
   797 -                         direction);
   790      if (state_flags & GTK_STATE_FLAG_PRELIGHT) {
   798 -
   791 -        gtk_render_background(style, cr,
   799      if (direction == GTK_TEXT_DIR_RTL) {
   792 +        gtk_render_background(widget->check.style, cr,
   800          arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
   793                                rect->x, rect->y, rect->width, rect->height);
   801                           GTK_ARROW_RIGHT : GTK_ARROW_LEFT;
       
   802 @@ -1680,10 +1434,17 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
       
   803          arrow_angle = ARROW_UP;
       
   804          break;
   794      }
   805      }
   795    
   806 -    if (arrow_type != GTK_ARROW_NONE)
       
   807 -        gtk_render_arrow(style, cr, arrow_angle,
       
   808 -                         arrow_rect.x, arrow_rect.y, arrow_rect.width);                    
   796 -    gtk_style_context_restore(style);
   809 -    gtk_style_context_restore(style);
   797 +    gtk_style_context_restore(widget->check.style);
   810 +    if (arrow_type == GTK_ARROW_NONE)
   798    
   811 +        return MOZ_GTK_SUCCESS;
   799      return MOZ_GTK_SUCCESS;
   812 +
   800  }
   813 +    calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
   801 @@ -1836,32 +2037,26 @@ moz_gtk_toggle_label_paint(cairo_t *cr,
   814 +                         direction);
   802                             GtkWidgetState* state, 
   815 +    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   803                             gboolean isradio, GtkTextDirection direction)
   816 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_BUTTON_ARROW,
   804  {
   817 +                                               direction, state_flags);
   805 -    GtkStyleContext *style;
   818 +    gtk_render_arrow(style, cr, arrow_angle,
   806 -    GtkWidget *widget;
   819 +                     arrow_rect.x, arrow_rect.y, arrow_rect.width);
   807 +    MozGtkWidget *widget;
   820 +    ReleaseStyleContext(style);
   808  
   821      return MOZ_GTK_SUCCESS;
   809      if (!state->focused)
   822  }
   810          return MOZ_GTK_SUCCESS;
   823  
   811  
   824 @@ -1776,19 +1537,10 @@ static gint
   812      if (isradio) {
   825  moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
   813          ensure_radiobutton_widget();
   826                        GtkTextDirection direction)
   814 -        widget = gRadiobuttonWidget;
   827  {
   815 +        widget = &gRadiobutton;
   828 -    GtkStyleContext* style;
   816      } else {
   829 -
   817          ensure_checkbox_widget();
   830 -    ensure_toolbar_widget();
   818 -        widget = gCheckboxWidget;
   831 -    gtk_widget_set_direction(gToolbarWidget, direction);
   819 -    }
   832 -
   820 -    style = gtk_widget_get_style_context(widget);
   833 -    style = gtk_widget_get_style_context(gToolbarWidget);
   821 -    gtk_style_context_save(style);
   834 -    gtk_style_context_save(style);
   822 -    if (isradio) {
   835 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLBAR);
   823 -      gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
   836 -
   824 -    } else {
   837 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR, direction);
   825 -      gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
       
   826 +        widget = &gCheckbox;
       
   827      }
       
   828 -    gtk_widget_set_direction(widget, direction);
       
   829 +    gtk_style_context_save(widget->check.styleLabel);
       
   830 +    gtk_widget_set_direction(widget->widget, direction);
       
   831  
       
   832 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
       
   833 -    gtk_render_focus(style, cr,
       
   834 +    gtk_style_context_set_state(widget->check.styleLabel, 
       
   835 +                                GetStateFlagsFromGtkWidgetState(state));
       
   836 +    gtk_render_focus(widget->check.styleLabel, cr,
       
   837                      rect->x, rect->y, rect->width, rect->height);
       
   838 -    gtk_style_context_restore(style);
       
   839 +    gtk_style_context_restore(widget->check.styleLabel);
       
   840  
       
   841      return MOZ_GTK_SUCCESS;
       
   842  }
       
   843 @@ -1922,7 +2117,7 @@ moz_gtk_toolbar_separator_paint(cairo_t
       
   844                            rect->height * (end_fraction - start_fraction));
       
   845      } else {
       
   846          GtkBorder padding;
       
   847 -        gtk_style_context_get_padding(style, 0, &padding);
       
   848 +        gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   849      
       
   850          paint_width = padding.left;
       
   851          if (paint_width > rect->width)
       
   852 @@ -1945,9 +2140,9 @@ moz_gtk_tooltip_paint(cairo_t *cr, GdkRe
       
   853      GtkStyleContext* style;
       
   854  
       
   855      ensure_tooltip_widget();
       
   856 -    gtk_widget_set_direction(gTooltipWidget, direction);
       
   857 +    gtk_widget_set_direction(gTooltip.widget, direction);
       
   858  
       
   859 -    style = gtk_widget_get_style_context(gTooltipWidget);
       
   860 +    style = gTooltip.tooltip.styleBackground;
       
   861      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   838      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   862      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   839      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   863      return MOZ_GTK_SUCCESS;
   840 -    gtk_style_context_restore(style);
   864 @@ -2006,18 +2201,13 @@ static gint
   841 -
       
   842 +    ReleaseStyleContext(style);
       
   843      return MOZ_GTK_SUCCESS;
       
   844  }
       
   845  
       
   846 @@ -1798,7 +1550,6 @@ static gint
       
   847  moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
       
   848                                  GtkTextDirection direction)
       
   849  {
       
   850 -    GtkStyleContext* style;
       
   851      gint     separator_width;
       
   852      gint     paint_width;
       
   853      gboolean wide_separators;
       
   854 @@ -1807,16 +1558,14 @@ moz_gtk_toolbar_separator_paint(cairo_t
       
   855      const double start_fraction = 0.2;
       
   856      const double end_fraction = 0.8;
       
   857  
       
   858 -    ensure_toolbar_separator_widget();
       
   859 -    gtk_widget_set_direction(gToolbarSeparatorWidget, direction);
       
   860 -
       
   861 -    style = gtk_widget_get_style_context(gToolbarSeparatorWidget);
       
   862 -
       
   863 -    gtk_style_context_get_style(gtk_widget_get_style_context(gToolbarWidget),
       
   864 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
       
   865 +    gtk_style_context_get_style(style,
       
   866                                  "wide-separators", &wide_separators,
       
   867                                  "separator-width", &separator_width,
       
   868                                  NULL);
       
   869 +    ReleaseStyleContext(style);
       
   870  
       
   871 +    style = ClaimStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction);
       
   872      if (wide_separators) {
       
   873          if (separator_width > rect->width)
       
   874              separator_width = rect->width;
       
   875 @@ -1840,7 +1589,7 @@ moz_gtk_toolbar_separator_paint(cairo_t
       
   876                          rect->x + (rect->width - paint_width) / 2,
       
   877                          rect->y + rect->height * end_fraction);
       
   878      }
       
   879 -
       
   880 +    ReleaseStyleContext(style);
       
   881      return MOZ_GTK_SUCCESS;
       
   882  }
       
   883  
       
   884 @@ -1848,14 +1597,10 @@ static gint
       
   885  moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
       
   886                        GtkTextDirection direction)
       
   887  {
       
   888 -    GtkStyleContext* style;
       
   889 -
       
   890 -    ensure_tooltip_widget();
       
   891 -    gtk_widget_set_direction(gTooltipWidget, direction);
       
   892 -
       
   893 -    style = gtk_widget_get_style_context(gTooltipWidget);
       
   894 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction);
       
   895      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   896      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   897 +    ReleaseStyleContext(style);
       
   898      return MOZ_GTK_SUCCESS;
       
   899  }
       
   900  
       
   901 @@ -1870,14 +1615,11 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
       
   902      // GTK_STYLE_CLASS_VIEW to match the background with textarea elements.
       
   903      // The resizer is drawn with shaded variants of the background color, and
       
   904      // so a transparent background would lead to a transparent resizer.
       
   905 -    ensure_text_view_widget();
       
   906 -    gtk_widget_set_direction(gTextViewWidget, GTK_TEXT_DIR_LTR);
       
   907 -
       
   908 -    style = gtk_widget_get_style_context(gTextViewWidget);
       
   909 -    gtk_style_context_save(style);
       
   910 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
       
   911 +    style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR,
       
   912 +                              GetStateFlagsFromGtkWidgetState(state));
       
   913 +    // TODO - we need to save/restore style when gtk 3.20 CSS node path
       
   914 +    // is used
       
   915      gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
       
   916 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
       
   917  
       
   918      // Workaround unico not respecting the text direction for resizers.
       
   919      // See bug 1174248.
       
   920 @@ -1891,7 +1633,7 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
       
   921  
       
   922      gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   923      cairo_restore(cr);
       
   924 -    gtk_style_context_restore(style);
       
   925 +    ReleaseStyleContext(style);
       
   926  
       
   927      return MOZ_GTK_SUCCESS;
       
   928  }
       
   929 @@ -1900,16 +1642,9 @@ static gint
       
   930  moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
       
   931                      GtkTextDirection direction)
       
   932  {
       
   933 -    GtkStyleContext* style;
       
   934 -
       
   935 -    ensure_frame_widget();
       
   936 -    gtk_widget_set_direction(gFrameWidget, direction);
       
   937 -    style = gtk_widget_get_style_context(gFrameWidget);
       
   938 -    gtk_style_context_save(style);
       
   939 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
       
   940 -
       
   941 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_FRAME, direction);
       
   942      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   943 -    gtk_style_context_restore(style);
       
   944 +    ReleaseStyleContext(style);
       
   945      return MOZ_GTK_SUCCESS;
       
   946  }
       
   947  
       
   948 @@ -1917,18 +1652,11 @@ static gint
   865  moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
   949  moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
   866                            GtkTextDirection direction)
   950                            GtkTextDirection direction)
   867  {
   951  {
   868 -    GtkStyleContext* style;
   952 -    GtkStyleContext* style;
   869 -
   953 -
   870      ensure_progress_widget();
   954 -    ensure_progress_widget();
   871 -    gtk_widget_set_direction(gProgressWidget, direction);
   955 -    gtk_widget_set_direction(gProgressWidget, direction);
   872 +    gtk_widget_set_direction(gProgressBar.widget, direction);
   956 -
   873  
       
   874 -    style = gtk_widget_get_style_context(gProgressWidget);
   957 -    style = gtk_widget_get_style_context(gProgressWidget);
   875 -    gtk_style_context_save(style);
   958 -    gtk_style_context_save(style);
   876 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
   959 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
   877 -    
   960 -    
   878 -    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   961 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH,
   879 -    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   962 +                                               direction);
       
   963      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   964      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
   880 -    gtk_style_context_restore(style);
   965 -    gtk_style_context_restore(style);
   881 +    gtk_render_background(gProgressBar.progress.styleTrough, cr,
   966 +    ReleaseStyleContext(style);
   882 +                          rect->x, rect->y, rect->width, rect->height);
   967  
   883 +    gtk_render_frame(gProgressBar.progress.styleTrough, cr,
   968      return MOZ_GTK_SUCCESS;
   884 +                     rect->x, rect->y, rect->width, rect->height);
   969  }
   885  
   970 @@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
   886      return MOZ_GTK_SUCCESS;
   971  {
   887  }
   972      GtkStyleContext* style;
   888 @@ -2027,15 +2217,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
   973  
   889                               GtkTextDirection direction,
   974 -    ensure_progress_widget();
   890                               GtkThemeWidgetType widget)
       
   891  {
       
   892 -    GtkStyleContext* style;
       
   893 -
       
   894      ensure_progress_widget();
       
   895 -    gtk_widget_set_direction(gProgressWidget, direction);
   975 -    gtk_widget_set_direction(gProgressWidget, direction);
   896 -
   976 -
   897 -    style = gtk_widget_get_style_context(gProgressWidget);
   977 -    style = gtk_widget_get_style_context(gProgressWidget);
   898 -    gtk_style_context_save(style);
   978 -    gtk_style_context_save(style);
   899 -    gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
   979 -    gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
   900 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
   980 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
   901 +    gtk_widget_set_direction(gProgressBar.widget, direction);
   981 +    if (gtk_check_version(3, 20, 0) != nullptr) {
       
   982 +      /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR
       
   983 +       * because ClaimStyleContext() saves/restores that style */
       
   984 +      style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction);
       
   985 +      gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
       
   986 +      gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
       
   987 +    } else {
       
   988 +      style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
       
   989 +    }
   902  
   990  
   903      if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
   991      if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
   904          widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
   992          widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
   905 @@ -2074,12 +2257,14 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
   993 @@ -1990,7 +1720,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
   906      // gtk_render_activity was used to render progress chunks on GTK versions
       
   907      // before 3.13.7, see bug 1173907.
       
   908      if (!gtk_check_version(3, 13, 7)) {
       
   909 -      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   910 -      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   911 +      gtk_render_background(gProgressBar.progress.styleProgress, cr,
       
   912 +                            rect->x, rect->y, rect->width, rect->height);
       
   913 +      gtk_render_frame(gProgressBar.progress.styleProgress, cr,
       
   914 +                       rect->x, rect->y, rect->width, rect->height);
       
   915      } else {
   994      } else {
   916 -      gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
   995        gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
   917 +      gtk_render_activity(gProgressBar.progress.styleProgress, cr,
       
   918 +                          rect->x, rect->y, rect->width, rect->height);
       
   919      }
   996      }
   920 -    gtk_style_context_restore(style);
   997 -    gtk_style_context_restore(style);
   921  
   998 +    ReleaseStyleContext(style);
   922      return MOZ_GTK_SUCCESS;
   999  
   923  }
  1000      return MOZ_GTK_SUCCESS;
   924 @@ -2096,7 +2281,7 @@ moz_gtk_get_tab_thickness(void)
  1001  }
   925  
  1002 @@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR
   926      style = gtk_widget_get_style_context(gTabWidget);
  1003  {
   927      gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK);
  1004      GtkStyleContext* style;
   928 -    gtk_style_context_get_border(style, 0, &border);
  1005  
   929 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
  1006 -    ensure_menu_bar_widget();
   930  
  1007 -    gtk_widget_set_direction(gMenuBarWidget, direction);
   931      if (border.top < 2)
  1008 +    GtkWidget* widget = GetWidget(MOZ_GTK_MENUBAR);
   932          return 2; /* some themes don't set ythickness correctly */
  1009 +    gtk_widget_set_direction(widget, direction);
   933 @@ -2292,7 +2477,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan
  1010  
   934        gtk_style_context_save(style);
  1011 -    style = gtk_widget_get_style_context(gMenuBarWidget);
   935        moz_gtk_tab_prepare_style_context(style, flags);
  1012 +    style = gtk_widget_get_style_context(widget);
   936  
  1013      gtk_style_context_save(style);
   937 -      gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
  1014      gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
   938 +      moz_gtk_get_style_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
  1015      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
   939  
  1016 @@ -2343,14 +2073,14 @@ moz_gtk_menu_popup_paint(cairo_t *cr, Gd
   940        focusRect.x += padding.left;
  1017  {
   941        focusRect.width -= (padding.left + padding.right);
  1018      GtkStyleContext* style;
   942 @@ -2408,7 +2593,7 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t *
  1019  
   943  }
  1020 -    ensure_menu_popup_widget();
   944  
  1021 -    gtk_widget_set_direction(gMenuPopupWidget, direction);
       
  1022 +    GtkWidget* widget = GetWidget(MOZ_GTK_MENUPOPUP);
       
  1023 +    gtk_widget_set_direction(widget, direction);
       
  1024  
       
  1025      // Draw a backing toplevel. This fixes themes that don't provide a menu
       
  1026      // background, and depend on the GtkMenu's implementation window to provide it.
       
  1027      moz_gtk_window_paint(cr, rect, direction);
       
  1028  
       
  1029 -    style = gtk_widget_get_style_context(gMenuPopupWidget);
       
  1030 +    style = gtk_widget_get_style_context(widget);
       
  1031      gtk_style_context_save(style);
       
  1032      gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENU);
       
  1033  
       
  1034 @@ -2373,12 +2103,10 @@ moz_gtk_menu_separator_paint(cairo_t *cr
       
  1035      gint x, y, w;
       
  1036      GtkBorder padding;
       
  1037  
       
  1038 -    ensure_menu_separator_widget();
       
  1039 -    gtk_widget_set_direction(gMenuSeparatorWidget, direction);
       
  1040 -
       
  1041 -    border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
       
  1042 -
       
  1043 -    style = gtk_widget_get_style_context(gMenuSeparatorWidget);
       
  1044 +    border_width =
       
  1045 +        gtk_container_get_border_width(GTK_CONTAINER(
       
  1046 +                                       GetWidget(MOZ_GTK_MENUSEPARATOR)));
       
  1047 +    style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR, direction);
       
  1048      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
       
  1049  
       
  1050      x = rect->x + border_width;
       
  1051 @@ -2408,42 +2136,36 @@ moz_gtk_menu_separator_paint(cairo_t *cr
       
  1052      }
       
  1053  
       
  1054      gtk_style_context_restore(style);
       
  1055 +    ReleaseStyleContext(style);
       
  1056  
       
  1057      return MOZ_GTK_SUCCESS;
       
  1058  }
       
  1059  
       
  1060  // See gtk_menu_item_draw() for reference.
   945  static gint
  1061  static gint
   946 -moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect,
  1062 -moz_gtk_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
   947 +moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state,
  1063 -                        GtkWidgetState* state,
   948                         GtkTextDirection direction)
  1064 -                        gint flags, GtkTextDirection direction)
   949  {
  1065 +moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
   950      GtkStyleContext* style;
  1066 +                        GtkWidgetState* state, GtkTextDirection direction)
   951 @@ -2468,7 +2653,7 @@ moz_gtk_menu_separator_paint(cairo_t *cr
  1067  {
   952      border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
  1068 -    GtkStyleContext* style;
   953  
  1069 -    GtkWidget* item_widget;
   954      style = gtk_widget_get_style_context(gMenuSeparatorWidget);
  1070 -    guint border_width;
   955 -    gtk_style_context_get_padding(style, 0, &padding);
  1071      gint x, y, w, h;
   956 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
  1072  
   957  
  1073      if (state->inHover && !state->disabled) {   
   958      x = rect->x + border_width;
  1074 -        if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
   959      y = rect->y + border_width;
  1075 -            ensure_menu_bar_item_widget();
   960 @@ -2521,7 +2706,8 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
  1076 -            item_widget = gMenuBarItemWidget;
   961              item_widget = gMenuItemWidget;
  1077 -        } else {
       
  1078 -            ensure_menu_item_widget();
       
  1079 -            item_widget = gMenuItemWidget;
       
  1080 -        }
       
  1081 -        style = gtk_widget_get_style_context(item_widget);
       
  1082 -        gtk_style_context_save(style);
       
  1083 +        guint border_width =
       
  1084 +            gtk_container_get_border_width(GTK_CONTAINER(GetWidget(widget)));
       
  1085 +        GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
  1086 +        GtkStyleContext* style =
       
  1087 +            ClaimStyleContext(widget, direction, state_flags);
       
  1088  
       
  1089 -        if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
       
  1090 -            gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
       
  1091 +        bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr;
       
  1092 +        if (pre_3_6) {
       
  1093 +            // GTK+ 3.4 saves the style context and adds the menubar class to
       
  1094 +            // menubar children, but does each of these only when drawing, not
       
  1095 +            // during layout.
       
  1096 +            gtk_style_context_save(style);
       
  1097 +            if (widget == MOZ_GTK_MENUBARITEM) {
       
  1098 +                gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
       
  1099 +            }
   962          }
  1100          }
   963          style = gtk_widget_get_style_context(item_widget);
  1101  
   964 -        gtk_style_context_save(style);
  1102 -        gtk_widget_set_direction(item_widget, direction);
   965 +// TODO - FIX!
  1103 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
   966 +//        gtk_style_context_save(style);
  1104 -        gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
   967  
  1105 -
   968          if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
  1106 -        border_width = gtk_container_get_border_width(GTK_CONTAINER(item_widget));
   969              gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
  1107 -
   970 @@ -2540,7 +2726,7 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
  1108          x = rect->x + border_width;
       
  1109          y = rect->y + border_width;
       
  1110          w = rect->width - border_width * 2;
       
  1111 @@ -2451,7 +2173,11 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
   971  
  1112  
   972          gtk_render_background(style, cr, x, y, w, h);
  1113          gtk_render_background(style, cr, x, y, w, h);
   973          gtk_render_frame(style, cr, x, y, w, h);
  1114          gtk_render_frame(style, cr, x, y, w, h);
   974 -        gtk_style_context_restore(style);
  1115 -        gtk_style_context_restore(style);
   975 +//        gtk_style_context_restore(style);
  1116 +
       
  1117 +        if (pre_3_6) {
       
  1118 +            gtk_style_context_restore(style);
       
  1119 +        }
       
  1120 +        ReleaseStyleContext(style);
   976      }
  1121      }
   977  
  1122  
   978      return MOZ_GTK_SUCCESS;
  1123      return MOZ_GTK_SUCCESS;
   979 @@ -2556,7 +2742,10 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
  1124 @@ -2462,21 +2188,13 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
   980  
  1125                           GtkWidgetState* state,
   981      ensure_menu_item_widget();
  1126                           GtkTextDirection direction)
   982      gtk_widget_set_direction(gMenuItemWidget, direction);
  1127  {
   983 -
  1128 -    GtkStyleContext* style;
   984 +/*
  1129      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   985 +    state_flags |= (direction == GTK_TEXT_DIR_LTR) ? GTK_STATE_FLAG_DIR_LTR :
  1130 -
   986 +                                                     GTK_STATE_FLAG_DIR_RTL;
  1131 -    ensure_menu_item_widget();
   987 +*/
  1132 -    gtk_widget_set_direction(gMenuItemWidget, direction);
   988      style = gtk_widget_get_style_context(gMenuItemWidget);
  1133 -
   989      gtk_style_context_save(style);
  1134 -    style = gtk_widget_get_style_context(gMenuItemWidget);
   990      gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
  1135 -    gtk_style_context_save(style);
   991 @@ -2606,7 +2795,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
  1136 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
   992      }
  1137 -    gtk_style_context_set_state(style, state_flags);
   993      
  1138 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUITEM,
   994      gtk_style_context_set_state(style, state_flags);
  1139 +                                               direction, state_flags);
   995 -    gtk_style_context_get_padding(style, state_flags, &padding);
  1140      gtk_render_arrow(style, cr,
   996 +    moz_gtk_get_style_padding(style, state_flags, &padding);
  1141                      (direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
   997  
  1142                      rect->x, rect->y, rect->width);
   998      offset = gtk_container_get_border_width(GTK_CONTAINER(gCheckMenuItemWidget)) +
  1143 -    gtk_style_context_restore(style);
   999                                              padding.left + 2;
  1144 -
  1000 @@ -2658,7 +2847,7 @@ moz_gtk_add_style_border(GtkStyleContext
  1145 +    ReleaseStyleContext(style);
  1001  {
  1146      return MOZ_GTK_SUCCESS;
  1002      GtkBorder border;
  1147  }
  1003  
  1148  
  1004 -    gtk_style_context_get_border(style, 0, &border);
  1149 @@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
  1005 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
  1150      gint indicator_size, horizontal_padding;
  1006  
  1151      gint x, y;
  1007      *left += border.left;
  1152  
  1008      *right += border.right;
  1153 -    moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction);
  1009 @@ -2667,12 +2856,22 @@ moz_gtk_add_style_border(GtkStyleContext
  1154 +    moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
  1010  }
  1155  
  1011  
  1156      ensure_check_menu_item_widget();
  1012  static void
  1157      gtk_widget_set_direction(gCheckMenuItemWidget, direction);
  1013 +moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags,
  1158 @@ -2545,21 +2263,13 @@ static gint
  1014 +                         GtkBorder *border)
  1159  moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect,
  1015 +{
  1160                         GtkWidgetState* state)
  1016 +    gtk_style_context_save(style);
  1161  {
  1017 +    gtk_style_context_set_state(style, state_flags);
  1162 -    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
  1018 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), border);
  1163 -    GtkStyleContext *style;
  1019 +    gtk_style_context_restore(style);
  1164 -    ensure_info_bar();
  1020 +}
  1165 -
  1021 +
  1166 -    style = gtk_widget_get_style_context(gInfoBar);
  1022 +static void
  1167 -    gtk_style_context_save(style);
  1023  moz_gtk_add_style_padding(GtkStyleContext* style,
  1168 -
  1024                            gint* left, gint* top, gint* right, gint* bottom)
  1169 -    gtk_style_context_set_state(style, state_flags);
  1025  {
  1170 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
  1026      GtkBorder padding;
  1171 -
  1027  
  1172 +    GtkStyleContext *style =
  1028 -    gtk_style_context_get_padding(style, 0, &padding);
  1173 +        ClaimStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
  1029 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
  1174 +                          GetStateFlagsFromGtkWidgetState(state));
  1030  
  1175      gtk_render_background(style, cr, rect->x, rect->y, rect->width,
  1031      *left += padding.left;
  1176                            rect->height);
  1032      *right += padding.right;
  1177      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
  1033 @@ -2680,6 +2879,16 @@ moz_gtk_add_style_padding(GtkStyleContex
  1178 -
  1034      *bottom += padding.bottom;
  1179 -    gtk_style_context_restore(style);
  1035  }
  1180 +    ReleaseStyleContext(style);
  1036  
  1181  
  1037 +static void
  1182      return MOZ_GTK_SUCCESS;
  1038 +moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags,
  1183  }
  1039 +                          GtkBorder *padding)
  1184 @@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType
  1040 +{
  1185      case MOZ_GTK_BUTTON:
  1041 +    gtk_style_context_save(style);
       
  1042 +    gtk_style_context_set_state(style, state_flags);
       
  1043 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), padding);
       
  1044 +    gtk_style_context_restore(style);
       
  1045 +}
       
  1046 +
       
  1047  gint
       
  1048  moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
       
  1049                            gint* right, gint* bottom, GtkTextDirection direction,
       
  1050 @@ -2694,37 +2903,35 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1051      case MOZ_GTK_TOOLBAR_BUTTON:
  1186      case MOZ_GTK_TOOLBAR_BUTTON:
  1052          {
  1187          {
  1053              ensure_button_widget();
  1188 -            ensure_button_widget();
  1054 -            style = gtk_widget_get_style_context(gButtonWidget);
  1189 -            style = gtk_widget_get_style_context(gButtonWidget);
  1055 -
  1190 +            style = ClaimStyleContext(MOZ_GTK_BUTTON);
       
  1191  
  1056 -            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
  1192 -            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
  1057  
  1193 +            *left = *top = *right = *bottom =
  1058 -            if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
  1194 +                gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
  1059 -                gtk_style_context_save(style);
  1195  
  1060 -                gtk_style_context_add_class(style, "image-button");
  1196              if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
  1061 -            }
  1197                  gtk_style_context_save(style);
       
  1198                  gtk_style_context_add_class(style, "image-button");
       
  1199              }
  1062 -              
  1200 -              
  1063 -            moz_gtk_add_style_padding(style, left, top, right, bottom);
  1201 +
       
  1202              moz_gtk_add_style_padding(style, left, top, right, bottom);
  1064 -                
  1203 -                
  1065 -            if (widget == MOZ_GTK_TOOLBAR_BUTTON)
  1204 +
  1066 -                gtk_style_context_restore(style);
  1205              if (widget == MOZ_GTK_TOOLBAR_BUTTON)
  1067 +            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButton.widget));
  1206                  gtk_style_context_restore(style);
  1068 +            moz_gtk_add_style_padding(gButton.button.style, left, top, right, bottom);
  1207  
  1069  
  1208 @@ -2624,12 +2334,13 @@ moz_gtk_get_widget_border(WidgetNodeType
  1070              // XXX: Subtract 1 pixel from the border to account for the added
       
  1071              // -moz-focus-inner border (Bug 1228281).
  1209              // -moz-focus-inner border (Bug 1228281).
  1072              *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
  1210              *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
  1073 -            moz_gtk_add_style_border(style, left, top, right, bottom);
  1211              moz_gtk_add_style_border(style, left, top, right, bottom);
  1074 +            moz_gtk_add_style_border(gButton.button.style, left, top, right, bottom);
  1212 +
  1075 +
  1213 +            ReleaseStyleContext(style);
  1076              return MOZ_GTK_SUCCESS;
  1214              return MOZ_GTK_SUCCESS;
  1077          }
  1215          }
  1078      case MOZ_GTK_ENTRY:
  1216      case MOZ_GTK_ENTRY:
  1079          {
  1217          {
  1080              ensure_entry_widget();
  1218 -            ensure_entry_widget();
  1081 -            style = gtk_widget_get_style_context(gEntryWidget);
  1219 -            style = gtk_widget_get_style_context(gEntryWidget);
       
  1220 +            style = ClaimStyleContext(MOZ_GTK_ENTRY);
  1082  
  1221  
  1083              // XXX: Subtract 1 pixel from the padding to account for the default
  1222              // XXX: Subtract 1 pixel from the padding to account for the default
  1084              // padding in forms.css. See bug 1187385.
  1223              // padding in forms.css. See bug 1187385.
  1085              *left = *top = *right = *bottom = -1;
  1224 @@ -2637,16 +2348,15 @@ moz_gtk_get_widget_border(WidgetNodeType
  1086 -            moz_gtk_add_style_padding(style, left, top, right, bottom);
  1225              moz_gtk_add_style_padding(style, left, top, right, bottom);
  1087 -            moz_gtk_add_style_border(style, left, top, right, bottom);
  1226              moz_gtk_add_style_border(style, left, top, right, bottom);
  1088  
  1227  
  1089 +            moz_gtk_add_style_padding(gEntry.entry.style, left, top, right, bottom);
  1228 +            ReleaseStyleContext(style);
  1090 +            moz_gtk_add_style_border(gEntry.entry.style, left, top, right, bottom);
       
  1091 +
       
  1092 +            return MOZ_GTK_SUCCESS;
       
  1093 +        }
       
  1094 +    case MOZ_GTK_TOOLTIP:
       
  1095 +        {
       
  1096 +            ensure_tooltip_widget();
       
  1097 +            moz_gtk_add_style_padding(gTooltip.tooltip.styleBackground, left, top, right, bottom);
       
  1098 +            moz_gtk_add_style_border(gTooltip.tooltip.styleBackground, left, top, right, bottom);
       
  1099              return MOZ_GTK_SUCCESS;
  1229              return MOZ_GTK_SUCCESS;
  1100          }
  1230          }
       
  1231 +    case MOZ_GTK_TEXT_VIEW:
  1101      case MOZ_GTK_TREEVIEW:
  1232      case MOZ_GTK_TREEVIEW:
  1102 @@ -2759,7 +2966,7 @@ moz_gtk_get_widget_border(GtkThemeWidget
  1233          {
  1103          break;
  1234 -            ensure_scrolled_window_widget();
  1104      case MOZ_GTK_DROPDOWN_ENTRY:
  1235 -            style = gtk_widget_get_style_context(gScrolledWindowWidget);
  1105          ensure_combo_box_entry_widgets();
  1236 -            gtk_style_context_save(style);
  1106 -        w = gComboBoxEntryTextareaWidget;
  1237 -            gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
  1107 +        w = gComboBoxEntryTextarea.widget;
  1238 +            style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW);
  1108          break;
  1239              moz_gtk_add_style_border(style, left, top, right, bottom);
  1109      case MOZ_GTK_DROPDOWN_ARROW:
  1240 -            gtk_style_context_restore(style);
  1110          ensure_combo_box_entry_widgets();
  1241 +            ReleaseStyleContext(style);
  1111 @@ -2795,7 +3002,7 @@ moz_gtk_get_widget_border(GtkThemeWidget
  1242              return MOZ_GTK_SUCCESS;
  1112  
  1243          }
  1113                  if (!wide_separators) {
  1244      case MOZ_GTK_TREE_HEADER_CELL:
  1114                      style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
  1245 @@ -2726,14 +2436,12 @@ moz_gtk_get_widget_border(WidgetNodeType
  1115 -                    gtk_style_context_get_border(style, 0, &border);
       
  1116 +                    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
  1117                      separator_width = border.left;
       
  1118                  }
       
  1119              }
       
  1120 @@ -2814,14 +3021,17 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1121          w = gTabWidget;
  1246          w = gTabWidget;
  1122          break;
  1247          break;
  1123      case MOZ_GTK_PROGRESSBAR:
  1248      case MOZ_GTK_PROGRESSBAR:
  1124 -        ensure_progress_widget();
  1249 -        ensure_progress_widget();
  1125 -        w = gProgressWidget;
  1250 -        w = gProgressWidget;
  1126 -        break;
  1251 +        w = GetWidget(MOZ_GTK_PROGRESSBAR);
  1127 +        {
  1252          break;
  1128 +            ensure_progress_widget();
       
  1129 +            moz_gtk_add_style_border(gProgressBar.progress.styleTrough,
       
  1130 +                                     left, top, right, bottom);
       
  1131 +            return MOZ_GTK_SUCCESS;
       
  1132 +        }
       
  1133      case MOZ_GTK_SPINBUTTON_ENTRY:
  1253      case MOZ_GTK_SPINBUTTON_ENTRY:
  1134      case MOZ_GTK_SPINBUTTON_UP:
  1254      case MOZ_GTK_SPINBUTTON_UP:
  1135      case MOZ_GTK_SPINBUTTON_DOWN:
  1255      case MOZ_GTK_SPINBUTTON_DOWN:
  1136          ensure_spin_widget();
  1256 -        ensure_spin_widget();
  1137 -        w = gSpinWidget;
  1257 -        w = gSpinWidget;
  1138 +        w = gSpin.widget;
  1258 +        w = GetWidget(MOZ_GTK_SPINBUTTON);
  1139          break;
  1259          break;
  1140      case MOZ_GTK_SCALE_HORIZONTAL:
  1260      case MOZ_GTK_SCALE_HORIZONTAL:
  1141          ensure_scale_widget();
  1261          ensure_scale_widget();
  1142 @@ -2840,12 +3050,13 @@ moz_gtk_get_widget_border(GtkThemeWidget
  1262 @@ -2744,8 +2452,7 @@ moz_gtk_get_widget_border(WidgetNodeType
       
  1263          w = gVScaleWidget;
       
  1264          break;
       
  1265      case MOZ_GTK_FRAME:
       
  1266 -        ensure_frame_widget();
       
  1267 -        w = gFrameWidget;
       
  1268 +        w = GetWidget(MOZ_GTK_FRAME);
       
  1269          break;
       
  1270      case MOZ_GTK_CHECKBUTTON_CONTAINER:
       
  1271      case MOZ_GTK_RADIOBUTTON_CONTAINER:
       
  1272 @@ -2761,19 +2468,17 @@ moz_gtk_get_widget_border(WidgetNodeType
       
  1273              return MOZ_GTK_SUCCESS;
       
  1274          }
       
  1275      case MOZ_GTK_MENUPOPUP:
       
  1276 -        ensure_menu_popup_widget();
       
  1277 -        w = gMenuPopupWidget;
       
  1278 +        w = GetWidget(MOZ_GTK_MENUPOPUP);
       
  1279          break;
       
  1280 +    case MOZ_GTK_MENUBARITEM:
       
  1281      case MOZ_GTK_MENUITEM:
       
  1282      case MOZ_GTK_CHECKMENUITEM:
       
  1283      case MOZ_GTK_RADIOMENUITEM:
  1143          {
  1284          {
  1144              if (widget == MOZ_GTK_CHECKBUTTON_CONTAINER) {
  1285 -            if (widget == MOZ_GTK_MENUITEM) {
  1145                  ensure_checkbox_widget();
  1286 -                ensure_menu_item_widget();
  1146 -                w = gCheckboxWidget;
  1287 -                ensure_menu_bar_item_widget();
  1147 +                w = gCheckbox.widget;
  1288 -                w = gMenuItemWidget;
  1148 +                style = gCheckbox.check.styleCheck;
  1289 -            }
  1149              } else {
  1290 -            else {
  1150                  ensure_radiobutton_widget();
  1291 +            if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) {
  1151 -                w = gRadiobuttonWidget;
  1292 +                // Bug 1274143 for MOZ_GTK_MENUBARITEM
  1152 +                w = gRadiobutton.widget;
  1293 +                w = GetWidget(MOZ_GTK_MENUITEM);
  1153 +                style = gRadiobutton.check.styleCheck;
  1294 +            } else {
       
  1295                  ensure_check_menu_item_widget();
       
  1296                  w = gCheckMenuItemWidget;
  1154              }
  1297              }
  1155 -            style = gtk_widget_get_style_context(w);
  1298 @@ -2784,9 +2489,16 @@ moz_gtk_get_widget_border(WidgetNodeType
  1156  
  1299              return MOZ_GTK_SUCCESS;
  1157              *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w));
  1300          }
  1158              moz_gtk_add_style_border(style,
  1301      case MOZ_GTK_INFO_BAR:
  1159 @@ -2904,7 +3115,6 @@ moz_gtk_get_widget_border(GtkThemeWidget
  1302 -        ensure_info_bar();
       
  1303 -        w = gInfoBar;
       
  1304 +        w = GetWidget(MOZ_GTK_INFO_BAR);
       
  1305          break;
       
  1306 +    case MOZ_GTK_TOOLTIP:
       
  1307 +        {
       
  1308 +            style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
       
  1309 +            moz_gtk_add_style_border(style, left, top, right, bottom);
       
  1310 +            moz_gtk_add_style_padding(style, left, top, right, bottom);
       
  1311 +            ReleaseStyleContext(style);
       
  1312 +            return MOZ_GTK_SUCCESS;
       
  1313 +        }
       
  1314      /* These widgets have no borders, since they are not containers. */
       
  1315      case MOZ_GTK_CHECKBUTTON_LABEL:
       
  1316      case MOZ_GTK_RADIOBUTTON_LABEL:
       
  1317 @@ -2810,7 +2522,6 @@ moz_gtk_get_widget_border(WidgetNodeType
  1160      case MOZ_GTK_MENUSEPARATOR:
  1318      case MOZ_GTK_MENUSEPARATOR:
  1161      /* These widgets have no borders.*/
  1319      /* These widgets have no borders.*/
  1162      case MOZ_GTK_SPINBUTTON:
  1320      case MOZ_GTK_SPINBUTTON:
  1163 -    case MOZ_GTK_TOOLTIP:
  1321 -    case MOZ_GTK_TOOLTIP:
  1164      case MOZ_GTK_WINDOW:
  1322      case MOZ_GTK_WINDOW:
  1165      case MOZ_GTK_RESIZER:
  1323      case MOZ_GTK_RESIZER:
  1166      case MOZ_GTK_MENUARROW:
  1324      case MOZ_GTK_MENUARROW:
  1167 @@ -2978,6 +3188,32 @@ moz_gtk_get_combo_box_entry_button_size(
  1325 @@ -2908,8 +2619,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi
       
  1326              widget = gComboBoxArrowWidget;
       
  1327              break;
       
  1328          default:
       
  1329 -            ensure_button_arrow_widget();
       
  1330 -            widget = gButtonArrowWidget;
       
  1331 +            widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
       
  1332              break;
       
  1333      }
       
  1334  
       
  1335 @@ -2924,11 +2634,9 @@ moz_gtk_get_toolbar_separator_width(gint
       
  1336  {
       
  1337      gboolean wide_separators;
       
  1338      gint separator_width;
       
  1339 -    GtkStyleContext* style;
       
  1340      GtkBorder border;
       
  1341  
       
  1342 -    ensure_toolbar_widget();
       
  1343 -    style = gtk_widget_get_style_context(gToolbarWidget);
       
  1344 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
       
  1345      gtk_style_context_get_style(style,
       
  1346                                  "space-size", size,
       
  1347                                  "wide-separators",  &wide_separators,
       
  1348 @@ -2937,17 +2645,18 @@ moz_gtk_get_toolbar_separator_width(gint
       
  1349      /* Just in case... */
       
  1350      gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
       
  1351      *size = MAX(*size, (wide_separators ? separator_width : border.left));
       
  1352 +    ReleaseStyleContext(style);
       
  1353      return MOZ_GTK_SUCCESS;
  1168  }
  1354  }
  1169  
  1355  
  1170  gint
  1356  gint
  1171 +moz_gtk_get_entry_height(gint* height)
  1357  moz_gtk_get_expander_size(gint* size)
  1172 +{
  1358  {
  1173 +    GtkRequisition requisition;
  1359 -    ensure_expander_widget();
  1174 +    ensure_entry_widget();
  1360 -    gtk_style_context_get_style(gtk_widget_get_style_context(gExpanderWidget),
  1175 +
  1361 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_EXPANDER);
  1176 +    gtk_widget_get_preferred_size(gEntry.widget, NULL, &requisition);
  1362 +    gtk_style_context_get_style(style,
  1177 +    *height = requisition.height;
  1363                                  "expander-size", size,
  1178 +
  1364                                  NULL);
  1179 +    return MOZ_GTK_SUCCESS;
  1365 -
  1180 +}
  1366 +    ReleaseStyleContext(style);
  1181 +
  1367      return MOZ_GTK_SUCCESS;
  1182 +
  1368  }
  1183 +gint
  1369  
  1184 +moz_gtk_get_button_height(gint* height)
  1370 @@ -2972,11 +2681,11 @@ moz_gtk_get_menu_separator_height(gint *
  1185 +{
  1371      GtkStyleContext* style;
  1186 +    GtkRequisition requisition;
  1372      guint border_width;
  1187 +    ensure_entry_widget();
  1373  
  1188 +
  1374 -    ensure_menu_separator_widget();
  1189 +    gtk_widget_get_preferred_size(gButton.widget, NULL, &requisition);
  1375 -
  1190 +    *height = requisition.height;
  1376 -    border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
  1191 +
  1377 +    border_width =
  1192 +    return MOZ_GTK_SUCCESS;
  1378 +        gtk_container_get_border_width(GTK_CONTAINER(
  1193 +}
  1379 +                                       GetWidget(MOZ_GTK_MENUSEPARATOR)));
  1194 +
  1380  
  1195 +
  1381 -    style = gtk_widget_get_style_context(gMenuSeparatorWidget);
  1196 +gint
  1382 +    style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR);
  1197  moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height)
  1383      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
  1198  {
       
  1199      gint arrow_size;
       
  1200 @@ -3030,7 +3266,7 @@ moz_gtk_get_toolbar_separator_width(gint
       
  1201                           "separator-width", &separator_width,
       
  1202                           NULL);
       
  1203      /* Just in case... */
       
  1204 -    gtk_style_context_get_border(style, 0, &border);
       
  1205 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
  1206      *size = MAX(*size, (wide_separators ? separator_width : border.left));
       
  1207      return MOZ_GTK_SUCCESS;
       
  1208  }
       
  1209 @@ -3072,7 +3308,7 @@ moz_gtk_get_menu_separator_height(gint *
       
  1210      border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
       
  1211  
       
  1212      style = gtk_widget_get_style_context(gMenuSeparatorWidget);
       
  1213 -    gtk_style_context_get_padding(style, 0, &padding);
       
  1214 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
  1215  
  1384  
  1216      gtk_style_context_save(style);
  1385      gtk_style_context_save(style);
  1217      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR);
  1386 @@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint *
  1218 @@ -3130,15 +3366,21 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro
  1387                                  NULL);
  1219  {
  1388  
  1220      ensure_scrollbar_widget();
  1389      gtk_style_context_restore(style);
  1221  
  1390 +    ReleaseStyleContext(style);
  1222 -    gtk_widget_style_get (gHorizScrollbarWidget,
  1391  
  1223 +    gtk_widget_style_get (gHorizScrollbar.widget,
  1392      *size = padding.top + padding.bottom + border_width*2;
  1224                            "slider_width", &metrics->slider_width,
  1393      *size += (wide_separators) ? separator_height : 1;
  1225                            "trough_border", &metrics->trough_border,
  1394 @@ -2998,8 +2708,7 @@ moz_gtk_get_menu_separator_height(gint *
  1226                            "stepper_size", &metrics->stepper_size,
  1395  void
  1227                            "stepper_spacing", &metrics->stepper_spacing,
  1396  moz_gtk_get_entry_min_height(gint* height)
  1228                            NULL);
  1397  {
  1229  
  1398 -    ensure_entry_widget();
  1230 -    metrics->min_slider_size = 
  1399 -    GtkStyleContext* style = gtk_widget_get_style_context(gEntryWidget);
  1231 -        gtk_range_get_min_slider_size(GTK_RANGE(gHorizScrollbarWidget));
  1400 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY);
  1232 +    if (!gtk_check_version(3,19,7)) {
  1401      if (!gtk_check_version(3, 20, 0)) {
  1233 +        gtk_style_context_get(gVertScrollbar.scroll.styleSlider, 
  1402          gtk_style_context_get(style, gtk_style_context_get_state(style),
  1234 +                              gtk_style_context_get_state(gVertScrollbar.scroll.styleSlider), 
  1403                                "min-height", height,
  1235 +                              "min-height", &metrics->min_slider_size, NULL);
  1404 @@ -3014,6 +2723,7 @@ moz_gtk_get_entry_min_height(gint* heigh
  1236 +    } else {
  1405      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
  1237 +        metrics->min_slider_size = 
  1406  
  1238 +            gtk_range_get_min_slider_size(GTK_RANGE(gVertScrollbar.widget));
  1407      *height += (border.top + border.bottom + padding.top + padding.bottom);
  1239 +    }
  1408 +    ReleaseStyleContext(style);
  1240  
  1409  }
  1241      return MOZ_GTK_SUCCESS;
  1410  
  1242  }
  1411  void
  1243 @@ -3163,7 +3405,7 @@ moz_gtk_images_in_buttons()
  1412 @@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons()
       
  1413      gboolean result;
  1244      GtkSettings* settings;
  1414      GtkSettings* settings;
  1245  
  1415  
  1246      ensure_button_widget();
  1416 -    ensure_button_widget();
  1247 -    settings = gtk_widget_get_settings(gButtonWidget);
  1417 -    settings = gtk_widget_get_settings(gButtonWidget);
  1248 +    settings = gtk_widget_get_settings(gButton.widget);
  1418 +    settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
  1249  
  1419  
  1250      g_object_get(settings, "gtk-button-images", &result, NULL);
  1420      g_object_get(settings, "gtk-button-images", &result, NULL);
  1251      return result;
  1421      return result;
  1252 @@ -3191,7 +3433,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
  1422 @@ -3116,14 +2825,14 @@ moz_gtk_widget_paint(WidgetNodeType widg
       
  1423      case MOZ_GTK_BUTTON:
       
  1424      case MOZ_GTK_TOOLBAR_BUTTON:
       
  1425          if (state->depressed) {
       
  1426 -            ensure_toggle_button_widget();
       
  1427              return moz_gtk_button_paint(cr, rect, state,
       
  1428                                          (GtkReliefStyle) flags,
       
  1429 -                                        gToggleButtonWidget, direction);
       
  1430 +                                        GetWidget(MOZ_GTK_TOGGLE_BUTTON),
       
  1431 +                                        direction);
  1253          }
  1432          }
  1254          ensure_button_widget();
  1433 -        ensure_button_widget();
  1255          return moz_gtk_button_paint(cr, rect, state,
  1434          return moz_gtk_button_paint(cr, rect, state,
  1256 -                                    (GtkReliefStyle) flags, gButtonWidget,
  1435 -                                    (GtkReliefStyle) flags, gButtonWidget,
  1257 +                                    (GtkReliefStyle) flags, gButton.widget,
  1436 +                                    (GtkReliefStyle) flags,
       
  1437 +                                    GetWidget(MOZ_GTK_BUTTON),
  1258                                      direction);
  1438                                      direction);
  1259          break;
  1439          break;
  1260      case MOZ_GTK_CHECKBUTTON:
  1440      case MOZ_GTK_CHECKBUTTON:
  1261 @@ -3241,7 +3483,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
  1441 @@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
       
  1442                                           state, direction);
       
  1443          break;
  1262      case MOZ_GTK_SPINBUTTON_ENTRY:
  1444      case MOZ_GTK_SPINBUTTON_ENTRY:
  1263          ensure_spin_widget();
  1445 -        ensure_spin_widget();
       
  1446 +        // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly
  1264          return moz_gtk_entry_paint(cr, rect, state,
  1447          return moz_gtk_entry_paint(cr, rect, state,
  1265 -                                   gSpinWidget, direction);
  1448 -                                   gSpinWidget, direction);
  1266 +                                   &gSpin, direction);
  1449 +                                   GetWidget(MOZ_GTK_SPINBUTTON), direction);
  1267          break;
  1450          break;
  1268      case MOZ_GTK_GRIPPER:
  1451      case MOZ_GTK_GRIPPER:
  1269          return moz_gtk_gripper_paint(cr, rect, state,
  1452          return moz_gtk_gripper_paint(cr, rect, state,
  1270 @@ -3268,7 +3510,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
  1453 @@ -3198,9 +2907,11 @@ moz_gtk_widget_paint(WidgetNodeType widg
       
  1454                                                 (GtkExpanderStyle) flags, direction);
       
  1455          break;
  1271      case MOZ_GTK_ENTRY:
  1456      case MOZ_GTK_ENTRY:
  1272          ensure_entry_widget();
  1457 -        ensure_entry_widget();
  1273          return moz_gtk_entry_paint(cr, rect, state,
  1458 -        return moz_gtk_entry_paint(cr, rect, state,
  1274 -                                   gEntryWidget, direction);
  1459 -                                   gEntryWidget, direction);
  1275 +                                   &gEntry, direction);
  1460 +        return moz_gtk_entry_paint(cr, rect, state, GetWidget(MOZ_GTK_ENTRY),
       
  1461 +                                   direction);
       
  1462 +        break;
       
  1463 +    case MOZ_GTK_TEXT_VIEW:
       
  1464 +        return moz_gtk_text_view_paint(cr, rect, state, direction);
  1276          break;
  1465          break;
  1277      case MOZ_GTK_DROPDOWN:
  1466      case MOZ_GTK_DROPDOWN:
  1278          return moz_gtk_combo_box_paint(cr, rect, state, direction);
  1467          return moz_gtk_combo_box_paint(cr, rect, state, direction);
  1279 @@ -3280,7 +3522,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
  1468 @@ -3271,9 +2982,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
  1280      case MOZ_GTK_DROPDOWN_ENTRY:
  1469          return moz_gtk_menu_separator_paint(cr, rect,
  1281          ensure_combo_box_entry_widgets();
  1470                                              direction);
  1282          return moz_gtk_entry_paint(cr, rect, state,
       
  1283 -                                   gComboBoxEntryTextareaWidget, direction);
       
  1284 +                                   &gComboBoxEntryTextarea, direction);
       
  1285          break;
  1471          break;
  1286      case MOZ_GTK_CHECKBUTTON_CONTAINER:
  1472 +    case MOZ_GTK_MENUBARITEM:
  1287      case MOZ_GTK_RADIOBUTTON_CONTAINER:
  1473      case MOZ_GTK_MENUITEM:
  1288 @@ -3332,7 +3574,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
  1474 -        return moz_gtk_menu_item_paint(cr, rect, state, flags,
  1289                                                (GtkArrowType) flags, direction);
  1475 -                                       direction);
       
  1476 +        return moz_gtk_menu_item_paint(widget, cr, rect, state, direction);
  1290          break;
  1477          break;
  1291      case MOZ_GTK_MENUBAR:
  1478      case MOZ_GTK_MENUARROW:
  1292 -        return moz_gtk_menu_bar_paint(cr, rect, direction);
  1479          return moz_gtk_menu_arrow_paint(cr, rect, state,
  1293 +        return moz_gtk_menu_bar_paint(cr, rect, state, direction);
  1480 @@ -3333,25 +3044,16 @@ gboolean moz_gtk_has_scrollbar_buttons(v
  1294          break;
       
  1295      case MOZ_GTK_MENUPOPUP:
       
  1296          return moz_gtk_menu_popup_paint(cr, rect, direction);
       
  1297 @@ -3383,7 +3625,7 @@ GtkWidget* moz_gtk_get_scrollbar_widget(
       
  1298  {
       
  1299      MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()");
       
  1300      ensure_scrollbar_widget();
       
  1301 -    return gHorizScrollbarWidget;
       
  1302 +    return gVertScrollbar.widget;
       
  1303  }
       
  1304  
       
  1305  gboolean moz_gtk_has_scrollbar_buttons(void)
       
  1306 @@ -3391,7 +3633,7 @@ gboolean moz_gtk_has_scrollbar_buttons(v
       
  1307      gboolean backward, forward, secondary_backward, secondary_forward;
       
  1308      MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()");
       
  1309      ensure_scrollbar_widget();
       
  1310 -    gtk_widget_style_get (gHorizScrollbarWidget,
       
  1311 +    gtk_widget_style_get (gHorizScrollbar.widget,
       
  1312                            "has-backward-stepper", &backward,
       
  1313                            "has-forward-stepper", &forward,
       
  1314                            "has-secondary-backward-stepper", &secondary_backward,
       
  1315 @@ -3403,8 +3645,8 @@ gboolean moz_gtk_has_scrollbar_buttons(v
       
  1316  gint
  1481  gint
  1317  moz_gtk_shutdown()
  1482  moz_gtk_shutdown()
  1318  {
  1483  {
  1319 -    if (gTooltipWidget)
  1484 -    if (gTooltipWidget)
  1320 -        gtk_widget_destroy(gTooltipWidget);
  1485 -        gtk_widget_destroy(gTooltipWidget);
  1321 +    moz_gtk_widget_free(&gTooltip);
       
  1322 +
       
  1323      /* This will destroy all of our widgets */
  1486      /* This will destroy all of our widgets */
  1324      if (gProtoWindow)
  1487 -
  1325          gtk_widget_destroy(gProtoWindow);
  1488      ResetWidgetCache();
  1326 @@ -3415,17 +3657,19 @@ moz_gtk_shutdown()
  1489  
  1327  
  1490      /* TODO - replace it with appropriate widget */
  1328      gProtoWindow = NULL;
  1491      if (gTreeHeaderSortArrowWidget)
       
  1492          gtk_widget_destroy(gTreeHeaderSortArrowWidget);
       
  1493  
       
  1494 -    gProtoWindow = NULL;
  1329      gProtoLayout = NULL;
  1495      gProtoLayout = NULL;
  1330 -    gButtonWidget = NULL;
  1496 -    gButtonWidget = NULL;
  1331 +
  1497 -    gToggleButtonWidget = NULL;
  1332 +    // MozWidgets
  1498 -    gButtonArrowWidget = NULL;
  1333 +    moz_gtk_widget_free(&gButton);
       
  1334      gToggleButtonWidget = NULL;
       
  1335      gButtonArrowWidget = NULL;
       
  1336 -    gCheckboxWidget = NULL;
       
  1337 -    gRadiobuttonWidget = NULL;
       
  1338 -    gHorizScrollbarWidget = NULL;
       
  1339 -    gVertScrollbarWidget = NULL;
       
  1340 -    gSpinWidget = NULL;
  1499 -    gSpinWidget = NULL;
  1341 +    moz_gtk_widget_free(&gCheckbox);
       
  1342 +    moz_gtk_widget_free(&gRadiobutton);
       
  1343 +    moz_gtk_widget_free(&gHorizScrollbar);
       
  1344 +    moz_gtk_widget_free(&gVertScrollbar);
       
  1345 +    moz_gtk_widget_free(&gSpin);
       
  1346      gHScaleWidget = NULL;
  1500      gHScaleWidget = NULL;
  1347      gVScaleWidget = NULL;
  1501      gVScaleWidget = NULL;
  1348 -    gEntryWidget = NULL;
  1502 -    gEntryWidget = NULL;
  1349 +    moz_gtk_widget_free(&gEntry);
       
  1350      gComboBoxWidget = NULL;
  1503      gComboBoxWidget = NULL;
  1351      gComboBoxButtonWidget = NULL;
  1504      gComboBoxButtonWidget = NULL;
  1352      gComboBoxSeparatorWidget = NULL;
  1505      gComboBoxSeparatorWidget = NULL;
  1353 @@ -3433,14 +3677,13 @@ moz_gtk_shutdown()
  1506 @@ -3360,29 +3062,15 @@ moz_gtk_shutdown()
  1354      gComboBoxEntryWidget = NULL;
       
  1355      gComboBoxEntryButtonWidget = NULL;
  1507      gComboBoxEntryButtonWidget = NULL;
  1356      gComboBoxEntryArrowWidget = NULL;
  1508      gComboBoxEntryArrowWidget = NULL;
  1357 -    gComboBoxEntryTextareaWidget = NULL;
  1509      gComboBoxEntryTextareaWidget = NULL;
  1358 +    moz_gtk_widget_free(&gComboBoxEntryTextarea);
  1510 -    gHandleBoxWidget = NULL;
  1359      gHandleBoxWidget = NULL;
  1511 -    gToolbarWidget = NULL;
  1360      gToolbarWidget = NULL;
  1512 -    gFrameWidget = NULL;
  1361      gStatusbarWidget = NULL;
       
  1362      gFrameWidget = NULL;
       
  1363 -    gProgressWidget = NULL;
  1513 -    gProgressWidget = NULL;
  1364 +    moz_gtk_widget_free(&gProgressBar);
       
  1365      gTabWidget = NULL;
  1514      gTabWidget = NULL;
       
  1515 -    gTextViewWidget = nullptr;
  1366 -    gTooltipWidget = NULL;
  1516 -    gTooltipWidget = NULL;
  1367      gMenuBarWidget = NULL;
  1517 -    gMenuBarWidget = NULL;
  1368      gMenuBarItemWidget = NULL;
  1518 -    gMenuBarItemWidget = NULL;
  1369      gMenuPopupWidget = NULL;
  1519 -    gMenuPopupWidget = NULL;
  1370 diff -up firefox-46.0.1/widget/gtk/gtkdrawing.h.gtk3-20 firefox-46.0.1/widget/gtk/gtkdrawing.h
  1520 -    gMenuItemWidget = NULL;
  1371 --- firefox-46.0.1/widget/gtk/gtkdrawing.h.gtk3-20	2016-05-03 07:31:12.000000000 +0200
  1521      gImageMenuItemWidget = NULL;
  1372 +++ firefox-46.0.1/widget/gtk/gtkdrawing.h	2016-05-19 15:20:11.656519199 +0200
  1522      gCheckMenuItemWidget = NULL;
  1373 @@ -67,6 +67,13 @@ typedef enum {
  1523      gTreeViewWidget = NULL;
       
  1524      gMiddleTreeViewColumn = NULL;
       
  1525      gTreeHeaderCellWidget = NULL;
       
  1526      gTreeHeaderSortArrowWidget = NULL;
       
  1527 -    gExpanderWidget = NULL;
       
  1528 -    gToolbarSeparatorWidget = NULL;
       
  1529 -    gMenuSeparatorWidget = NULL;
       
  1530      gHPanedWidget = NULL;
       
  1531      gVPanedWidget = NULL;
       
  1532 -    gScrolledWindowWidget = NULL;
       
  1533  
       
  1534      is_initialized = FALSE;
       
  1535  
       
  1536 diff -up firefox-48.0/widget/gtk/gtkdrawing.h.gtk3-20 firefox-48.0/widget/gtk/gtkdrawing.h
       
  1537 --- firefox-48.0/widget/gtk/gtkdrawing.h.gtk3-20	2016-07-25 22:22:07.000000000 +0200
       
  1538 +++ firefox-48.0/widget/gtk/gtkdrawing.h	2016-07-29 09:15:11.822285857 +0200
       
  1539 @@ -69,12 +69,6 @@ typedef enum {
  1374    MOZ_GTK_TAB_SELECTED        = 1 << 10
  1540    MOZ_GTK_TAB_SELECTED        = 1 << 10
  1375  } GtkTabFlags;
  1541  } GtkTabFlags;
  1376  
  1542  
  1377 +typedef struct {
  1543 -/** flags for menuitems **/
  1378 +  GType type;
  1544 -typedef enum {
  1379 +  const gchar *name;
  1545 -  /* menuitem is part of the menubar */
  1380 +  const gchar *class1;
  1546 -  MOZ_TOPLEVEL_MENU_ITEM      = 1 << 0
  1381 +  const gchar *class2;
  1547 -} GtkMenuItemFlags;
  1382 +} GtkCssNode;
  1548 -
  1383 +
  1549  /* function type for moz_gtk_enable_style_props */
  1384  /** flags for menuitems **/
  1550  typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint);
  1385  typedef enum {
  1551  
  1386    /* menuitem is part of the menubar */
  1552 @@ -93,6 +87,10 @@ typedef enum {
  1387 @@ -396,6 +403,9 @@ void
  1553    MOZ_GTK_BUTTON,
  1388  moz_gtk_get_arrow_size(GtkThemeWidgetType widgetType,
  1554    /* Paints a button with image and no text */
  1389                         gint* width, gint* height);
  1555    MOZ_GTK_TOOLBAR_BUTTON,
  1390  
  1556 +  /* Paints a toggle button */
  1391 +gint moz_gtk_get_entry_height(gint* height);
  1557 +  MOZ_GTK_TOGGLE_BUTTON,
  1392 +gint moz_gtk_get_button_height(gint* height);
  1558 +  /* Paints a button arrow */
  1393 +
  1559 +  MOZ_GTK_BUTTON_ARROW,
  1394  /**
  1560  
  1395   * Get the desired size of a toolbar separator
  1561    /* Paints the container part of a GtkCheckButton. */
  1396   * size:    [OUT] the desired width
  1562    MOZ_GTK_CHECKBUTTON_CONTAINER,
  1397 @@ -466,6 +476,12 @@ gboolean moz_gtk_images_in_buttons(void)
  1563 @@ -115,6 +113,7 @@ typedef enum {
  1398   */
  1564  
  1399  gboolean moz_gtk_has_scrollbar_buttons(void);
  1565    /* Horizontal GtkScrollbar counterparts */
  1400  
  1566    MOZ_GTK_SCROLLBAR_HORIZONTAL,
  1401 +
  1567 +  MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL,
  1402 +GtkStyleContext *
  1568    /* Paints the trough (track) of a GtkScrollbar. */
  1403 +moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent);
  1569    MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL,
  1404 +
  1570    /* Paints the slider (thumb) of a GtkScrollbar. */
  1405 +
  1571 @@ -122,6 +121,7 @@ typedef enum {
  1406 +
  1572  
  1407  #ifdef __cplusplus
  1573    /* Vertical GtkScrollbar counterparts */
  1408  }
  1574    MOZ_GTK_SCROLLBAR_VERTICAL,
  1409  #endif /* __cplusplus */
  1575 +  MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
  1410 diff -up firefox-46.0.1/widget/gtk/mozgtk/mozgtk.c.gtk3-20 firefox-46.0.1/widget/gtk/mozgtk/mozgtk.c
  1576    MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
  1411 --- firefox-46.0.1/widget/gtk/mozgtk/mozgtk.c.gtk3-20	2016-05-03 07:31:12.000000000 +0200
  1577    MOZ_GTK_SCROLLBAR_THUMB_VERTICAL,
  1412 +++ firefox-46.0.1/widget/gtk/mozgtk/mozgtk.c	2016-05-20 10:40:19.442320669 +0200
  1578  
  1413 @@ -504,6 +504,11 @@ STUB(gtk_window_set_type_hint)
  1579 @@ -140,6 +140,10 @@ typedef enum {
  1414  STUB(gtk_window_set_wmclass)
  1580    MOZ_GTK_GRIPPER,
  1415  STUB(gtk_window_unfullscreen)
  1581    /* Paints a GtkEntry. */
  1416  STUB(gtk_window_unmaximize)
  1582    MOZ_GTK_ENTRY,
  1417 +STUB(gtk_widget_get_preferred_height_and_baseline_for_width)
  1583 +  /* Paints a GtkExpander. */
  1418 +STUB(gtk_entry_get_text_area)
  1584 +  MOZ_GTK_EXPANDER,
  1419 +STUB(gtk_check_menu_item_get_type)
  1585 +  /* Paints a GtkTextView. */
  1420 +STUB(gtk_spin_button_get_type)
  1586 +  MOZ_GTK_TEXT_VIEW,
  1421 +STUB(gtk_button_get_type)
  1587    /* Paints a GtkOptionMenu. */
  1422  #endif
  1588    MOZ_GTK_DROPDOWN,
  1423  
  1589    /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
  1424  #ifdef GTK3_SYMBOLS
  1590 @@ -159,6 +163,8 @@ typedef enum {
  1425 @@ -581,6 +586,14 @@ STUB(gtk_color_chooser_get_type)
  1591    MOZ_GTK_RESIZER,
       
  1592    /* Paints a GtkProgressBar. */
       
  1593    MOZ_GTK_PROGRESSBAR,
       
  1594 +  /* Paints a trough (track) of a GtkProgressBar */
       
  1595 +  MOZ_GTK_PROGRESS_TROUGH,
       
  1596    /* Paints a progress chunk of a GtkProgressBar. */
       
  1597    MOZ_GTK_PROGRESS_CHUNK,
       
  1598    /* Paints a progress chunk of an indeterminated GtkProgressBar. */
       
  1599 @@ -187,7 +193,9 @@ typedef enum {
       
  1600    MOZ_GTK_MENUARROW,
       
  1601    /* Paints an arrow in a toolbar button. flags is a GtkArrowType. */
       
  1602    MOZ_GTK_TOOLBARBUTTON_ARROW,
       
  1603 -  /* Paints items of menubar and popups. */
       
  1604 +  /* Paints items of menubar. */
       
  1605 +  MOZ_GTK_MENUBARITEM,
       
  1606 +  /* Paints items of popup menus. */
       
  1607    MOZ_GTK_MENUITEM,
       
  1608    MOZ_GTK_CHECKMENUITEM,
       
  1609    MOZ_GTK_RADIOMENUITEM,
       
  1610 @@ -202,6 +210,8 @@ typedef enum {
       
  1611    MOZ_GTK_WINDOW_CONTAINER,
       
  1612    /* Paints a GtkInfoBar, for notifications. */
       
  1613    MOZ_GTK_INFO_BAR,
       
  1614 +  /* Used for scrolled window shell. */
       
  1615 +  MOZ_GTK_SCROLLED_WINDOW,
       
  1616  
       
  1617    MOZ_GTK_WIDGET_NODE_COUNT
       
  1618  } WidgetNodeType;
       
  1619 diff -up firefox-48.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 firefox-48.0/widget/gtk/mozgtk/mozgtk.c
       
  1620 --- firefox-48.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20	2016-07-25 22:22:07.000000000 +0200
       
  1621 +++ firefox-48.0/widget/gtk/mozgtk/mozgtk.c	2016-07-29 09:15:11.823285862 +0200
       
  1622 @@ -517,6 +517,7 @@ STUB(gdk_event_get_source_device)
       
  1623  STUB(gdk_window_get_type)
       
  1624  STUB(gdk_x11_window_get_xid)
       
  1625  STUB(gdk_x11_display_get_type)
       
  1626 +STUB(gtk_box_new)
       
  1627  STUB(gtk_cairo_should_draw_window)
       
  1628  STUB(gtk_cairo_transform_to_window)
       
  1629  STUB(gtk_combo_box_text_append)
       
  1630 @@ -570,6 +571,7 @@ STUB(gtk_tree_view_column_get_button)
       
  1631  STUB(gtk_widget_get_preferred_size)
       
  1632  STUB(gtk_widget_get_state_flags)
       
  1633  STUB(gtk_widget_get_style_context)
       
  1634 +STUB(gtk_widget_path_append_for_widget)
       
  1635  STUB(gtk_widget_path_append_type)
       
  1636  STUB(gtk_widget_path_copy)
       
  1637  STUB(gtk_widget_path_free)
       
  1638 @@ -587,6 +589,10 @@ STUB(gtk_color_chooser_get_type)
  1426  STUB(gtk_color_chooser_set_rgba)
  1639  STUB(gtk_color_chooser_set_rgba)
  1427  STUB(gtk_color_chooser_get_rgba)
  1640  STUB(gtk_color_chooser_get_rgba)
  1428  STUB(gtk_color_chooser_set_use_alpha)
  1641  STUB(gtk_color_chooser_set_use_alpha)
  1429 +STUB(gtk_style_context_get_path)
  1642 +STUB(gtk_check_menu_item_new)
  1430 +STUB(gtk_widget_path_copy)
  1643 +STUB(gtk_style_context_get_direction)
  1431 +STUB(gtk_widget_path_iter_set_object_name)
  1644 +STUB(gtk_style_context_invalidate)
  1432 +STUB(gtk_widget_path_iter_add_class)
       
  1433 +STUB(gtk_widget_path_iter_get_state)
       
  1434 +STUB(gtk_style_context_set_parent)
       
  1435 +STUB(gtk_widget_path_unref)
       
  1436 +STUB(gtk_tooltip_get_type)
  1645 +STUB(gtk_tooltip_get_type)
  1437  #endif
  1646  #endif
  1438  
  1647  
  1439  #ifdef GTK2_SYMBOLS
  1648  #ifdef GTK2_SYMBOLS
  1440 diff -up firefox-46.0.1/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-46.0.1/widget/gtk/nsLookAndFeel.cpp
  1649 diff -up firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-48.0/widget/gtk/nsLookAndFeel.cpp
  1441 --- firefox-46.0.1/widget/gtk/nsLookAndFeel.cpp.gtk3-20	2016-05-03 07:31:12.000000000 +0200
  1650 --- firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20	2016-06-01 06:11:44.000000000 +0200
  1442 +++ firefox-46.0.1/widget/gtk/nsLookAndFeel.cpp	2016-05-20 13:53:54.085049707 +0200
  1651 +++ firefox-48.0/widget/gtk/nsLookAndFeel.cpp	2016-07-29 09:15:54.943459700 +0200
  1443 @@ -353,14 +353,18 @@ nsLookAndFeel::NativeGetColor(ColorID aI
  1652 @@ -31,6 +31,7 @@
  1444      case eColorID_activeborder:
  1653  
  1445          // active window border
  1654  #if MOZ_WIDGET_GTK != 2
  1446          gtk_style_context_get_border_color(mBackgroundStyle, 
  1655  #include <cairo-gobject.h>
  1447 -                                           GTK_STATE_FLAG_NORMAL, &gdk_color);
  1656 +#include "WidgetStyleCache.h"
  1448 +                                           gtk_style_context_get_state(mBackgroundStyle), 
       
  1449 +                                           &gdk_color);
       
  1450          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1451          break;
       
  1452      case eColorID_inactiveborder:
       
  1453          // inactive window border
       
  1454 +        gtk_style_context_save(mBackgroundStyle);
       
  1455 +        gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE);
       
  1456          gtk_style_context_get_border_color(mBackgroundStyle, 
       
  1457 -                                           GTK_STATE_FLAG_INSENSITIVE, 
       
  1458 +                                           gtk_style_context_get_state(mBackgroundStyle), 
       
  1459                                             &gdk_color);
       
  1460 +        gtk_style_context_restore(mBackgroundStyle);
       
  1461          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1462          break;
       
  1463      case eColorID_graytext: // disabled text in windows, menus, etc.
       
  1464 @@ -369,9 +373,12 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       
  1465          break;
       
  1466      case eColorID_inactivecaption:
       
  1467          // inactive window caption
       
  1468 +        gtk_style_context_save(mBackgroundStyle);
       
  1469 +        gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE);
       
  1470          gtk_style_context_get_background_color(mBackgroundStyle, 
       
  1471 -                                               GTK_STATE_FLAG_INSENSITIVE, 
       
  1472 +                                               gtk_style_context_get_state(mBackgroundStyle), 
       
  1473                                                 &gdk_color);
       
  1474 +        gtk_style_context_restore(mBackgroundStyle);
       
  1475          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1476          break;
       
  1477  #endif
  1657  #endif
  1478 @@ -497,13 +504,17 @@ nsLookAndFeel::NativeGetColor(ColorID aI
  1658  
  1479      case eColorID__moz_buttondefault:
  1659  using mozilla::LookAndFeel;
  1480        // default button border color
  1660 @@ -1135,15 +1136,24 @@ nsLookAndFeel::Init()
  1481          gtk_style_context_get_border_color(mButtonStyle, 
  1661      gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1482 -                                           GTK_STATE_FLAG_NORMAL, &gdk_color);
       
  1483 +                                           gtk_style_context_get_state(mButtonStyle),
       
  1484 +                                           &gdk_color);
       
  1485          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1486          break;
       
  1487      case eColorID__moz_buttonhoverface:
       
  1488 +        gtk_style_context_save(mButtonStyle);
       
  1489 +        gtk_style_context_set_state(mButtonStyle, GTK_STATE_FLAG_PRELIGHT);
       
  1490          gtk_style_context_get_background_color(mButtonStyle, 
       
  1491 -                                               GTK_STATE_FLAG_PRELIGHT, 
       
  1492 +                                               gtk_style_context_get_state(mButtonStyle), 
       
  1493                                                 &gdk_color);
       
  1494 +        gtk_style_context_restore(mButtonStyle);
       
  1495          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1496          break;
       
  1497      case eColorID__moz_buttonhovertext:
       
  1498 @@ -1110,27 +1126,29 @@ nsLookAndFeel::Init()
       
  1499      style = create_context(path);
       
  1500      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
       
  1501      gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
       
  1502 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1503 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1504      sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
       
  1505      g_object_unref(style);
       
  1506  
       
  1507      // Window colors
       
  1508      style = create_context(path);
       
  1509 -    gtk_style_context_save(style);
       
  1510      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       
  1511 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1512 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1513      sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1514 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1515 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1516      sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
  1662      sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
  1517 -    gtk_style_context_restore(style);
  1663      gtk_style_context_restore(style);
  1518 +    g_object_unref(style);
  1664 +    g_object_unref(style);
  1519  
  1665  
  1520      // tooltip foreground and background
  1666      // tooltip foreground and background
  1521 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
  1667 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
  1522 +    GtkCssNode tooltipPath[] = { 
  1668 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
  1523 +         { GTK_TYPE_TOOLTIP, "tooltip", NULL, NULL},
  1669 +    style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
  1524 +    };
  1670      gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1525 +    style = moz_gtk_style_create(tooltipPath, NULL);
       
  1526 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1527 +    sInfoText = GDK_RGBA_TO_NS_RGBA(color);
       
  1528      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       
  1529 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1530 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1531      sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
  1671      sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
  1532 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1672 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1533 -    sInfoText = GDK_RGBA_TO_NS_RGBA(color);
  1673 +    {
  1534      g_object_unref(style);
  1674 +        GtkStyleContext* boxStyle =
       
  1675 +            CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
       
  1676 +                                 style);
       
  1677 +        GtkStyleContext* labelStyle =
       
  1678 +            CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
       
  1679 +        gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
       
  1680 +        g_object_unref(labelStyle);
       
  1681 +        g_object_unref(boxStyle);
       
  1682 +    }
       
  1683      sInfoText = GDK_RGBA_TO_NS_RGBA(color);
       
  1684 -    g_object_unref(style);
       
  1685 +    ReleaseStyleContext(style);
  1535  
  1686  
  1536      // menu foreground & menu background
  1687      // menu foreground & menu background
  1537 @@ -1144,20 +1162,26 @@ nsLookAndFeel::Init()
  1688      GtkWidget *accel_label = gtk_accel_label_new("M");
  1538      gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
  1689 diff -up firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp
  1539  
  1690 --- firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20	2016-07-25 22:22:07.000000000 +0200
  1540      style = gtk_widget_get_style_context(accel_label);
  1691 +++ firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp	2016-07-29 09:15:11.824285865 +0200
  1541 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1692 @@ -354,10 +354,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
  1542 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  1693  
  1543      sMenuText = GDK_RGBA_TO_NS_RGBA(color);
  1694            if (isTopLevel) {
  1544 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color);
  1695              aState->inHover = menuFrame->IsOpen();
  1545 +    gtk_style_context_save(style);
  1696 -            *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
  1546 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_INSENSITIVE);
  1697            } else {
  1547 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  1698              aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
  1548      sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
  1699 -            *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
  1549 +    gtk_style_context_restore(style);
  1700            }
  1550  
  1701  
  1551      style = gtk_widget_get_style_context(menu);
  1702            aState->active = FALSE;
  1552 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
  1703 @@ -510,8 +508,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
  1553 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
  1704      break;
  1554      sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
  1705    case NS_THEME_NUMBER_INPUT:
  1555  
  1706    case NS_THEME_TEXTFIELD:
  1556      style = gtk_widget_get_style_context(menuitem);
  1707 +    aGtkWidgetType = MOZ_GTK_ENTRY;
  1557 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
  1708 +    break;
  1558 +    gtk_style_context_save(style);
  1709    case NS_THEME_TEXTFIELD_MULTILINE:
  1559 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
  1710 +#if (MOZ_WIDGET_GTK == 3)
  1560 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
  1711 +    aGtkWidgetType = MOZ_GTK_TEXT_VIEW;
  1561      sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
  1712 +#else
  1562 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
  1713      aGtkWidgetType = MOZ_GTK_ENTRY;
  1563 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  1714 +#endif
  1564      sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
  1715      break;
  1565 +    gtk_style_context_restore(style);
  1716    case NS_THEME_LISTBOX:
  1566  
  1717    case NS_THEME_TREEVIEW:
  1567      g_object_unref(menu);
  1718 @@ -673,6 +677,13 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
       
  1719      aGtkWidgetType = MOZ_GTK_MENUPOPUP;
       
  1720      break;
       
  1721    case NS_THEME_MENUITEM:
       
  1722 +    {
       
  1723 +      nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
       
  1724 +      if (menuFrame && menuFrame->IsOnMenuBar()) {
       
  1725 +        aGtkWidgetType = MOZ_GTK_MENUBARITEM;
       
  1726 +        break;
       
  1727 +      }
       
  1728 +    }
       
  1729      aGtkWidgetType = MOZ_GTK_MENUITEM;
       
  1730      break;
       
  1731    case NS_THEME_MENUSEPARATOR:
       
  1732 diff -up firefox-48.0/widget/gtk/WidgetStyleCache.cpp.gtk3-20 firefox-48.0/widget/gtk/WidgetStyleCache.cpp
       
  1733 --- firefox-48.0/widget/gtk/WidgetStyleCache.cpp.gtk3-20	2016-07-25 22:22:07.000000000 +0200
       
  1734 +++ firefox-48.0/widget/gtk/WidgetStyleCache.cpp	2016-07-29 09:15:11.825285869 +0200
       
  1735 @@ -22,7 +22,7 @@ static bool sStyleContextNeedsRestore;
       
  1736  static GtkStyleContext* sCurrentStyleContext;
  1568  #endif
  1737  #endif
  1569 @@ -1266,44 +1290,54 @@ nsLookAndFeel::Init()
  1738  static GtkStyleContext*
  1570              GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]);
  1739 -GetStyleInternal(WidgetNodeType aNodeType);
  1571      }
  1740 +GetCssNodeStyleInternal(WidgetNodeType aNodeType);
  1572  #else
  1741  
  1573 +    GtkCssNode labelPath[] = {
  1742  static GtkWidget*
  1574 +       { GTK_TYPE_LABEL, "label", "view", NULL },
  1743  CreateWindowWidget()
  1575 +       { G_TYPE_NONE, "selection", NULL, NULL }
  1744 @@ -67,12 +67,175 @@ CreateCheckboxWidget()
  1576 +    };
  1745  static GtkWidget*
  1577 +
  1746  CreateRadiobuttonWidget()
  1578 +    GtkStyleContext *styleLabel;
  1747  {
  1579 +    GtkStyleContext *styleSelection;
  1748 -  GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "M");
  1580 +    GtkBorder padding;
  1749 +  GtkWidget* widget = gtk_radio_button_new_with_label(nullptr, "M");
  1581 +
  1750    AddToWindowContainer(widget);
  1582      // Text colors
  1751    return widget;
  1583 -    style = gtk_widget_get_style_context(textView);
  1752  }
       
  1753  
       
  1754  static GtkWidget*
       
  1755 +CreateMenuBarWidget()
       
  1756 +{
       
  1757 +  GtkWidget* widget = gtk_menu_bar_new();
       
  1758 +  AddToWindowContainer(widget);
       
  1759 +  return widget;
       
  1760 +}
       
  1761 +
       
  1762 +static GtkWidget*
       
  1763 +CreateMenuPopupWidget()
       
  1764 +{
       
  1765 +  GtkWidget* widget = gtk_menu_new();
       
  1766 +  gtk_menu_attach_to_widget(GTK_MENU(widget), GetWidget(MOZ_GTK_WINDOW),
       
  1767 +                            nullptr);
       
  1768 +  return widget;
       
  1769 +}
       
  1770 +
       
  1771 +static GtkWidget*
       
  1772 +CreateMenuItemWidget(WidgetNodeType aShellType)
       
  1773 +{
       
  1774 +  GtkWidget* widget = gtk_menu_item_new();
       
  1775 +  gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(aShellType)), widget);
       
  1776 +  return widget;
       
  1777 +}
       
  1778 +
       
  1779 +static GtkWidget*
       
  1780 +CreateProgressWidget()
       
  1781 +{
       
  1782 +  GtkWidget* widget = gtk_progress_bar_new();
       
  1783 +  AddToWindowContainer(widget);
       
  1784 +  return widget;
       
  1785 +}
       
  1786 +
       
  1787 +static GtkWidget*
       
  1788 +CreateTooltipWidget()
       
  1789 +{
       
  1790 +  MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr,
       
  1791 +             "CreateTooltipWidget should be used for Gtk < 3.20 only.");
       
  1792 +  GtkWidget* widget = CreateWindowWidget();
       
  1793 +  GtkStyleContext* style = gtk_widget_get_style_context(widget);
       
  1794 +  gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
       
  1795 +  return widget;
       
  1796 +}
       
  1797 +
       
  1798 +static GtkWidget*
       
  1799 +CreateExpanderWidget()
       
  1800 +{
       
  1801 +  GtkWidget* widget = gtk_expander_new("M");
       
  1802 +  AddToWindowContainer(widget);
       
  1803 +  return widget;
       
  1804 +}
       
  1805 +
       
  1806 +static GtkWidget*
       
  1807 +CreateFrameWidget()
       
  1808 +{
       
  1809 +  GtkWidget* widget = gtk_frame_new(nullptr);
       
  1810 +  AddToWindowContainer(widget);
       
  1811 +  return widget;
       
  1812 +}
       
  1813 +
       
  1814 +static GtkWidget*
       
  1815 +CreateGripperWidget()
       
  1816 +{
       
  1817 +  GtkWidget* widget = gtk_handle_box_new();
       
  1818 +  AddToWindowContainer(widget);
       
  1819 +  return widget;
       
  1820 +}
       
  1821 +
       
  1822 +static GtkWidget*
       
  1823 +CreateToolbarWidget()
       
  1824 +{
       
  1825 +  GtkWidget* widget = gtk_toolbar_new();
       
  1826 +  gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget);
       
  1827 +  gtk_widget_realize(widget);
       
  1828 +  return widget;
       
  1829 +}
       
  1830 +
       
  1831 +static GtkWidget*
       
  1832 +CreateToolbarSeparatorWidget()
       
  1833 +{
       
  1834 +  GtkWidget* widget = GTK_WIDGET(gtk_separator_tool_item_new());
       
  1835 +  AddToWindowContainer(widget);
       
  1836 +  return widget;
       
  1837 +}
       
  1838 +
       
  1839 +static GtkWidget*
       
  1840 +CreateInfoBarWidget()
       
  1841 +{
       
  1842 +  GtkWidget* widget = gtk_info_bar_new();
       
  1843 +  AddToWindowContainer(widget);
       
  1844 +  return widget;
       
  1845 +}
       
  1846 +
       
  1847 +static GtkWidget*
       
  1848 +CreateButtonWidget()
       
  1849 +{
       
  1850 +  GtkWidget* widget = gtk_button_new_with_label("M");
       
  1851 +  AddToWindowContainer(widget);
       
  1852 +  return widget;
       
  1853 +}
       
  1854 +
       
  1855 +static GtkWidget*
       
  1856 +CreateToggleButtonWidget()
       
  1857 +{
       
  1858 +  GtkWidget* widget = gtk_toggle_button_new();
       
  1859 +  AddToWindowContainer(widget);
       
  1860 +  return widget;
       
  1861 +}
       
  1862 +
       
  1863 +static GtkWidget*
       
  1864 +CreateButtonArrowWidget()
       
  1865 +{
       
  1866 +  GtkWidget* widget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
       
  1867 +  gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_TOGGLE_BUTTON)), widget);
       
  1868 +  gtk_widget_realize(widget);
       
  1869 +  gtk_widget_show(widget);
       
  1870 +  return widget;
       
  1871 +}
       
  1872 +
       
  1873 +static GtkWidget*
       
  1874 +CreateSpinWidget()
       
  1875 +{
       
  1876 +  GtkWidget* widget = gtk_spin_button_new(nullptr, 1, 0);
       
  1877 +  AddToWindowContainer(widget);
       
  1878 +  return widget;
       
  1879 +}
       
  1880 +
       
  1881 +static GtkWidget*
       
  1882 +CreateEntryWidget()
       
  1883 +{
       
  1884 +  GtkWidget* widget = gtk_entry_new();
       
  1885 +  AddToWindowContainer(widget);
       
  1886 +  return widget;
       
  1887 +}
       
  1888 +
       
  1889 +static GtkWidget*
       
  1890 +CreateScrolledWindowWidget()
       
  1891 +{
       
  1892 +  GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
       
  1893 +  AddToWindowContainer(widget);
       
  1894 +  return widget;
       
  1895 +}
       
  1896 +
       
  1897 +static GtkWidget*
       
  1898 +CreateTextViewWidget()
       
  1899 +{
       
  1900 +  GtkWidget* widget = gtk_text_view_new();
       
  1901 +  gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
       
  1902 +                    widget);
       
  1903 +  return widget;
       
  1904 +}
       
  1905 +
       
  1906 +static GtkWidget*
       
  1907 +CreateMenuSeparatorWidget()
       
  1908 +{
       
  1909 +  GtkWidget* widget = gtk_separator_menu_item_new();
       
  1910 +  gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
       
  1911 +                        widget);
       
  1912 +  gtk_widget_realize(widget);
       
  1913 +  return widget;
       
  1914 +}
       
  1915 +
       
  1916 +
       
  1917 +static GtkWidget*
       
  1918  CreateWidget(WidgetNodeType aWidgetType)
       
  1919  {
       
  1920    switch (aWidgetType) {
       
  1921 @@ -80,16 +243,54 @@ CreateWidget(WidgetNodeType aWidgetType)
       
  1922        return CreateWindowWidget();
       
  1923      case MOZ_GTK_WINDOW_CONTAINER:
       
  1924        return CreateWindowContainerWidget();
       
  1925 +    case MOZ_GTK_CHECKBUTTON_CONTAINER:
       
  1926 +      return CreateCheckboxWidget();
       
  1927 +    case MOZ_GTK_PROGRESSBAR:
       
  1928 +      return CreateProgressWidget();
       
  1929 +    case MOZ_GTK_RADIOBUTTON_CONTAINER:
       
  1930 +      return CreateRadiobuttonWidget();
       
  1931      case MOZ_GTK_SCROLLBAR_HORIZONTAL:
       
  1932        return CreateScrollbarWidget(aWidgetType,
       
  1933                                     GTK_ORIENTATION_HORIZONTAL);
       
  1934      case MOZ_GTK_SCROLLBAR_VERTICAL:
       
  1935        return CreateScrollbarWidget(aWidgetType,
       
  1936                                     GTK_ORIENTATION_VERTICAL);
       
  1937 -    case MOZ_GTK_CHECKBUTTON_CONTAINER:
       
  1938 -      return CreateCheckboxWidget();
       
  1939 -    case MOZ_GTK_RADIOBUTTON_CONTAINER:
       
  1940 -      return CreateRadiobuttonWidget();
       
  1941 +    case MOZ_GTK_MENUBAR:
       
  1942 +      return CreateMenuBarWidget();
       
  1943 +    case MOZ_GTK_MENUPOPUP:
       
  1944 +      return CreateMenuPopupWidget();
       
  1945 +    case MOZ_GTK_MENUBARITEM:
       
  1946 +      return CreateMenuItemWidget(MOZ_GTK_MENUBAR);
       
  1947 +    case MOZ_GTK_MENUITEM:
       
  1948 +      return CreateMenuItemWidget(MOZ_GTK_MENUPOPUP);
       
  1949 +    case MOZ_GTK_MENUSEPARATOR:
       
  1950 +      return CreateMenuSeparatorWidget();
       
  1951 +    case MOZ_GTK_EXPANDER:
       
  1952 +      return CreateExpanderWidget();
       
  1953 +    case MOZ_GTK_FRAME:
       
  1954 +      return CreateFrameWidget();
       
  1955 +    case MOZ_GTK_GRIPPER:
       
  1956 +      return CreateGripperWidget();
       
  1957 +    case MOZ_GTK_TOOLBAR:
       
  1958 +      return CreateToolbarWidget();
       
  1959 +    case MOZ_GTK_TOOLBAR_SEPARATOR:
       
  1960 +      return CreateToolbarSeparatorWidget();
       
  1961 +    case MOZ_GTK_INFO_BAR:
       
  1962 +      return CreateInfoBarWidget();
       
  1963 +    case MOZ_GTK_SPINBUTTON:
       
  1964 +      return CreateSpinWidget();
       
  1965 +    case MOZ_GTK_BUTTON:
       
  1966 +      return CreateButtonWidget();
       
  1967 +    case MOZ_GTK_TOGGLE_BUTTON:
       
  1968 +      return CreateToggleButtonWidget();
       
  1969 +    case MOZ_GTK_BUTTON_ARROW:
       
  1970 +      return CreateButtonArrowWidget();
       
  1971 +    case MOZ_GTK_ENTRY:
       
  1972 +      return CreateEntryWidget();
       
  1973 +    case MOZ_GTK_SCROLLED_WINDOW: 
       
  1974 +      return CreateScrolledWindowWidget();
       
  1975 +    case MOZ_GTK_TEXT_VIEW:
       
  1976 +      return CreateTextViewWidget();
       
  1977      default:
       
  1978        /* Not implemented */
       
  1979        return nullptr;
       
  1980 @@ -107,17 +308,42 @@ GetWidget(WidgetNodeType aWidgetType)
       
  1981    return widget;
       
  1982  }
       
  1983  
       
  1984 -static GtkStyleContext*
       
  1985 -CreateCSSNode(const char* aName, GtkStyleContext *aParentStyle)
       
  1986 +GtkStyleContext*
       
  1987 +CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle)
       
  1988 +{
       
  1989 +  GtkWidgetPath* path = aParentStyle ?
       
  1990 +    gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
       
  1991 +    gtk_widget_path_new();
       
  1992 +
       
  1993 +  // Work around https://bugzilla.gnome.org/show_bug.cgi?id=767312
       
  1994 +  // which exists in GTK+ 3.20.
       
  1995 +  gtk_widget_get_style_context(aWidget);
       
  1996 +
       
  1997 +  gtk_widget_path_append_for_widget(path, aWidget);
       
  1998 +  // Release any floating reference on aWidget.
       
  1999 +  g_object_ref_sink(aWidget);
       
  2000 +  g_object_unref(aWidget);
       
  2001 +
       
  2002 +  GtkStyleContext *context = gtk_style_context_new();
       
  2003 +  gtk_style_context_set_path(context, path);
       
  2004 +  gtk_style_context_set_parent(context, aParentStyle);
       
  2005 +  gtk_widget_path_unref(path);
       
  2006 +
       
  2007 +  return context;
       
  2008 +}
       
  2009 +
       
  2010 +GtkStyleContext*
       
  2011 +CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType)
       
  2012  {
       
  2013    static auto sGtkWidgetPathIterSetObjectName =
       
  2014      reinterpret_cast<void (*)(GtkWidgetPath *, gint, const char *)>
       
  2015      (dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name"));
       
  2016  
       
  2017 -  GtkWidgetPath* path =
       
  2018 -    gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle));
       
  2019 +  GtkWidgetPath* path = aParentStyle ?
       
  2020 +    gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
       
  2021 +    gtk_widget_path_new();
       
  2022  
       
  2023 -  gtk_widget_path_append_type(path, G_TYPE_NONE);
       
  2024 +  gtk_widget_path_append_type(path, aType);
       
  2025  
       
  2026    (*sGtkWidgetPathIterSetObjectName)(path, -1, aName);
       
  2027  
       
  2028 @@ -130,95 +356,168 @@ CreateCSSNode(const char* aName, GtkStyl
       
  2029  }
       
  2030  
       
  2031  static GtkStyleContext*
       
  2032 -GetChildNodeStyle(WidgetNodeType aStyleType,
       
  2033 -                  WidgetNodeType aWidgetType,
       
  2034 -                  const gchar*   aStyleClass,
       
  2035 -                  WidgetNodeType aParentNodeType)
       
  2036 +CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType)
       
  2037  {
       
  2038 -  GtkStyleContext* style;
       
  2039 -
       
  2040 -  if (gtk_check_version(3, 20, 0) != nullptr) {
       
  2041 -    style = gtk_widget_get_style_context(sWidgetStorage[aWidgetType]);
       
  2042 -
  1584 -    gtk_style_context_save(style);
  2043 -    gtk_style_context_save(style);
  1585 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
  2044 -    MOZ_ASSERT(!sStyleContextNeedsRestore);
  1586 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2045 -    sStyleContextNeedsRestore = true;
  1587 +    styleLabel = moz_gtk_style_create(labelPath, NULL);
  2046 -
  1588 +    styleSelection = moz_gtk_style_create(labelPath+1, styleLabel);
  2047 -    gtk_style_context_add_class(style, aStyleClass);
  1589 +
  2048 -  }
  1590 +    gtk_style_context_get_background_color(styleLabel, gtk_style_context_get_state(styleLabel), &color);
  2049 -  else {
  1591      sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
  2050 -    style = sStyleStorage[aStyleType];
  1592 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2051 -    if (!style) {
  1593 +    gtk_style_context_get_color(styleLabel, gtk_style_context_get_state(styleLabel), &color);
  2052 -      style = CreateCSSNode(aStyleClass, GetStyleInternal(aParentNodeType));
  1594      sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
  2053 -      MOZ_ASSERT(!sStyleContextNeedsRestore);
  1595  
  2054 -      sStyleStorage[aStyleType] = style;
  1596      // Selected text and background
  2055 -    }
  1597 -    gtk_style_context_get_background_color(style,
  2056 -  }
  1598 -        static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
  2057 +  return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
  1599 -        &color);
  2058 +}
  1600 +    gtk_style_context_get_background_color(styleSelection, gtk_style_context_get_state(styleSelection), &color);
  2059  
  1601      sTextSelectedBackground = GDK_RGBA_TO_NS_RGBA(color);
  2060 +static GtkStyleContext*
  1602 -    gtk_style_context_get_color(style,
  2061 +GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
  1603 -        static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
  2062 +{
  1604 -        &color);
  2063 +  GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType));
  1605 +    gtk_style_context_get_color(styleSelection, gtk_style_context_get_state(styleSelection), &color);
  2064 +  gtk_style_context_save(style);
  1606      sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
  2065 +  MOZ_ASSERT(!sStyleContextNeedsRestore);
  1607 -    gtk_style_context_restore(style);
  2066 +  sStyleContextNeedsRestore = true;
  1608  
  2067 +  gtk_style_context_add_class(style, aStyleClass);
  1609      // Button text, background, border
  2068    return style;
  1610      style = gtk_widget_get_style_context(label);
  2069  }
  1611 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2070  
  1612 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2071 +/* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
  1613      sButtonText = GDK_RGBA_TO_NS_RGBA(color);
  2072  static GtkStyleContext*
  1614 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
  2073 -GetStyleInternal(WidgetNodeType aNodeType)
  1615 +    gtk_style_context_save(style);
  2074 +GetCssNodeStyleInternal(WidgetNodeType aNodeType)
  1616 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
  2075  {
  1617 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2076 +  GtkStyleContext* style = sStyleStorage[aNodeType];
  1618      sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
  2077 +  if (style)
  1619 +    gtk_style_context_restore(style);
  2078 +    return style;
  1620  
  2079 +
  1621      // Combobox text color
  2080    switch (aNodeType) {
  1622      style = gtk_widget_get_style_context(comboboxLabel);
  2081 -    case MOZ_GTK_SCROLLBAR_HORIZONTAL:
  1623 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2082 -      /* Root CSS node / widget for scrollbars */
  1624 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2083 +    case MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL:
  1625      sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
  2084 +      style = CreateChildCSSNode("contents",
  1626  
  2085 +                                 MOZ_GTK_SCROLLBAR_HORIZONTAL);
  1627      // Menubar text and hover text colors    
  2086        break;
  1628      style = gtk_widget_get_style_context(menuBar);
  2087      case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
  1629 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2088 -      return GetChildNodeStyle(aNodeType,
  1630 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2089 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL,
  1631      sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
  2090 -                               GTK_STYLE_CLASS_TROUGH,
  1632 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
  2091 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL);
  1633 +    gtk_style_context_save(style);
  2092 -
  1634 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
  2093 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
  1635 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2094 +                                 MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL);
  1636      sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
  2095 +      break;
  1637 +    gtk_style_context_restore(style);
  2096      case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
  1638  
  2097 -      return GetChildNodeStyle(aNodeType,
  1639      // GTK's guide to fancy odd row background colors:
  2098 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL,
  1640      // 1) Check if a theme explicitly defines an odd row color
  2099 -                               GTK_STYLE_CLASS_SLIDER,
  1641 @@ -1316,7 +1350,7 @@ nsLookAndFeel::Init()
  2100 -                               MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
  1642      // Get odd row background color
  2101 -
  1643      gtk_style_context_save(style);
  2102 -    case MOZ_GTK_SCROLLBAR_VERTICAL:
  1644      gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
  2103 -      /* Root CSS node / widget for scrollbars */
  1645 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2104 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
  1646 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
  2105 +                                 MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
  1647      sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
  2106 +      break;
  1648      gtk_style_context_restore(style);
  2107 +    case MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL:
  1649  
  2108 +      style = CreateChildCSSNode("contents",
  1650 @@ -1334,9 +1368,11 @@ nsLookAndFeel::Init()
  2109 +                                 MOZ_GTK_SCROLLBAR_VERTICAL);
  1651      gtk_container_add(GTK_CONTAINER(parent), infoBar);
  2110        break;
  1652      gtk_container_add(GTK_CONTAINER(infoBarContent), infoBarLabel);
  2111      case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
  1653      style = gtk_widget_get_style_context(infoBarLabel);
  2112 -      return GetChildNodeStyle(aNodeType,
  1654 +    gtk_style_context_save(style);
  2113 -                               MOZ_GTK_SCROLLBAR_VERTICAL,
  1655      gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
  2114 -                               GTK_STYLE_CLASS_TROUGH,
  1656 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
  2115 -                               MOZ_GTK_SCROLLBAR_VERTICAL);
  1657 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
  2116 -
  1658      sInfoBarText = GDK_RGBA_TO_NS_RGBA(color);
  2117 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
  1659 +    gtk_style_context_restore(style);
  2118 +                                 MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL);
       
  2119 +      break;
       
  2120      case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
       
  2121 -      return GetChildNodeStyle(aNodeType,
       
  2122 -                               MOZ_GTK_SCROLLBAR_VERTICAL,
       
  2123 -                               GTK_STYLE_CLASS_SLIDER,
       
  2124 -                               MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
       
  2125 -
       
  2126 -    case MOZ_GTK_RADIOBUTTON_CONTAINER:
       
  2127 -      /* Root CSS node / widget for checkboxes */
       
  2128 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
       
  2129 +                                 MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
       
  2130        break;
       
  2131      case MOZ_GTK_RADIOBUTTON:
       
  2132 -      return GetChildNodeStyle(aNodeType,
       
  2133 -                               MOZ_GTK_RADIOBUTTON_CONTAINER,
       
  2134 -                               GTK_STYLE_CLASS_RADIO,
       
  2135 -                               MOZ_GTK_RADIOBUTTON_CONTAINER);
       
  2136 -    case MOZ_GTK_CHECKBUTTON_CONTAINER:
       
  2137 -      /* Root CSS node / widget for radiobuttons */
       
  2138 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO,
       
  2139 +                                 MOZ_GTK_RADIOBUTTON_CONTAINER);
       
  2140        break;
       
  2141      case MOZ_GTK_CHECKBUTTON:
       
  2142 -      return GetChildNodeStyle(aNodeType,
       
  2143 -                               MOZ_GTK_CHECKBUTTON_CONTAINER,
       
  2144 -                               GTK_STYLE_CLASS_CHECK,
       
  2145 -                               MOZ_GTK_CHECKBUTTON_CONTAINER);
       
  2146 -    default:
       
  2147 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
       
  2148 +                                 MOZ_GTK_CHECKBUTTON_CONTAINER);
       
  2149 +      break;
       
  2150 +    case MOZ_GTK_PROGRESS_TROUGH:
       
  2151 +      /* Progress bar background (trough) */
       
  2152 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
       
  2153 +                                 MOZ_GTK_PROGRESSBAR);
       
  2154 +      break;
       
  2155 +    case MOZ_GTK_PROGRESS_CHUNK:
       
  2156 +      style = CreateChildCSSNode("progress",
       
  2157 +                                 MOZ_GTK_PROGRESS_TROUGH);
       
  2158        break;
       
  2159 +    case MOZ_GTK_TOOLTIP:
       
  2160 +      // We create this from the path because GtkTooltipWindow is not public.
       
  2161 +      style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP);
       
  2162 +      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       
  2163 +      break; 
       
  2164 +    case MOZ_GTK_GRIPPER:
       
  2165 +      // TODO - create from CSS node
       
  2166 +      return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
       
  2167 +                                     GTK_STYLE_CLASS_GRIP);
       
  2168 +    case MOZ_GTK_INFO_BAR:
       
  2169 +      // TODO - create from CSS node
       
  2170 +      return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
       
  2171 +                                     GTK_STYLE_CLASS_INFO);
       
  2172 +    case MOZ_GTK_SPINBUTTON_ENTRY:
       
  2173 +      // TODO - create from CSS node
       
  2174 +      return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
       
  2175 +                                     GTK_STYLE_CLASS_ENTRY);
       
  2176 +    case MOZ_GTK_SCROLLED_WINDOW:
       
  2177 +      // TODO - create from CSS node
       
  2178 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
       
  2179 +                                     GTK_STYLE_CLASS_FRAME);
       
  2180 +    case MOZ_GTK_TEXT_VIEW:
       
  2181 +      // TODO - create from CSS node
       
  2182 +      return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
       
  2183 +                                     GTK_STYLE_CLASS_VIEW);
       
  2184 +    default:
       
  2185 +      // TODO - create style from style path
       
  2186 +      GtkWidget* widget = GetWidget(aNodeType);
       
  2187 +      return gtk_widget_get_style_context(widget);
       
  2188    }
       
  2189  
       
  2190 -  GtkWidget* widget = GetWidget(aNodeType);
       
  2191 -  if (widget) {
       
  2192 -    return gtk_widget_get_style_context(widget);
       
  2193 -  }
       
  2194 +  MOZ_ASSERT(style, "missing style context for node type");
       
  2195 +  sStyleStorage[aNodeType] = style;
       
  2196 +  return style;
       
  2197 +}
       
  2198  
       
  2199 -  MOZ_ASSERT_UNREACHABLE("missing style context for node type");
       
  2200 -  return nullptr;
       
  2201 +/* GetWidgetStyleInternal is used by Gtk < 3.20 */
       
  2202 +static GtkStyleContext*
       
  2203 +GetWidgetStyleInternal(WidgetNodeType aNodeType)
       
  2204 +{
       
  2205 +  switch (aNodeType) {
       
  2206 +    case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
       
  2207 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
       
  2208 +                                     GTK_STYLE_CLASS_TROUGH);
       
  2209 +    case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
       
  2210 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
       
  2211 +                                     GTK_STYLE_CLASS_SLIDER);
       
  2212 +    case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
       
  2213 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
       
  2214 +                                     GTK_STYLE_CLASS_TROUGH);
       
  2215 +    case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
       
  2216 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
       
  2217 +                                     GTK_STYLE_CLASS_SLIDER);
       
  2218 +    case MOZ_GTK_RADIOBUTTON:
       
  2219 +      return GetWidgetStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER,
       
  2220 +                                     GTK_STYLE_CLASS_RADIO);
       
  2221 +    case MOZ_GTK_CHECKBUTTON:
       
  2222 +      return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
       
  2223 +                                     GTK_STYLE_CLASS_CHECK);
       
  2224 +    case MOZ_GTK_PROGRESS_TROUGH:
       
  2225 +      return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
       
  2226 +                                     GTK_STYLE_CLASS_TROUGH);
       
  2227 +    case MOZ_GTK_TOOLTIP: {
       
  2228 +      GtkStyleContext* style = sStyleStorage[aNodeType];
       
  2229 +      if (style)
       
  2230 +        return style;
       
  2231 +
       
  2232 +      // The tooltip style class is added first in CreateTooltipWidget() so
       
  2233 +      // that gtk_widget_path_append_for_widget() in CreateStyleForWidget()
       
  2234 +      // will find it.
       
  2235 +      GtkWidget* tooltipWindow = CreateTooltipWidget();
       
  2236 +      style = CreateStyleForWidget(tooltipWindow, nullptr);
       
  2237 +      gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
       
  2238 +      sStyleStorage[aNodeType] = style;
       
  2239 +      return style;
       
  2240 +    }
       
  2241 +    case MOZ_GTK_GRIPPER:
       
  2242 +      return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
       
  2243 +                                     GTK_STYLE_CLASS_GRIP);
       
  2244 +    case MOZ_GTK_INFO_BAR:
       
  2245 +      return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
       
  2246 +                                     GTK_STYLE_CLASS_INFO);
       
  2247 +    case MOZ_GTK_SPINBUTTON_ENTRY:
       
  2248 +      return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
       
  2249 +                                     GTK_STYLE_CLASS_ENTRY);
       
  2250 +    case MOZ_GTK_SCROLLED_WINDOW:
       
  2251 +      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
       
  2252 +                                     GTK_STYLE_CLASS_FRAME);
       
  2253 +    case MOZ_GTK_TEXT_VIEW:
       
  2254 +      return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
       
  2255 +                                     GTK_STYLE_CLASS_VIEW);
       
  2256 +    default:
       
  2257 +      GtkWidget* widget = GetWidget(aNodeType);
       
  2258 +      MOZ_ASSERT(widget);
       
  2259 +      return gtk_widget_get_style_context(widget);
       
  2260 +  }
       
  2261  }
       
  2262  
       
  2263  void
       
  2264 @@ -245,13 +544,39 @@ ResetWidgetCache(void)
       
  2265  
       
  2266  GtkStyleContext*
       
  2267  ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
       
  2268 -                  StyleFlags aFlags)
       
  2269 +                  GtkStateFlags aStateFlags, StyleFlags aFlags)
       
  2270  {
       
  2271 -  GtkStyleContext* style = GetStyleInternal(aNodeType);
       
  2272 +  MOZ_ASSERT(!sStyleContextNeedsRestore);
       
  2273 +  GtkStyleContext* style;
       
  2274 +  if (gtk_check_version(3, 20, 0) != nullptr) {
       
  2275 +    style = GetWidgetStyleInternal(aNodeType);
       
  2276 +  } else {
       
  2277 +    style = GetCssNodeStyleInternal(aNodeType);
       
  2278 +  }
       
  2279  #ifdef DEBUG
       
  2280    MOZ_ASSERT(!sCurrentStyleContext);
       
  2281    sCurrentStyleContext = style;
  1660  #endif
  2282  #endif
  1661      // Some themes have a unified menu bar, and support window dragging on it
  2283 +  GtkStateFlags oldState = gtk_style_context_get_state(style);
  1662      gboolean supports_menubar_drag = FALSE;
  2284 +  GtkTextDirection oldDirection = gtk_style_context_get_direction(style);
  1663 diff -up firefox-46.0.1/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-46.0.1/widget/gtk/nsNativeThemeGTK.cpp
  2285 +  if (oldState != aStateFlags || oldDirection != aDirection) {
  1664 --- firefox-46.0.1/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20	2016-05-03 07:31:12.000000000 +0200
  2286 +    // From GTK 3.8, set_state() will overwrite the direction, so set
  1665 +++ firefox-46.0.1/widget/gtk/nsNativeThemeGTK.cpp	2016-05-19 15:20:11.658519202 +0200
  2287 +    // direction after state.
  1666 @@ -1567,9 +1567,6 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
  2288 +    gtk_style_context_set_state(style, aStateFlags);
  1667    case NS_THEME_RADIO_CONTAINER:
  2289 +    gtk_style_context_set_direction(style, aDirection);
  1668    case NS_THEME_CHECKBOX_LABEL:
  2290 +
  1669    case NS_THEME_RADIO_LABEL:
  2291 +    // This invalidate is necessary for unsaved style contexts from GtkWidgets
  1670 -  case NS_THEME_BUTTON:
  2292 +    // in pre-3.18 GTK, because automatic invalidation of such contexts
  1671 -  case NS_THEME_DROPDOWN:
  2293 +    // was delayed until a resize event runs.
  1672 -  case NS_THEME_TOOLBAR_BUTTON:
  2294 +    //
  1673    case NS_THEME_TREEVIEW_HEADER_CELL:
  2295 +    // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7
  1674      {
  2296 +    //
  1675        if (aWidgetType == NS_THEME_DROPDOWN) {
  2297 +    // Avoid calling invalidate on saved contexts to avoid performing
  1676 @@ -1588,6 +1585,21 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
  2298 +    // build_properties() (in 3.16 stylecontext.c) unnecessarily early.
  1677        aResult->height += border.top + border.bottom;
  2299 +    if (!sStyleContextNeedsRestore) {
  1678      }
  2300 +      gtk_style_context_invalidate(style);
  1679      break;
       
  1680 +  case NS_THEME_BUTTON:
       
  1681 +  case NS_THEME_DROPDOWN:
       
  1682 +  case NS_THEME_TOOLBAR_BUTTON:
       
  1683 +    {
       
  1684 +        moz_gtk_get_button_height(&aResult->height);
       
  1685 +    }
  2301 +    }
  1686 +    break;
  2302 +  }
  1687 +  case NS_THEME_FOCUS_OUTLINE:
  2303    return style;
  1688 +  case NS_THEME_NUMBER_INPUT:
  2304  }
  1689 +  case NS_THEME_TEXTFIELD:
  2305  
  1690 +  case NS_THEME_TEXTFIELD_MULTILINE:
  2306 diff -up firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20 firefox-48.0/widget/gtk/WidgetStyleCache.h
  1691 +    {
  2307 --- firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20	2016-07-25 22:22:07.000000000 +0200
  1692 +        moz_gtk_get_entry_height(&aResult->height);
  2308 +++ firefox-48.0/widget/gtk/WidgetStyleCache.h	2016-07-29 09:15:11.825285869 +0200
  1693 +    } 
  2309 @@ -21,10 +21,24 @@ enum : StyleFlags {
  1694 +    break;
  2310  GtkWidget*
  1695    case NS_THEME_TOOLBAR_SEPARATOR:
  2311  GetWidget(WidgetNodeType aNodeType);
  1696      {
  2312  
  1697        gint separator_width;
  2313 +/*
       
  2314 + * Return a new style context based on aWidget, as a child of aParentStyle.
       
  2315 + * If aWidget still has a floating reference, then it is sunk and released.
       
  2316 + */
       
  2317 +GtkStyleContext*
       
  2318 +CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle);
       
  2319 +
       
  2320 +// CreateCSSNode is implemented for gtk >= 3.20 only.
       
  2321 +GtkStyleContext*
       
  2322 +CreateCSSNode(const char*      aName,
       
  2323 +              GtkStyleContext* aParentStyle,
       
  2324 +              GType            aType = G_TYPE_NONE);
       
  2325 +
       
  2326  // Callers must call ReleaseStyleContext() on the returned context.
       
  2327  GtkStyleContext*
       
  2328  ClaimStyleContext(WidgetNodeType aNodeType,
       
  2329                    GtkTextDirection aDirection = GTK_TEXT_DIR_LTR,
       
  2330 +                  GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
       
  2331                    StyleFlags aFlags = NO_STYLE_FLAGS);
       
  2332  void
       
  2333  ReleaseStyleContext(GtkStyleContext* style);
       
  2334