]> git.pld-linux.org Git - packages/firefox.git/blob - firefox-gtk3-20.patch
- rebuild with libvpx 1.6
[packages/firefox.git] / firefox-gtk3-20.patch
1 diff -up firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20 firefox-48.0/widget/gtk/gtk3drawing.cpp
2 --- firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20     2016-07-25 22:22:07.000000000 +0200
3 +++ firefox-48.0/widget/gtk/gtk3drawing.cpp     2016-07-29 09:15:11.822285857 +0200
4 @@ -18,15 +18,9 @@
5  
6  #include <math.h>
7  
8 -static GtkWidget* gProtoWindow;
9  static GtkWidget* gProtoLayout;
10 -static GtkWidget* gButtonWidget;
11 -static GtkWidget* gToggleButtonWidget;
12 -static GtkWidget* gButtonArrowWidget;
13 -static GtkWidget* gSpinWidget;
14  static GtkWidget* gHScaleWidget;
15  static GtkWidget* gVScaleWidget;
16 -static GtkWidget* gEntryWidget;
17  static GtkWidget* gComboBoxWidget;
18  static GtkWidget* gComboBoxButtonWidget;
19  static GtkWidget* gComboBoxArrowWidget;
20 @@ -35,30 +29,15 @@ static GtkWidget* gComboBoxEntryWidget;
21  static GtkWidget* gComboBoxEntryTextareaWidget;
22  static GtkWidget* gComboBoxEntryButtonWidget;
23  static GtkWidget* gComboBoxEntryArrowWidget;
24 -static GtkWidget* gHandleBoxWidget;
25 -static GtkWidget* gToolbarWidget;
26 -static GtkWidget* gFrameWidget;
27 -static GtkWidget* gProgressWidget;
28  static GtkWidget* gTabWidget;
29 -static GtkWidget* gTextViewWidget;
30 -static GtkWidget* gTooltipWidget;
31 -static GtkWidget* gMenuBarWidget;
32 -static GtkWidget* gMenuBarItemWidget;
33 -static GtkWidget* gMenuPopupWidget;
34 -static GtkWidget* gMenuItemWidget;
35  static GtkWidget* gImageMenuItemWidget;
36  static GtkWidget* gCheckMenuItemWidget;
37  static GtkWidget* gTreeViewWidget;
38  static GtkTreeViewColumn* gMiddleTreeViewColumn;
39  static GtkWidget* gTreeHeaderCellWidget;
40  static GtkWidget* gTreeHeaderSortArrowWidget;
41 -static GtkWidget* gExpanderWidget;
42 -static GtkWidget* gToolbarSeparatorWidget;
43 -static GtkWidget* gMenuSeparatorWidget;
44  static GtkWidget* gHPanedWidget;
45  static GtkWidget* gVPanedWidget;
46 -static GtkWidget* gScrolledWindowWidget;
47 -static GtkWidget* gInfoBar;
48  
49  static style_prop_t style_prop_func;
50  static gboolean have_arrow_scaling;
51 @@ -94,15 +73,6 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
52      return stateFlags;
53  }
54  
55 -/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
56 -   that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
57 -   things they may want to do. */
58 -static void
59 -moz_gtk_set_widget_name(GtkWidget* widget)
60 -{
61 -    gtk_widget_set_name(widget, "MozillaGtkWidget");
62 -}
63 -
64  gint
65  moz_gtk_enable_style_props(style_prop_t styleGetProp)
66  {
67 @@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t
68  }
69  
70  static gint
71 -ensure_window_widget()
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 -{
89 -    if (!gButtonWidget) {
90 -        gButtonWidget = gtk_button_new_with_label("M");
91 -        setup_widget_prototype(gButtonWidget);
92 -    }
93 -    return MOZ_GTK_SUCCESS;
94 -}
95 -
96 -static gint
97  ensure_hpaned_widget()
98  {
99      if (!gHPanedWidget) {
100 @@ -160,40 +111,6 @@ ensure_vpaned_widget()
101  }
102  
103  static gint
104 -ensure_toggle_button_widget()
105 -{
106 -    if (!gToggleButtonWidget) {
107 -        gToggleButtonWidget = gtk_toggle_button_new();
108 -        setup_widget_prototype(gToggleButtonWidget);
109 -  }
110 -  return MOZ_GTK_SUCCESS;
111 -}
112 -
113 -static gint
114 -ensure_button_arrow_widget()
115 -{
116 -    if (!gButtonArrowWidget) {
117 -        ensure_toggle_button_widget();
118 -
119 -        gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
120 -        gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget);
121 -        gtk_widget_realize(gButtonArrowWidget);
122 -        gtk_widget_show(gButtonArrowWidget);
123 -    }
124 -    return MOZ_GTK_SUCCESS;
125 -}
126 -
127 -static gint
128 -ensure_spin_widget()
129 -{
130 -  if (!gSpinWidget) {
131 -    gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
132 -    setup_widget_prototype(gSpinWidget);
133 -  }
134 -  return MOZ_GTK_SUCCESS;
135 -}
136 -
137 -static gint
138  ensure_scale_widget()
139  {
140    if (!gHScaleWidget) {
141 @@ -207,16 +124,6 @@ ensure_scale_widget()
142    return MOZ_GTK_SUCCESS;
143  }
144  
145 -static gint
146 -ensure_entry_widget()
147 -{
148 -    if (!gEntryWidget) {
149 -        gEntryWidget = gtk_entry_new();
150 -        setup_widget_prototype(gEntryWidget);
151 -    }
152 -    return MOZ_GTK_SUCCESS;
153 -}
154 -
155  /* We need to have pointers to the inner widgets (button, separator, arrow)
156   * of the ComboBox to get the correct rendering from theme engines which
157   * special cases their look. Since the inner layout can change, we ask GTK
158 @@ -225,7 +132,7 @@ ensure_entry_widget()
159   * g_object_add_weak_pointer().
160   * Note that if we don't find the inner widgets (which shouldn't happen), we
161   * fallback to use generic "non-inner" widgets, and they don't need that kind
162 - * of weak pointer since they are explicit children of gProtoWindow and as
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);
174      }
175  
176      if (!gComboBoxArrowWidget) {
177          /* Shouldn't be reached with current internal gtk implementation;
178           * we gButtonArrowWidget as last resort fallback to avoid
179           * crashing. */
180 -        ensure_button_arrow_widget();
181 -        gComboBoxArrowWidget = gButtonArrowWidget;
182 +        gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
183      }
184  
185      /* We don't test the validity of gComboBoxSeparatorWidget since there
186 @@ -316,15 +221,6 @@ ensure_combo_box_widgets()
187      return MOZ_GTK_SUCCESS;
188  }
189  
190 -static void
191 -ensure_info_bar()
192 -{
193 -  if (!gInfoBar) {
194 -      gInfoBar = gtk_info_bar_new();
195 -      setup_widget_prototype(gInfoBar);
196 -  }
197 -}
198 -
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()
212                           NULL);
213  
214      if (!gComboBoxEntryTextareaWidget) {
215 -        ensure_entry_widget();
216 -        gComboBoxEntryTextareaWidget = gEntryWidget;
217 +        gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
218      }
219  
220      if (gComboBoxEntryButtonWidget) {
221 @@ -412,68 +307,19 @@ ensure_combo_box_entry_widgets()
222          /* Shouldn't be reached with current internal gtk implementation;
223           * we use a generic toggle button as last resort fallback to avoid
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 -{
279 -    if (!gTooltipWidget) {
280 -        gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
281 -        GtkStyleContext* style = gtk_widget_get_style_context(gTooltipWidget);
282 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
283 -        gtk_widget_realize(gTooltipWidget);
284 -        moz_gtk_set_widget_name(gTooltipWidget);
285 -    }
286 -    return MOZ_GTK_SUCCESS;
287 -}
288 -
289  static gint
290  ensure_tab_widget()
291  {
292 @@ -485,81 +331,11 @@ ensure_tab_widget()
293  }
294  
295  static gint
296 -ensure_progress_widget()
297 -{
298 -    if (!gProgressWidget) {
299 -        gProgressWidget = gtk_progress_bar_new();
300 -        setup_widget_prototype(gProgressWidget);
301 -    }
302 -    return MOZ_GTK_SUCCESS;
303 -}
304 -
305 -static gint
306 -ensure_frame_widget()
307 -{
308 -    if (!gFrameWidget) {
309 -        gFrameWidget = gtk_frame_new(NULL);
310 -        setup_widget_prototype(gFrameWidget);
311 -    }
312 -    return MOZ_GTK_SUCCESS;
313 -}
314 -
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);
374      }
375 @@ -567,25 +343,11 @@ ensure_image_menu_item_widget()
376  }
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
392  ensure_check_menu_item_widget()
393  {
394      if (!gCheckMenuItemWidget) {
395 -        ensure_menu_popup_widget();
396 -        gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
397 -        gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
398 +        gCheckMenuItemWidget = gtk_check_menu_item_new();
399 +        gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
400                                gCheckMenuItemWidget);
401          gtk_widget_realize(gCheckMenuItemWidget);
402      }
403 @@ -646,37 +408,6 @@ ensure_tree_header_cell_widget()
404      return MOZ_GTK_SUCCESS;
405  }
406  
407 -static gint
408 -ensure_expander_widget()
409 -{
410 -    if (!gExpanderWidget) {
411 -        gExpanderWidget = gtk_expander_new("M");
412 -        setup_widget_prototype(gExpanderWidget);
413 -    }
414 -    return MOZ_GTK_SUCCESS;
415 -}
416 -
417 -static gint
418 -ensure_scrolled_window_widget()
419 -{
420 -    if (!gScrolledWindowWidget) {
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
442  {
443      GtkBorder border;
444      GtkBorder padding;
445 -    GtkStyleContext *style;
446 -
447 -    ensure_entry_widget();
448 -    style = gtk_widget_get_style_context(gEntryWidget);
449 -
450 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY);
451      gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
452      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
453      *focus_h_width = border.left + padding.left;
454      *focus_v_width = border.top + padding.top;
455 +    ReleaseStyleContext(style);
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  {
475      GtkBorder* default_outside_border;
476  
477 -    ensure_button_widget();
478 -    gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
479 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
480 +    gtk_style_context_get_style(style,
481                                  "default-outside-border", &default_outside_border,
482                                  NULL);
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  {
489      GtkBorder* default_border;
490  
491 -    ensure_button_widget();
492 -    gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
493 +    GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
494 +    gtk_style_context_get_style(style,
495                                  "default-border", &default_border,
496                                  NULL);
497 +    ReleaseStyleContext(style);
498  
499      if (default_border) {
500          *border_top = default_border->top;
501 @@ -831,17 +559,15 @@ static gint
502  moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
503                       GtkTextDirection direction)
504  {
505 -    GtkStyleContext* style;
506 -
507 -    ensure_window_widget();
508 -    gtk_widget_set_direction(gProtoWindow, direction);
509 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
510  
511 -    style = gtk_widget_get_style_context(gProtoWindow);        
512      gtk_style_context_save(style);
513      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
514      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
515      gtk_style_context_restore(style);
516  
517 +    ReleaseStyleContext(style);
518 +
519      return MOZ_GTK_SUCCESS;
520  }
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);
570      }
571  
572 -    GtkStyleContext* style =
573 -        ClaimStyleContext(widget == MOZ_GTK_SCROLLBAR_HORIZONTAL ?
574 -                          MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
575 -                          MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
576 -                          direction);
577 -    // TODO - integate with ClaimStyleContext()?
578 -    gtk_style_context_set_direction(style, direction);
579 +    bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL);
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);
632 -    gtk_style_context_save(style);
633 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
634 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction);
635      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
636      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
637 -    gtk_style_context_restore(style);
638 -
639 +    ReleaseStyleContext(style);
640      return MOZ_GTK_SUCCESS;
641  }
642  
643 @@ -1204,21 +956,14 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
644                            gboolean isDown, GtkWidgetState* state,
645                            GtkTextDirection direction)
646  {
647 -    GdkRectangle arrow_rect;
648 -    GtkStyleContext* style;
649 -
650 -    ensure_spin_widget();
651 -    style = gtk_widget_get_style_context(gSpinWidget);
652 -    gtk_style_context_save(style);
653 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
654 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
655 -    gtk_widget_set_direction(gSpinWidget, direction);
656 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction,
657 +                                 GetStateFlagsFromGtkWidgetState(state));
658  
659      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
660      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
661  
662 -
663      /* hard code these values */
664 +    GdkRectangle arrow_rect;
665      arrow_rect.width = 6;
666      arrow_rect.height = 6;
667      arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
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  {
692 -    GtkStyleContext* style;
693 -
694 -    ensure_handlebox_widget();
695 -    gtk_widget_set_direction(gHandleBoxWidget, direction);
696 -
697 -    style = gtk_widget_get_style_context(gHandleBoxWidget);
698 -    gtk_style_context_save(style);
699 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
700 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
701 -
702 +    GtkStyleContext* style =
703 +            ClaimStyleContext(MOZ_GTK_GRIPPER, direction,
704 +                              GetStateFlagsFromGtkWidgetState(state));
705      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
706      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
707 -    gtk_style_context_restore(style);
708 -
709 +    ReleaseStyleContext(style);
710      return MOZ_GTK_SUCCESS;
711  }
712  
713 @@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
714      return MOZ_GTK_SUCCESS;
715  }
716  
717 +static gint
718 +moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
719 +                        GtkWidgetState* state,
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);
770      xthickness = border.left;
771      ythickness = border.top;    
772 @@ -1473,7 +1238,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
773                            rect->height - 2 * ythickness);
774      gtk_render_frame(style, cr, 
775                       rect->x, rect->y, rect->width, rect->height); 
776 -    gtk_style_context_restore(style);
777 +    ReleaseStyleContext(style);
778      gtk_style_context_restore(style_tree);
779      return MOZ_GTK_SUCCESS;
780  }
781 @@ -1648,20 +1413,9 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
782                      GtkWidgetState* state,
783                      GtkArrowType arrow_type, GtkTextDirection direction)
784  {
785 -    GtkStyleContext* style;
786 -    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
787      GdkRectangle arrow_rect;
788      gdouble arrow_angle;
789  
790 -    ensure_button_arrow_widget();
791 -    style = gtk_widget_get_style_context(gButtonArrowWidget);
792 -    gtk_style_context_save(style);
793 -    gtk_style_context_set_state(style, state_flags);
794 -    gtk_widget_set_direction(gButtonArrowWidget, direction);
795 -
796 -    calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
797 -                         direction);
798 -
799      if (direction == GTK_TEXT_DIR_RTL) {
800          arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
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;
805      }
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);                    
809 -    gtk_style_context_restore(style);
810 +    if (arrow_type == GTK_ARROW_NONE)
811 +        return MOZ_GTK_SUCCESS;
812 +
813 +    calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
814 +                         direction);
815 +    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
816 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_BUTTON_ARROW,
817 +                                               direction, state_flags);
818 +    gtk_render_arrow(style, cr, arrow_angle,
819 +                     arrow_rect.x, arrow_rect.y, arrow_rect.width);
820 +    ReleaseStyleContext(style);
821      return MOZ_GTK_SUCCESS;
822  }
823  
824 @@ -1776,19 +1537,10 @@ static gint
825  moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
826                        GtkTextDirection direction)
827  {
828 -    GtkStyleContext* style;
829 -
830 -    ensure_toolbar_widget();
831 -    gtk_widget_set_direction(gToolbarWidget, direction);
832 -
833 -    style = gtk_widget_get_style_context(gToolbarWidget);
834 -    gtk_style_context_save(style);
835 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLBAR);
836 -
837 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR, direction);
838      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
839      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
840 -    gtk_style_context_restore(style);
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
949  moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
950                            GtkTextDirection direction)
951  {
952 -    GtkStyleContext* style;
953 -
954 -    ensure_progress_widget();
955 -    gtk_widget_set_direction(gProgressWidget, direction);
956 -
957 -    style = gtk_widget_get_style_context(gProgressWidget);
958 -    gtk_style_context_save(style);
959 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
960 -    
961 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH,
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);
965 -    gtk_style_context_restore(style);
966 +    ReleaseStyleContext(style);
967  
968      return MOZ_GTK_SUCCESS;
969  }
970 @@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
971  {
972      GtkStyleContext* style;
973  
974 -    ensure_progress_widget();
975 -    gtk_widget_set_direction(gProgressWidget, direction);
976 -
977 -    style = gtk_widget_get_style_context(gProgressWidget);
978 -    gtk_style_context_save(style);
979 -    gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
980 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
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 +    }
990  
991      if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
992          widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
993 @@ -1990,7 +1720,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
994      } else {
995        gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
996      }
997 -    gtk_style_context_restore(style);
998 +    ReleaseStyleContext(style);
999  
1000      return MOZ_GTK_SUCCESS;
1001  }
1002 @@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR
1003  {
1004      GtkStyleContext* style;
1005  
1006 -    ensure_menu_bar_widget();
1007 -    gtk_widget_set_direction(gMenuBarWidget, direction);
1008 +    GtkWidget* widget = GetWidget(MOZ_GTK_MENUBAR);
1009 +    gtk_widget_set_direction(widget, direction);
1010  
1011 -    style = gtk_widget_get_style_context(gMenuBarWidget);
1012 +    style = gtk_widget_get_style_context(widget);
1013      gtk_style_context_save(style);
1014      gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
1015      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
1016 @@ -2343,14 +2073,14 @@ moz_gtk_menu_popup_paint(cairo_t *cr, Gd
1017  {
1018      GtkStyleContext* style;
1019  
1020 -    ensure_menu_popup_widget();
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.
1061  static gint
1062 -moz_gtk_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
1063 -                        GtkWidgetState* state,
1064 -                        gint flags, GtkTextDirection direction)
1065 +moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
1066 +                        GtkWidgetState* state, GtkTextDirection direction)
1067  {
1068 -    GtkStyleContext* style;
1069 -    GtkWidget* item_widget;
1070 -    guint border_width;
1071      gint x, y, w, h;
1072  
1073      if (state->inHover && !state->disabled) {   
1074 -        if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
1075 -            ensure_menu_bar_item_widget();
1076 -            item_widget = gMenuBarItemWidget;
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 +            }
1100          }
1101  
1102 -        gtk_widget_set_direction(item_widget, direction);
1103 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
1104 -        gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
1105 -
1106 -        border_width = gtk_container_get_border_width(GTK_CONTAINER(item_widget));
1107 -
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
1112  
1113          gtk_render_background(style, cr, x, y, w, h);
1114          gtk_render_frame(style, cr, x, y, w, h);
1115 -        gtk_style_context_restore(style);
1116 +
1117 +        if (pre_3_6) {
1118 +            gtk_style_context_restore(style);
1119 +        }
1120 +        ReleaseStyleContext(style);
1121      }
1122  
1123      return MOZ_GTK_SUCCESS;
1124 @@ -2462,21 +2188,13 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
1125                           GtkWidgetState* state,
1126                           GtkTextDirection direction)
1127  {
1128 -    GtkStyleContext* style;
1129      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
1130 -
1131 -    ensure_menu_item_widget();
1132 -    gtk_widget_set_direction(gMenuItemWidget, direction);
1133 -
1134 -    style = gtk_widget_get_style_context(gMenuItemWidget);
1135 -    gtk_style_context_save(style);
1136 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
1137 -    gtk_style_context_set_state(style, state_flags);
1138 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUITEM,
1139 +                                               direction, state_flags);
1140      gtk_render_arrow(style, cr,
1141                      (direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
1142                      rect->x, rect->y, rect->width);
1143 -    gtk_style_context_restore(style);
1144 -
1145 +    ReleaseStyleContext(style);
1146      return MOZ_GTK_SUCCESS;
1147  }
1148  
1149 @@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
1150      gint indicator_size, horizontal_padding;
1151      gint x, y;
1152  
1153 -    moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction);
1154 +    moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
1155  
1156      ensure_check_menu_item_widget();
1157      gtk_widget_set_direction(gCheckMenuItemWidget, direction);
1158 @@ -2545,21 +2263,13 @@ static gint
1159  moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect,
1160                         GtkWidgetState* state)
1161  {
1162 -    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
1163 -    GtkStyleContext *style;
1164 -    ensure_info_bar();
1165 -
1166 -    style = gtk_widget_get_style_context(gInfoBar);
1167 -    gtk_style_context_save(style);
1168 -
1169 -    gtk_style_context_set_state(style, state_flags);
1170 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
1171 -
1172 +    GtkStyleContext *style =
1173 +        ClaimStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
1174 +                          GetStateFlagsFromGtkWidgetState(state));
1175      gtk_render_background(style, cr, rect->x, rect->y, rect->width,
1176                            rect->height);
1177      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
1178 -
1179 -    gtk_style_context_restore(style);
1180 +    ReleaseStyleContext(style);
1181  
1182      return MOZ_GTK_SUCCESS;
1183  }
1184 @@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType
1185      case MOZ_GTK_BUTTON:
1186      case MOZ_GTK_TOOLBAR_BUTTON:
1187          {
1188 -            ensure_button_widget();
1189 -            style = gtk_widget_get_style_context(gButtonWidget);
1190 +            style = ClaimStyleContext(MOZ_GTK_BUTTON);
1191  
1192 -            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
1193 +            *left = *top = *right = *bottom =
1194 +                gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
1195  
1196              if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
1197                  gtk_style_context_save(style);
1198                  gtk_style_context_add_class(style, "image-button");
1199              }
1200 -              
1201 +
1202              moz_gtk_add_style_padding(style, left, top, right, bottom);
1203 -                
1204 +
1205              if (widget == MOZ_GTK_TOOLBAR_BUTTON)
1206                  gtk_style_context_restore(style);
1207  
1208 @@ -2624,12 +2334,13 @@ moz_gtk_get_widget_border(WidgetNodeType
1209              // -moz-focus-inner border (Bug 1228281).
1210              *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
1211              moz_gtk_add_style_border(style, left, top, right, bottom);
1212 +
1213 +            ReleaseStyleContext(style);
1214              return MOZ_GTK_SUCCESS;
1215          }
1216      case MOZ_GTK_ENTRY:
1217          {
1218 -            ensure_entry_widget();
1219 -            style = gtk_widget_get_style_context(gEntryWidget);
1220 +            style = ClaimStyleContext(MOZ_GTK_ENTRY);
1221  
1222              // XXX: Subtract 1 pixel from the padding to account for the default
1223              // padding in forms.css. See bug 1187385.
1224 @@ -2637,16 +2348,15 @@ moz_gtk_get_widget_border(WidgetNodeType
1225              moz_gtk_add_style_padding(style, left, top, right, bottom);
1226              moz_gtk_add_style_border(style, left, top, right, bottom);
1227  
1228 +            ReleaseStyleContext(style);
1229              return MOZ_GTK_SUCCESS;
1230          }
1231 +    case MOZ_GTK_TEXT_VIEW:
1232      case MOZ_GTK_TREEVIEW:
1233          {
1234 -            ensure_scrolled_window_widget();
1235 -            style = gtk_widget_get_style_context(gScrolledWindowWidget);
1236 -            gtk_style_context_save(style);
1237 -            gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
1238 +            style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW);
1239              moz_gtk_add_style_border(style, left, top, right, bottom);
1240 -            gtk_style_context_restore(style);
1241 +            ReleaseStyleContext(style);
1242              return MOZ_GTK_SUCCESS;
1243          }
1244      case MOZ_GTK_TREE_HEADER_CELL:
1245 @@ -2726,14 +2436,12 @@ moz_gtk_get_widget_border(WidgetNodeType
1246          w = gTabWidget;
1247          break;
1248      case MOZ_GTK_PROGRESSBAR:
1249 -        ensure_progress_widget();
1250 -        w = gProgressWidget;
1251 +        w = GetWidget(MOZ_GTK_PROGRESSBAR);
1252          break;
1253      case MOZ_GTK_SPINBUTTON_ENTRY:
1254      case MOZ_GTK_SPINBUTTON_UP:
1255      case MOZ_GTK_SPINBUTTON_DOWN:
1256 -        ensure_spin_widget();
1257 -        w = gSpinWidget;
1258 +        w = GetWidget(MOZ_GTK_SPINBUTTON);
1259          break;
1260      case MOZ_GTK_SCALE_HORIZONTAL:
1261          ensure_scale_widget();
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:
1284          {
1285 -            if (widget == MOZ_GTK_MENUITEM) {
1286 -                ensure_menu_item_widget();
1287 -                ensure_menu_bar_item_widget();
1288 -                w = gMenuItemWidget;
1289 -            }
1290 -            else {
1291 +            if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) {
1292 +                // Bug 1274143 for MOZ_GTK_MENUBARITEM
1293 +                w = GetWidget(MOZ_GTK_MENUITEM);
1294 +            } else {
1295                  ensure_check_menu_item_widget();
1296                  w = gCheckMenuItemWidget;
1297              }
1298 @@ -2784,9 +2489,16 @@ moz_gtk_get_widget_border(WidgetNodeType
1299              return MOZ_GTK_SUCCESS;
1300          }
1301      case MOZ_GTK_INFO_BAR:
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
1318      case MOZ_GTK_MENUSEPARATOR:
1319      /* These widgets have no borders.*/
1320      case MOZ_GTK_SPINBUTTON:
1321 -    case MOZ_GTK_TOOLTIP:
1322      case MOZ_GTK_WINDOW:
1323      case MOZ_GTK_RESIZER:
1324      case MOZ_GTK_MENUARROW:
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;
1354  }
1355  
1356  gint
1357  moz_gtk_get_expander_size(gint* size)
1358  {
1359 -    ensure_expander_widget();
1360 -    gtk_style_context_get_style(gtk_widget_get_style_context(gExpanderWidget),
1361 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_EXPANDER);
1362 +    gtk_style_context_get_style(style,
1363                                  "expander-size", size,
1364                                  NULL);
1365 -
1366 +    ReleaseStyleContext(style);
1367      return MOZ_GTK_SUCCESS;
1368  }
1369  
1370 @@ -2972,11 +2681,11 @@ moz_gtk_get_menu_separator_height(gint *
1371      GtkStyleContext* style;
1372      guint border_width;
1373  
1374 -    ensure_menu_separator_widget();
1375 -
1376 -    border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
1377 +    border_width =
1378 +        gtk_container_get_border_width(GTK_CONTAINER(
1379 +                                       GetWidget(MOZ_GTK_MENUSEPARATOR)));
1380  
1381 -    style = gtk_widget_get_style_context(gMenuSeparatorWidget);
1382 +    style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR);
1383      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
1384  
1385      gtk_style_context_save(style);
1386 @@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint *
1387                                  NULL);
1388  
1389      gtk_style_context_restore(style);
1390 +    ReleaseStyleContext(style);
1391  
1392      *size = padding.top + padding.bottom + border_width*2;
1393      *size += (wide_separators) ? separator_height : 1;
1394 @@ -2998,8 +2708,7 @@ moz_gtk_get_menu_separator_height(gint *
1395  void
1396  moz_gtk_get_entry_min_height(gint* height)
1397  {
1398 -    ensure_entry_widget();
1399 -    GtkStyleContext* style = gtk_widget_get_style_context(gEntryWidget);
1400 +    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY);
1401      if (!gtk_check_version(3, 20, 0)) {
1402          gtk_style_context_get(style, gtk_style_context_get_state(style),
1403                                "min-height", height,
1404 @@ -3014,6 +2723,7 @@ moz_gtk_get_entry_min_height(gint* heigh
1405      gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
1406  
1407      *height += (border.top + border.bottom + padding.top + padding.bottom);
1408 +    ReleaseStyleContext(style);
1409  }
1410  
1411  void
1412 @@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons()
1413      gboolean result;
1414      GtkSettings* settings;
1415  
1416 -    ensure_button_widget();
1417 -    settings = gtk_widget_get_settings(gButtonWidget);
1418 +    settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
1419  
1420      g_object_get(settings, "gtk-button-images", &result, NULL);
1421      return result;
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);
1432          }
1433 -        ensure_button_widget();
1434          return moz_gtk_button_paint(cr, rect, state,
1435 -                                    (GtkReliefStyle) flags, gButtonWidget,
1436 +                                    (GtkReliefStyle) flags,
1437 +                                    GetWidget(MOZ_GTK_BUTTON),
1438                                      direction);
1439          break;
1440      case MOZ_GTK_CHECKBUTTON:
1441 @@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
1442                                           state, direction);
1443          break;
1444      case MOZ_GTK_SPINBUTTON_ENTRY:
1445 -        ensure_spin_widget();
1446 +        // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly
1447          return moz_gtk_entry_paint(cr, rect, state,
1448 -                                   gSpinWidget, direction);
1449 +                                   GetWidget(MOZ_GTK_SPINBUTTON), direction);
1450          break;
1451      case MOZ_GTK_GRIPPER:
1452          return moz_gtk_gripper_paint(cr, rect, state,
1453 @@ -3198,9 +2907,11 @@ moz_gtk_widget_paint(WidgetNodeType widg
1454                                                 (GtkExpanderStyle) flags, direction);
1455          break;
1456      case MOZ_GTK_ENTRY:
1457 -        ensure_entry_widget();
1458 -        return moz_gtk_entry_paint(cr, rect, state,
1459 -                                   gEntryWidget, 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);
1465          break;
1466      case MOZ_GTK_DROPDOWN:
1467          return moz_gtk_combo_box_paint(cr, rect, state, direction);
1468 @@ -3271,9 +2982,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
1469          return moz_gtk_menu_separator_paint(cr, rect,
1470                                              direction);
1471          break;
1472 +    case MOZ_GTK_MENUBARITEM:
1473      case MOZ_GTK_MENUITEM:
1474 -        return moz_gtk_menu_item_paint(cr, rect, state, flags,
1475 -                                       direction);
1476 +        return moz_gtk_menu_item_paint(widget, cr, rect, state, direction);
1477          break;
1478      case MOZ_GTK_MENUARROW:
1479          return moz_gtk_menu_arrow_paint(cr, rect, state,
1480 @@ -3333,25 +3044,16 @@ gboolean moz_gtk_has_scrollbar_buttons(v
1481  gint
1482  moz_gtk_shutdown()
1483  {
1484 -    if (gTooltipWidget)
1485 -        gtk_widget_destroy(gTooltipWidget);
1486      /* This will destroy all of our widgets */
1487 -
1488      ResetWidgetCache();
1489  
1490      /* TODO - replace it with appropriate widget */
1491      if (gTreeHeaderSortArrowWidget)
1492          gtk_widget_destroy(gTreeHeaderSortArrowWidget);
1493  
1494 -    gProtoWindow = NULL;
1495      gProtoLayout = NULL;
1496 -    gButtonWidget = NULL;
1497 -    gToggleButtonWidget = NULL;
1498 -    gButtonArrowWidget = NULL;
1499 -    gSpinWidget = NULL;
1500      gHScaleWidget = NULL;
1501      gVScaleWidget = NULL;
1502 -    gEntryWidget = NULL;
1503      gComboBoxWidget = NULL;
1504      gComboBoxButtonWidget = NULL;
1505      gComboBoxSeparatorWidget = NULL;
1506 @@ -3360,29 +3062,15 @@ moz_gtk_shutdown()
1507      gComboBoxEntryButtonWidget = NULL;
1508      gComboBoxEntryArrowWidget = NULL;
1509      gComboBoxEntryTextareaWidget = NULL;
1510 -    gHandleBoxWidget = NULL;
1511 -    gToolbarWidget = NULL;
1512 -    gFrameWidget = NULL;
1513 -    gProgressWidget = NULL;
1514      gTabWidget = NULL;
1515 -    gTextViewWidget = nullptr;
1516 -    gTooltipWidget = NULL;
1517 -    gMenuBarWidget = NULL;
1518 -    gMenuBarItemWidget = NULL;
1519 -    gMenuPopupWidget = NULL;
1520 -    gMenuItemWidget = NULL;
1521      gImageMenuItemWidget = NULL;
1522      gCheckMenuItemWidget = NULL;
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 {
1540    MOZ_GTK_TAB_SELECTED        = 1 << 10
1541  } GtkTabFlags;
1542  
1543 -/** flags for menuitems **/
1544 -typedef enum {
1545 -  /* menuitem is part of the menubar */
1546 -  MOZ_TOPLEVEL_MENU_ITEM      = 1 << 0
1547 -} GtkMenuItemFlags;
1548 -
1549  /* function type for moz_gtk_enable_style_props */
1550  typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint);
1551  
1552 @@ -93,6 +87,10 @@ typedef enum {
1553    MOZ_GTK_BUTTON,
1554    /* Paints a button with image and no text */
1555    MOZ_GTK_TOOLBAR_BUTTON,
1556 +  /* Paints a toggle button */
1557 +  MOZ_GTK_TOGGLE_BUTTON,
1558 +  /* Paints a button arrow */
1559 +  MOZ_GTK_BUTTON_ARROW,
1560  
1561    /* Paints the container part of a GtkCheckButton. */
1562    MOZ_GTK_CHECKBUTTON_CONTAINER,
1563 @@ -115,6 +113,7 @@ typedef enum {
1564  
1565    /* Horizontal GtkScrollbar counterparts */
1566    MOZ_GTK_SCROLLBAR_HORIZONTAL,
1567 +  MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL,
1568    /* Paints the trough (track) of a GtkScrollbar. */
1569    MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL,
1570    /* Paints the slider (thumb) of a GtkScrollbar. */
1571 @@ -122,6 +121,7 @@ typedef enum {
1572  
1573    /* Vertical GtkScrollbar counterparts */
1574    MOZ_GTK_SCROLLBAR_VERTICAL,
1575 +  MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
1576    MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
1577    MOZ_GTK_SCROLLBAR_THUMB_VERTICAL,
1578  
1579 @@ -140,6 +140,10 @@ typedef enum {
1580    MOZ_GTK_GRIPPER,
1581    /* Paints a GtkEntry. */
1582    MOZ_GTK_ENTRY,
1583 +  /* Paints a GtkExpander. */
1584 +  MOZ_GTK_EXPANDER,
1585 +  /* Paints a GtkTextView. */
1586 +  MOZ_GTK_TEXT_VIEW,
1587    /* Paints a GtkOptionMenu. */
1588    MOZ_GTK_DROPDOWN,
1589    /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
1590 @@ -159,6 +163,8 @@ typedef enum {
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)
1639  STUB(gtk_color_chooser_set_rgba)
1640  STUB(gtk_color_chooser_get_rgba)
1641  STUB(gtk_color_chooser_set_use_alpha)
1642 +STUB(gtk_check_menu_item_new)
1643 +STUB(gtk_style_context_get_direction)
1644 +STUB(gtk_style_context_invalidate)
1645 +STUB(gtk_tooltip_get_type)
1646  #endif
1647  
1648  #ifdef GTK2_SYMBOLS
1649 diff -up firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-48.0/widget/gtk/nsLookAndFeel.cpp
1650 --- firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20   2016-06-01 06:11:44.000000000 +0200
1651 +++ firefox-48.0/widget/gtk/nsLookAndFeel.cpp   2016-07-29 09:15:54.943459700 +0200
1652 @@ -31,6 +31,7 @@
1653  
1654  #if MOZ_WIDGET_GTK != 2
1655  #include <cairo-gobject.h>
1656 +#include "WidgetStyleCache.h"
1657  #endif
1658  
1659  using mozilla::LookAndFeel;
1660 @@ -1135,15 +1136,24 @@ nsLookAndFeel::Init()
1661      gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1662      sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
1663      gtk_style_context_restore(style);
1664 +    g_object_unref(style);
1665  
1666      // tooltip foreground and background
1667 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
1668 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
1669 +    style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
1670      gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
1671      sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
1672 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1673 +    {
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);
1686  
1687      // menu foreground & menu background
1688      GtkWidget *accel_label = gtk_accel_label_new("M");
1689 diff -up firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp
1690 --- firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20        2016-07-25 22:22:07.000000000 +0200
1691 +++ firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp        2016-07-29 09:15:11.824285865 +0200
1692 @@ -354,10 +354,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
1693  
1694            if (isTopLevel) {
1695              aState->inHover = menuFrame->IsOpen();
1696 -            *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
1697            } else {
1698              aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
1699 -            *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
1700            }
1701  
1702            aState->active = FALSE;
1703 @@ -510,8 +508,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
1704      break;
1705    case NS_THEME_NUMBER_INPUT:
1706    case NS_THEME_TEXTFIELD:
1707 +    aGtkWidgetType = MOZ_GTK_ENTRY;
1708 +    break;
1709    case NS_THEME_TEXTFIELD_MULTILINE:
1710 +#if (MOZ_WIDGET_GTK == 3)
1711 +    aGtkWidgetType = MOZ_GTK_TEXT_VIEW;
1712 +#else
1713      aGtkWidgetType = MOZ_GTK_ENTRY;
1714 +#endif
1715      break;
1716    case NS_THEME_LISTBOX:
1717    case NS_THEME_TREEVIEW:
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;
1737  #endif
1738  static GtkStyleContext*
1739 -GetStyleInternal(WidgetNodeType aNodeType);
1740 +GetCssNodeStyleInternal(WidgetNodeType aNodeType);
1741  
1742  static GtkWidget*
1743  CreateWindowWidget()
1744 @@ -67,12 +67,175 @@ CreateCheckboxWidget()
1745  static GtkWidget*
1746  CreateRadiobuttonWidget()
1747  {
1748 -  GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "M");
1749 +  GtkWidget* widget = gtk_radio_button_new_with_label(nullptr, "M");
1750    AddToWindowContainer(widget);
1751    return widget;
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 -
2043 -    gtk_style_context_save(style);
2044 -    MOZ_ASSERT(!sStyleContextNeedsRestore);
2045 -    sStyleContextNeedsRestore = true;
2046 -
2047 -    gtk_style_context_add_class(style, aStyleClass);
2048 -  }
2049 -  else {
2050 -    style = sStyleStorage[aStyleType];
2051 -    if (!style) {
2052 -      style = CreateCSSNode(aStyleClass, GetStyleInternal(aParentNodeType));
2053 -      MOZ_ASSERT(!sStyleContextNeedsRestore);
2054 -      sStyleStorage[aStyleType] = style;
2055 -    }
2056 -  }
2057 +  return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
2058 +}
2059  
2060 +static GtkStyleContext*
2061 +GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
2062 +{
2063 +  GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType));
2064 +  gtk_style_context_save(style);
2065 +  MOZ_ASSERT(!sStyleContextNeedsRestore);
2066 +  sStyleContextNeedsRestore = true;
2067 +  gtk_style_context_add_class(style, aStyleClass);
2068    return style;
2069  }
2070  
2071 +/* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
2072  static GtkStyleContext*
2073 -GetStyleInternal(WidgetNodeType aNodeType)
2074 +GetCssNodeStyleInternal(WidgetNodeType aNodeType)
2075  {
2076 +  GtkStyleContext* style = sStyleStorage[aNodeType];
2077 +  if (style)
2078 +    return style;
2079 +
2080    switch (aNodeType) {
2081 -    case MOZ_GTK_SCROLLBAR_HORIZONTAL:
2082 -      /* Root CSS node / widget for scrollbars */
2083 +    case MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL:
2084 +      style = CreateChildCSSNode("contents",
2085 +                                 MOZ_GTK_SCROLLBAR_HORIZONTAL);
2086        break;
2087      case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
2088 -      return GetChildNodeStyle(aNodeType,
2089 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL,
2090 -                               GTK_STYLE_CLASS_TROUGH,
2091 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL);
2092 -
2093 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
2094 +                                 MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL);
2095 +      break;
2096      case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
2097 -      return GetChildNodeStyle(aNodeType,
2098 -                               MOZ_GTK_SCROLLBAR_HORIZONTAL,
2099 -                               GTK_STYLE_CLASS_SLIDER,
2100 -                               MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
2101 -
2102 -    case MOZ_GTK_SCROLLBAR_VERTICAL:
2103 -      /* Root CSS node / widget for scrollbars */
2104 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
2105 +                                 MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
2106 +      break;
2107 +    case MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL:
2108 +      style = CreateChildCSSNode("contents",
2109 +                                 MOZ_GTK_SCROLLBAR_VERTICAL);
2110        break;
2111      case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
2112 -      return GetChildNodeStyle(aNodeType,
2113 -                               MOZ_GTK_SCROLLBAR_VERTICAL,
2114 -                               GTK_STYLE_CLASS_TROUGH,
2115 -                               MOZ_GTK_SCROLLBAR_VERTICAL);
2116 -
2117 +      style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
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;
2282  #endif
2283 +  GtkStateFlags oldState = gtk_style_context_get_state(style);
2284 +  GtkTextDirection oldDirection = gtk_style_context_get_direction(style);
2285 +  if (oldState != aStateFlags || oldDirection != aDirection) {
2286 +    // From GTK 3.8, set_state() will overwrite the direction, so set
2287 +    // direction after state.
2288 +    gtk_style_context_set_state(style, aStateFlags);
2289 +    gtk_style_context_set_direction(style, aDirection);
2290 +
2291 +    // This invalidate is necessary for unsaved style contexts from GtkWidgets
2292 +    // in pre-3.18 GTK, because automatic invalidation of such contexts
2293 +    // was delayed until a resize event runs.
2294 +    //
2295 +    // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7
2296 +    //
2297 +    // Avoid calling invalidate on saved contexts to avoid performing
2298 +    // build_properties() (in 3.16 stylecontext.c) unnecessarily early.
2299 +    if (!sStyleContextNeedsRestore) {
2300 +      gtk_style_context_invalidate(style);
2301 +    }
2302 +  }
2303    return style;
2304  }
2305  
2306 diff -up firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20 firefox-48.0/widget/gtk/WidgetStyleCache.h
2307 --- firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20  2016-07-25 22:22:07.000000000 +0200
2308 +++ firefox-48.0/widget/gtk/WidgetStyleCache.h  2016-07-29 09:15:11.825285869 +0200
2309 @@ -21,10 +21,24 @@ enum : StyleFlags {
2310  GtkWidget*
2311  GetWidget(WidgetNodeType aNodeType);
2312  
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);
This page took 0.192466 seconds and 3 git commands to generate.