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
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;
49 static style_prop_t style_prop_func;
50 static gboolean have_arrow_scaling;
51 @@ -94,15 +73,6 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
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. */
59 -moz_gtk_set_widget_name(GtkWidget* widget)
61 - gtk_widget_set_name(widget, "MozillaGtkWidget");
65 moz_gtk_enable_style_props(style_prop_t styleGetProp)
67 @@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t
71 -ensure_window_widget()
73 - if (!gProtoWindow) {
74 - gProtoWindow = GetWidget(MOZ_GTK_WINDOW);
76 - return MOZ_GTK_SUCCESS;
80 setup_widget_prototype(GtkWidget* widget)
83 @@ -130,16 +91,6 @@ setup_widget_prototype(GtkWidget* widget
87 -ensure_button_widget()
89 - if (!gButtonWidget) {
90 - gButtonWidget = gtk_button_new_with_label("M");
91 - setup_widget_prototype(gButtonWidget);
93 - return MOZ_GTK_SUCCESS;
97 ensure_hpaned_widget()
100 @@ -160,40 +111,6 @@ ensure_vpaned_widget()
104 -ensure_toggle_button_widget()
106 - if (!gToggleButtonWidget) {
107 - gToggleButtonWidget = gtk_toggle_button_new();
108 - setup_widget_prototype(gToggleButtonWidget);
110 - return MOZ_GTK_SUCCESS;
114 -ensure_button_arrow_widget()
116 - if (!gButtonArrowWidget) {
117 - ensure_toggle_button_widget();
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);
124 - return MOZ_GTK_SUCCESS;
128 -ensure_spin_widget()
130 - if (!gSpinWidget) {
131 - gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
132 - setup_widget_prototype(gSpinWidget);
134 - return MOZ_GTK_SUCCESS;
138 ensure_scale_widget()
140 if (!gHScaleWidget) {
141 @@ -207,16 +124,6 @@ ensure_scale_widget()
142 return MOZ_GTK_SUCCESS;
146 -ensure_entry_widget()
148 - if (!gEntryWidget) {
149 - gEntryWidget = gtk_entry_new();
150 - setup_widget_prototype(gEntryWidget);
152 - return MOZ_GTK_SUCCESS;
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. */
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
171 - ensure_toggle_button_widget();
172 - gComboBoxButtonWidget = gToggleButtonWidget;
173 + gComboBoxButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
176 if (!gComboBoxArrowWidget) {
177 /* Shouldn't be reached with current internal gtk implementation;
178 * we gButtonArrowWidget as last resort fallback to avoid
180 - ensure_button_arrow_widget();
181 - gComboBoxArrowWidget = gButtonArrowWidget;
182 + gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
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;
194 - gInfoBar = gtk_info_bar_new();
195 - setup_widget_prototype(gInfoBar);
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. */
210 moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget,
211 @@ -385,8 +281,7 @@ ensure_combo_box_entry_widgets()
214 if (!gComboBoxEntryTextareaWidget) {
215 - ensure_entry_widget();
216 - gComboBoxEntryTextareaWidget = gEntryWidget;
217 + gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
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
225 - ensure_toggle_button_widget();
226 - gComboBoxEntryButtonWidget = gToggleButtonWidget;
227 + gComboBoxEntryButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
230 if (!gComboBoxEntryArrowWidget) {
231 /* Shouldn't be reached with current internal gtk implementation;
232 * we gButtonArrowWidget as last resort fallback to avoid
234 - ensure_button_arrow_widget();
235 - gComboBoxEntryArrowWidget = gButtonArrowWidget;
236 + gComboBoxEntryArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
239 return MOZ_GTK_SUCCESS;
244 -ensure_handlebox_widget()
246 - if (!gHandleBoxWidget) {
247 - gHandleBoxWidget = gtk_handle_box_new();
248 - setup_widget_prototype(gHandleBoxWidget);
250 - return MOZ_GTK_SUCCESS;
254 -ensure_toolbar_widget()
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);
262 - return MOZ_GTK_SUCCESS;
266 -ensure_toolbar_separator_widget()
268 - if (!gToolbarSeparatorWidget) {
269 - ensure_toolbar_widget();
270 - gToolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new());
271 - setup_widget_prototype(gToolbarSeparatorWidget);
273 - return MOZ_GTK_SUCCESS;
277 -ensure_tooltip_widget()
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);
286 - return MOZ_GTK_SUCCESS;
292 @@ -485,81 +331,11 @@ ensure_tab_widget()
296 -ensure_progress_widget()
298 - if (!gProgressWidget) {
299 - gProgressWidget = gtk_progress_bar_new();
300 - setup_widget_prototype(gProgressWidget);
302 - return MOZ_GTK_SUCCESS;
306 -ensure_frame_widget()
308 - if (!gFrameWidget) {
309 - gFrameWidget = gtk_frame_new(NULL);
310 - setup_widget_prototype(gFrameWidget);
312 - return MOZ_GTK_SUCCESS;
316 -ensure_menu_bar_widget()
318 - if (!gMenuBarWidget) {
319 - gMenuBarWidget = gtk_menu_bar_new();
320 - setup_widget_prototype(gMenuBarWidget);
322 - return MOZ_GTK_SUCCESS;
326 -ensure_menu_bar_item_widget()
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);
335 - return MOZ_GTK_SUCCESS;
339 -ensure_menu_popup_widget()
341 - if (!gMenuPopupWidget) {
342 - ensure_window_widget();
343 - gMenuPopupWidget = gtk_menu_new();
344 - gtk_menu_attach_to_widget(GTK_MENU(gMenuPopupWidget), gProtoWindow,
346 - gtk_widget_realize(gMenuPopupWidget);
348 - return MOZ_GTK_SUCCESS;
352 -ensure_menu_item_widget()
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),
359 - gtk_widget_realize(gMenuItemWidget);
361 - return MOZ_GTK_SUCCESS;
365 ensure_image_menu_item_widget()
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);
375 @@ -567,25 +343,11 @@ ensure_image_menu_item_widget()
379 -ensure_menu_separator_widget()
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);
388 - return MOZ_GTK_SUCCESS;
392 ensure_check_menu_item_widget()
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);
403 @@ -646,37 +408,6 @@ ensure_tree_header_cell_widget()
404 return MOZ_GTK_SUCCESS;
408 -ensure_expander_widget()
410 - if (!gExpanderWidget) {
411 - gExpanderWidget = gtk_expander_new("M");
412 - setup_widget_prototype(gExpanderWidget);
414 - return MOZ_GTK_SUCCESS;
418 -ensure_scrolled_window_widget()
420 - if (!gScrolledWindowWidget) {
421 - gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
422 - setup_widget_prototype(gScrolledWindowWidget);
424 - return MOZ_GTK_SUCCESS;
428 -ensure_text_view_widget()
430 - if (gTextViewWidget)
433 - gTextViewWidget = gtk_text_view_new();
434 - ensure_scrolled_window_widget();
435 - gtk_container_add(GTK_CONTAINER(gScrolledWindowWidget), gTextViewWidget);
441 @@ -729,26 +460,21 @@ moz_gtk_get_focus_outline_size(gint* foc
445 - GtkStyleContext *style;
447 - ensure_entry_widget();
448 - style = gtk_widget_get_style_context(gEntryWidget);
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;
460 moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
462 - ensure_menu_item_widget();
464 - gtk_style_context_get_style(gtk_widget_get_style_context(gMenuItemWidget),
465 - "horizontal-padding", horizontal_padding,
467 + gtk_widget_style_get(GetWidget(MOZ_GTK_MENUITEM),
468 + "horizontal-padding", horizontal_padding,
471 return MOZ_GTK_SUCCESS;
473 @@ -771,10 +497,11 @@ moz_gtk_button_get_default_overflow(gint
475 GtkBorder* default_outside_border;
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,
483 + ReleaseStyleContext(style);
485 if (default_outside_border) {
486 *border_top = default_outside_border->top;
487 @@ -794,10 +521,11 @@ moz_gtk_button_get_default_border(gint*
489 GtkBorder* default_border;
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,
497 + ReleaseStyleContext(style);
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)
505 - GtkStyleContext* style;
507 - ensure_window_widget();
508 - gtk_widget_set_direction(gProtoWindow, direction);
509 + GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
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);
517 + ReleaseStyleContext(style);
519 return MOZ_GTK_SUCCESS;
522 @@ -1118,6 +844,36 @@ moz_gtk_scrollbar_button_paint(cairo_t *
523 return MOZ_GTK_SUCCESS;
527 +moz_gtk_update_scrollbar_style(GtkStyleContext* style,
528 + WidgetNodeType widget,
529 + GtkTextDirection direction)
531 + if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
532 + gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM);
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);
538 + gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT);
539 + gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RIGHT);
545 +moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
546 + GdkRectangle* rect, bool drawFocus)
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);
551 + gtk_render_focus(style, cr,
552 + rect->x, rect->y, rect->width, rect->height);
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)
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);
572 - GtkStyleContext* style =
573 - ClaimStyleContext(widget == MOZ_GTK_SCROLLBAR_HORIZONTAL ?
574 - MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
575 - MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
577 - // TODO - integate with ClaimStyleContext()?
578 - gtk_style_context_set_direction(style, direction);
579 + bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL);
580 + GtkStyleContext* style;
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);
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,
598 + moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
599 + ReleaseStyleContext(style);
601 + style = ClaimStyleContext(isHorizontal ?
602 + MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
603 + MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
605 + moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
606 ReleaseStyleContext(style);
608 return MOZ_GTK_SUCCESS;
609 @@ -1160,12 +924,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode
610 GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
613 - GtkStyleContext* style = ClaimStyleContext(widget, direction);
615 - // TODO - integate those with ClaimStyleContext()?
616 - gtk_style_context_set_state(style, state_flags);
617 - gtk_style_context_set_direction(style, direction);
619 + GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
620 gtk_style_context_get_margin (style, state_flags, &margin);
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)
627 - GtkStyleContext* style;
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);
639 + ReleaseStyleContext(style);
640 return MOZ_GTK_SUCCESS;
643 @@ -1204,21 +956,14 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
644 gboolean isDown, GtkWidgetState* state,
645 GtkTextDirection direction)
647 - GdkRectangle arrow_rect;
648 - GtkStyleContext* style;
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));
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);
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,
672 - gtk_style_context_restore(style);
674 + ReleaseStyleContext(style);
675 return MOZ_GTK_SUCCESS;
678 @@ -1295,8 +1041,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G
679 gtk_widget_set_direction(widget, direction);
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
688 @@ -1321,20 +1067,12 @@ moz_gtk_gripper_paint(cairo_t *cr, GdkRe
689 GtkWidgetState* state,
690 GtkTextDirection direction)
692 - GtkStyleContext* style;
694 - ensure_handlebox_widget();
695 - gtk_widget_set_direction(gHandleBoxWidget, direction);
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));
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);
709 + ReleaseStyleContext(style);
710 return MOZ_GTK_SUCCESS;
713 @@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
714 return MOZ_GTK_SUCCESS;
718 +moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
719 + GtkWidgetState* state,
720 + GtkTextDirection direction)
722 + GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
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);
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);
733 + GtkStyleContext* style =
734 + ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
736 + gint xthickness = border.left + padding.left;
737 + gint ythickness = border.top + padding.top;
739 + gtk_render_background(style, cr,
740 + rect->x + xthickness, rect->y + ythickness,
741 + rect->width - 2 * xthickness,
742 + rect->height - 2 * ythickness);
744 + ReleaseStyleContext(style);
746 + return MOZ_GTK_SUCCESS;
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
755 ensure_tree_view_widget();
756 - ensure_scrolled_window_widget();
758 gtk_widget_set_direction(gTreeViewWidget, direction);
759 - gtk_widget_set_direction(gScrolledWindowWidget, direction);
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;
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;
781 @@ -1648,20 +1413,9 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
782 GtkWidgetState* state,
783 GtkArrowType arrow_type, GtkTextDirection direction)
785 - GtkStyleContext* style;
786 - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
787 GdkRectangle arrow_rect;
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);
796 - calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
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;
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;
813 + calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
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;
824 @@ -1776,19 +1537,10 @@ static gint
825 moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
826 GtkTextDirection direction)
828 - GtkStyleContext* style;
830 - ensure_toolbar_widget();
831 - gtk_widget_set_direction(gToolbarWidget, direction);
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);
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);
842 + ReleaseStyleContext(style);
843 return MOZ_GTK_SUCCESS;
846 @@ -1798,7 +1550,6 @@ static gint
847 moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
848 GtkTextDirection direction)
850 - GtkStyleContext* style;
851 gint separator_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;
858 - ensure_toolbar_separator_widget();
859 - gtk_widget_set_direction(gToolbarSeparatorWidget, direction);
861 - style = gtk_widget_get_style_context(gToolbarSeparatorWidget);
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,
869 + ReleaseStyleContext(style);
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);
880 + ReleaseStyleContext(style);
881 return MOZ_GTK_SUCCESS;
884 @@ -1848,14 +1597,10 @@ static gint
885 moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
886 GtkTextDirection direction)
888 - GtkStyleContext* style;
890 - ensure_tooltip_widget();
891 - gtk_widget_set_direction(gTooltipWidget, direction);
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;
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);
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
915 gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
916 - gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
918 // Workaround unico not respecting the text direction for resizers.
920 @@ -1891,7 +1633,7 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
922 gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
924 - gtk_style_context_restore(style);
925 + ReleaseStyleContext(style);
927 return MOZ_GTK_SUCCESS;
929 @@ -1900,16 +1642,9 @@ static gint
930 moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
931 GtkTextDirection direction)
933 - GtkStyleContext* style;
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);
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;
948 @@ -1917,18 +1652,11 @@ static gint
949 moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
950 GtkTextDirection direction)
952 - GtkStyleContext* style;
954 - ensure_progress_widget();
955 - gtk_widget_set_direction(gProgressWidget, direction);
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);
961 + GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH,
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);
968 return MOZ_GTK_SUCCESS;
970 @@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
972 GtkStyleContext* style;
974 - ensure_progress_widget();
975 - gtk_widget_set_direction(gProgressWidget, direction);
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);
988 + style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
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
995 gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
997 - gtk_style_context_restore(style);
998 + ReleaseStyleContext(style);
1000 return MOZ_GTK_SUCCESS;
1002 @@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR
1004 GtkStyleContext* style;
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);
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
1018 GtkStyleContext* style;
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);
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);
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);
1034 @@ -2373,12 +2103,10 @@ moz_gtk_menu_separator_paint(cairo_t *cr
1038 - ensure_menu_separator_widget();
1039 - gtk_widget_set_direction(gMenuSeparatorWidget, direction);
1041 - border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
1043 - style = gtk_widget_get_style_context(gMenuSeparatorWidget);
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);
1050 x = rect->x + border_width;
1051 @@ -2408,42 +2136,36 @@ moz_gtk_menu_separator_paint(cairo_t *cr
1054 gtk_style_context_restore(style);
1055 + ReleaseStyleContext(style);
1057 return MOZ_GTK_SUCCESS;
1060 // See gtk_menu_item_draw() for reference.
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)
1068 - GtkStyleContext* style;
1069 - GtkWidget* item_widget;
1070 - guint border_width;
1073 if (state->inHover && !state->disabled) {
1074 - if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
1075 - ensure_menu_bar_item_widget();
1076 - item_widget = gMenuBarItemWidget;
1078 - ensure_menu_item_widget();
1079 - item_widget = gMenuItemWidget;
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);
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;
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
1096 + gtk_style_context_save(style);
1097 + if (widget == MOZ_GTK_MENUBARITEM) {
1098 + gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
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));
1106 - border_width = gtk_container_get_border_width(GTK_CONTAINER(item_widget));
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
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);
1118 + gtk_style_context_restore(style);
1120 + ReleaseStyleContext(style);
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)
1128 - GtkStyleContext* style;
1129 GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
1131 - ensure_menu_item_widget();
1132 - gtk_widget_set_direction(gMenuItemWidget, direction);
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);
1145 + ReleaseStyleContext(style);
1146 return MOZ_GTK_SUCCESS;
1149 @@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
1150 gint indicator_size, horizontal_padding;
1153 - moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction);
1154 + moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
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)
1162 - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
1163 - GtkStyleContext *style;
1164 - ensure_info_bar();
1166 - style = gtk_widget_get_style_context(gInfoBar);
1167 - gtk_style_context_save(style);
1169 - gtk_style_context_set_state(style, state_flags);
1170 - gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
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,
1177 gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
1179 - gtk_style_context_restore(style);
1180 + ReleaseStyleContext(style);
1182 return MOZ_GTK_SUCCESS;
1184 @@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType
1185 case MOZ_GTK_BUTTON:
1186 case MOZ_GTK_TOOLBAR_BUTTON:
1188 - ensure_button_widget();
1189 - style = gtk_widget_get_style_context(gButtonWidget);
1190 + style = ClaimStyleContext(MOZ_GTK_BUTTON);
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)));
1196 if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
1197 gtk_style_context_save(style);
1198 gtk_style_context_add_class(style, "image-button");
1202 moz_gtk_add_style_padding(style, left, top, right, bottom);
1205 if (widget == MOZ_GTK_TOOLBAR_BUTTON)
1206 gtk_style_context_restore(style);
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);
1213 + ReleaseStyleContext(style);
1214 return MOZ_GTK_SUCCESS;
1218 - ensure_entry_widget();
1219 - style = gtk_widget_get_style_context(gEntryWidget);
1220 + style = ClaimStyleContext(MOZ_GTK_ENTRY);
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);
1228 + ReleaseStyleContext(style);
1229 return MOZ_GTK_SUCCESS;
1231 + case MOZ_GTK_TEXT_VIEW:
1232 case MOZ_GTK_TREEVIEW:
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;
1244 case MOZ_GTK_TREE_HEADER_CELL:
1245 @@ -2726,14 +2436,12 @@ moz_gtk_get_widget_border(WidgetNodeType
1248 case MOZ_GTK_PROGRESSBAR:
1249 - ensure_progress_widget();
1250 - w = gProgressWidget;
1251 + w = GetWidget(MOZ_GTK_PROGRESSBAR);
1253 case MOZ_GTK_SPINBUTTON_ENTRY:
1254 case MOZ_GTK_SPINBUTTON_UP:
1255 case MOZ_GTK_SPINBUTTON_DOWN:
1256 - ensure_spin_widget();
1258 + w = GetWidget(MOZ_GTK_SPINBUTTON);
1260 case MOZ_GTK_SCALE_HORIZONTAL:
1261 ensure_scale_widget();
1262 @@ -2744,8 +2452,7 @@ moz_gtk_get_widget_border(WidgetNodeType
1266 - ensure_frame_widget();
1268 + w = GetWidget(MOZ_GTK_FRAME);
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;
1275 case MOZ_GTK_MENUPOPUP:
1276 - ensure_menu_popup_widget();
1277 - w = gMenuPopupWidget;
1278 + w = GetWidget(MOZ_GTK_MENUPOPUP);
1280 + case MOZ_GTK_MENUBARITEM:
1281 case MOZ_GTK_MENUITEM:
1282 case MOZ_GTK_CHECKMENUITEM:
1283 case MOZ_GTK_RADIOMENUITEM:
1285 - if (widget == MOZ_GTK_MENUITEM) {
1286 - ensure_menu_item_widget();
1287 - ensure_menu_bar_item_widget();
1288 - w = gMenuItemWidget;
1291 + if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) {
1292 + // Bug 1274143 for MOZ_GTK_MENUBARITEM
1293 + w = GetWidget(MOZ_GTK_MENUITEM);
1295 ensure_check_menu_item_widget();
1296 w = gCheckMenuItemWidget;
1298 @@ -2784,9 +2489,16 @@ moz_gtk_get_widget_border(WidgetNodeType
1299 return MOZ_GTK_SUCCESS;
1301 case MOZ_GTK_INFO_BAR:
1302 - ensure_info_bar();
1304 + w = GetWidget(MOZ_GTK_INFO_BAR);
1306 + case MOZ_GTK_TOOLTIP:
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;
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;
1329 - ensure_button_arrow_widget();
1330 - widget = gButtonArrowWidget;
1331 + widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
1335 @@ -2924,11 +2634,9 @@ moz_gtk_get_toolbar_separator_width(gint
1337 gboolean wide_separators;
1338 gint separator_width;
1339 - GtkStyleContext* style;
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,
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;
1357 moz_gtk_get_expander_size(gint* size)
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,
1366 + ReleaseStyleContext(style);
1367 return MOZ_GTK_SUCCESS;
1370 @@ -2972,11 +2681,11 @@ moz_gtk_get_menu_separator_height(gint *
1371 GtkStyleContext* style;
1374 - ensure_menu_separator_widget();
1376 - border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
1378 + gtk_container_get_border_width(GTK_CONTAINER(
1379 + GetWidget(MOZ_GTK_MENUSEPARATOR)));
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);
1385 gtk_style_context_save(style);
1386 @@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint *
1389 gtk_style_context_restore(style);
1390 + ReleaseStyleContext(style);
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 *
1396 moz_gtk_get_entry_min_height(gint* height)
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);
1407 *height += (border.top + border.bottom + padding.top + padding.bottom);
1408 + ReleaseStyleContext(style);
1412 @@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons()
1414 GtkSettings* settings;
1416 - ensure_button_widget();
1417 - settings = gtk_widget_get_settings(gButtonWidget);
1418 + settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
1420 g_object_get(settings, "gtk-button-images", &result, NULL);
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),
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),
1440 case MOZ_GTK_CHECKBUTTON:
1441 @@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
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);
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);
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),
1463 + case MOZ_GTK_TEXT_VIEW:
1464 + return moz_gtk_text_view_paint(cr, rect, state, direction);
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,
1472 + case MOZ_GTK_MENUBARITEM:
1473 case MOZ_GTK_MENUITEM:
1474 - return moz_gtk_menu_item_paint(cr, rect, state, flags,
1476 + return moz_gtk_menu_item_paint(widget, cr, rect, state, direction);
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
1484 - if (gTooltipWidget)
1485 - gtk_widget_destroy(gTooltipWidget);
1486 /* This will destroy all of our widgets */
1490 /* TODO - replace it with appropriate widget */
1491 if (gTreeHeaderSortArrowWidget)
1492 gtk_widget_destroy(gTreeHeaderSortArrowWidget);
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;
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;
1534 is_initialized = FALSE;
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
1543 -/** flags for menuitems **/
1545 - /* menuitem is part of the menubar */
1546 - MOZ_TOPLEVEL_MENU_ITEM = 1 << 0
1547 -} GtkMenuItemFlags;
1549 /* function type for moz_gtk_enable_style_props */
1550 typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint);
1552 @@ -93,6 +87,10 @@ typedef enum {
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,
1561 /* Paints the container part of a GtkCheckButton. */
1562 MOZ_GTK_CHECKBUTTON_CONTAINER,
1563 @@ -115,6 +113,7 @@ typedef enum {
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 {
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,
1579 @@ -140,6 +140,10 @@ typedef enum {
1581 /* Paints a GtkEntry. */
1583 + /* Paints a GtkExpander. */
1585 + /* Paints a GtkTextView. */
1586 + MOZ_GTK_TEXT_VIEW,
1587 /* Paints a GtkOptionMenu. */
1589 /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
1590 @@ -159,6 +163,8 @@ typedef enum {
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 {
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. */
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. */
1614 + /* Used for scrolled window shell. */
1615 + MOZ_GTK_SCROLLED_WINDOW,
1617 MOZ_GTK_WIDGET_NODE_COUNT
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)
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)
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
1654 #if MOZ_WIDGET_GTK != 2
1655 #include <cairo-gobject.h>
1656 +#include "WidgetStyleCache.h"
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);
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);
1674 + GtkStyleContext* boxStyle =
1675 + CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
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);
1683 sInfoText = GDK_RGBA_TO_NS_RGBA(color);
1684 - g_object_unref(style);
1685 + ReleaseStyleContext(style);
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
1695 aState->inHover = menuFrame->IsOpen();
1696 - *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
1698 aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
1699 - *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
1702 aState->active = FALSE;
1703 @@ -510,8 +508,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
1705 case NS_THEME_NUMBER_INPUT:
1706 case NS_THEME_TEXTFIELD:
1707 + aGtkWidgetType = MOZ_GTK_ENTRY;
1709 case NS_THEME_TEXTFIELD_MULTILINE:
1710 +#if (MOZ_WIDGET_GTK == 3)
1711 + aGtkWidgetType = MOZ_GTK_TEXT_VIEW;
1713 aGtkWidgetType = MOZ_GTK_ENTRY;
1716 case NS_THEME_LISTBOX:
1717 case NS_THEME_TREEVIEW:
1718 @@ -673,6 +677,13 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
1719 aGtkWidgetType = MOZ_GTK_MENUPOPUP;
1721 case NS_THEME_MENUITEM:
1723 + nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
1724 + if (menuFrame && menuFrame->IsOnMenuBar()) {
1725 + aGtkWidgetType = MOZ_GTK_MENUBARITEM;
1729 aGtkWidgetType = MOZ_GTK_MENUITEM;
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;
1738 static GtkStyleContext*
1739 -GetStyleInternal(WidgetNodeType aNodeType);
1740 +GetCssNodeStyleInternal(WidgetNodeType aNodeType);
1743 CreateWindowWidget()
1744 @@ -67,12 +67,175 @@ CreateCheckboxWidget()
1746 CreateRadiobuttonWidget()
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);
1755 +CreateMenuBarWidget()
1757 + GtkWidget* widget = gtk_menu_bar_new();
1758 + AddToWindowContainer(widget);
1763 +CreateMenuPopupWidget()
1765 + GtkWidget* widget = gtk_menu_new();
1766 + gtk_menu_attach_to_widget(GTK_MENU(widget), GetWidget(MOZ_GTK_WINDOW),
1772 +CreateMenuItemWidget(WidgetNodeType aShellType)
1774 + GtkWidget* widget = gtk_menu_item_new();
1775 + gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(aShellType)), widget);
1780 +CreateProgressWidget()
1782 + GtkWidget* widget = gtk_progress_bar_new();
1783 + AddToWindowContainer(widget);
1788 +CreateTooltipWidget()
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);
1799 +CreateExpanderWidget()
1801 + GtkWidget* widget = gtk_expander_new("M");
1802 + AddToWindowContainer(widget);
1807 +CreateFrameWidget()
1809 + GtkWidget* widget = gtk_frame_new(nullptr);
1810 + AddToWindowContainer(widget);
1815 +CreateGripperWidget()
1817 + GtkWidget* widget = gtk_handle_box_new();
1818 + AddToWindowContainer(widget);
1823 +CreateToolbarWidget()
1825 + GtkWidget* widget = gtk_toolbar_new();
1826 + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget);
1827 + gtk_widget_realize(widget);
1832 +CreateToolbarSeparatorWidget()
1834 + GtkWidget* widget = GTK_WIDGET(gtk_separator_tool_item_new());
1835 + AddToWindowContainer(widget);
1840 +CreateInfoBarWidget()
1842 + GtkWidget* widget = gtk_info_bar_new();
1843 + AddToWindowContainer(widget);
1848 +CreateButtonWidget()
1850 + GtkWidget* widget = gtk_button_new_with_label("M");
1851 + AddToWindowContainer(widget);
1856 +CreateToggleButtonWidget()
1858 + GtkWidget* widget = gtk_toggle_button_new();
1859 + AddToWindowContainer(widget);
1864 +CreateButtonArrowWidget()
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);
1876 + GtkWidget* widget = gtk_spin_button_new(nullptr, 1, 0);
1877 + AddToWindowContainer(widget);
1882 +CreateEntryWidget()
1884 + GtkWidget* widget = gtk_entry_new();
1885 + AddToWindowContainer(widget);
1890 +CreateScrolledWindowWidget()
1892 + GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
1893 + AddToWindowContainer(widget);
1898 +CreateTextViewWidget()
1900 + GtkWidget* widget = gtk_text_view_new();
1901 + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
1907 +CreateMenuSeparatorWidget()
1909 + GtkWidget* widget = gtk_separator_menu_item_new();
1910 + gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
1912 + gtk_widget_realize(widget);
1918 CreateWidget(WidgetNodeType aWidgetType)
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();
1978 /* Not implemented */
1980 @@ -107,17 +308,42 @@ GetWidget(WidgetNodeType aWidgetType)
1984 -static GtkStyleContext*
1985 -CreateCSSNode(const char* aName, GtkStyleContext *aParentStyle)
1987 +CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle)
1989 + GtkWidgetPath* path = aParentStyle ?
1990 + gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
1991 + gtk_widget_path_new();
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);
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);
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);
2011 +CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType)
2013 static auto sGtkWidgetPathIterSetObjectName =
2014 reinterpret_cast<void (*)(GtkWidgetPath *, gint, const char *)>
2015 (dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name"));
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();
2023 - gtk_widget_path_append_type(path, G_TYPE_NONE);
2024 + gtk_widget_path_append_type(path, aType);
2026 (*sGtkWidgetPathIterSetObjectName)(path, -1, aName);
2028 @@ -130,95 +356,168 @@ CreateCSSNode(const char* aName, GtkStyl
2031 static GtkStyleContext*
2032 -GetChildNodeStyle(WidgetNodeType aStyleType,
2033 - WidgetNodeType aWidgetType,
2034 - const gchar* aStyleClass,
2035 - WidgetNodeType aParentNodeType)
2036 +CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType)
2038 - GtkStyleContext* style;
2040 - if (gtk_check_version(3, 20, 0) != nullptr) {
2041 - style = gtk_widget_get_style_context(sWidgetStorage[aWidgetType]);
2043 - gtk_style_context_save(style);
2044 - MOZ_ASSERT(!sStyleContextNeedsRestore);
2045 - sStyleContextNeedsRestore = true;
2047 - gtk_style_context_add_class(style, aStyleClass);
2050 - style = sStyleStorage[aStyleType];
2052 - style = CreateCSSNode(aStyleClass, GetStyleInternal(aParentNodeType));
2053 - MOZ_ASSERT(!sStyleContextNeedsRestore);
2054 - sStyleStorage[aStyleType] = style;
2057 + return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
2060 +static GtkStyleContext*
2061 +GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
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);
2071 +/* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
2072 static GtkStyleContext*
2073 -GetStyleInternal(WidgetNodeType aNodeType)
2074 +GetCssNodeStyleInternal(WidgetNodeType aNodeType)
2076 + GtkStyleContext* style = sStyleStorage[aNodeType];
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);
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);
2093 + style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
2094 + MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL);
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);
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);
2107 + case MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL:
2108 + style = CreateChildCSSNode("contents",
2109 + MOZ_GTK_SCROLLBAR_VERTICAL);
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);
2117 + style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
2118 + MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL);
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);
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);
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);
2141 case MOZ_GTK_CHECKBUTTON:
2142 - return GetChildNodeStyle(aNodeType,
2143 - MOZ_GTK_CHECKBUTTON_CONTAINER,
2144 - GTK_STYLE_CLASS_CHECK,
2145 - MOZ_GTK_CHECKBUTTON_CONTAINER);
2147 + style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
2148 + MOZ_GTK_CHECKBUTTON_CONTAINER);
2150 + case MOZ_GTK_PROGRESS_TROUGH:
2151 + /* Progress bar background (trough) */
2152 + style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
2153 + MOZ_GTK_PROGRESSBAR);
2155 + case MOZ_GTK_PROGRESS_CHUNK:
2156 + style = CreateChildCSSNode("progress",
2157 + MOZ_GTK_PROGRESS_TROUGH);
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);
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);
2185 + // TODO - create style from style path
2186 + GtkWidget* widget = GetWidget(aNodeType);
2187 + return gtk_widget_get_style_context(widget);
2190 - GtkWidget* widget = GetWidget(aNodeType);
2192 - return gtk_widget_get_style_context(widget);
2194 + MOZ_ASSERT(style, "missing style context for node type");
2195 + sStyleStorage[aNodeType] = style;
2199 - MOZ_ASSERT_UNREACHABLE("missing style context for node type");
2201 +/* GetWidgetStyleInternal is used by Gtk < 3.20 */
2202 +static GtkStyleContext*
2203 +GetWidgetStyleInternal(WidgetNodeType aNodeType)
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];
2232 + // The tooltip style class is added first in CreateTooltipWidget() so
2233 + // that gtk_widget_path_append_for_widget() in CreateStyleForWidget()
2235 + GtkWidget* tooltipWindow = CreateTooltipWidget();
2236 + style = CreateStyleForWidget(tooltipWindow, nullptr);
2237 + gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
2238 + sStyleStorage[aNodeType] = style;
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);
2257 + GtkWidget* widget = GetWidget(aNodeType);
2258 + MOZ_ASSERT(widget);
2259 + return gtk_widget_get_style_context(widget);
2264 @@ -245,13 +544,39 @@ ResetWidgetCache(void)
2267 ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
2268 - StyleFlags aFlags)
2269 + GtkStateFlags aStateFlags, StyleFlags aFlags)
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);
2277 + style = GetCssNodeStyleInternal(aNodeType);
2280 MOZ_ASSERT(!sCurrentStyleContext);
2281 sCurrentStyleContext = style;
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);
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.
2295 + // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7
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);
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 {
2311 GetWidget(WidgetNodeType aNodeType);
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.
2318 +CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle);
2320 +// CreateCSSNode is implemented for gtk >= 3.20 only.
2322 +CreateCSSNode(const char* aName,
2323 + GtkStyleContext* aParentStyle,
2324 + GType aType = G_TYPE_NONE);
2326 // Callers must call ReleaseStyleContext() on the returned context.
2328 ClaimStyleContext(WidgetNodeType aNodeType,
2329 GtkTextDirection aDirection = GTK_TEXT_DIR_LTR,
2330 + GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
2331 StyleFlags aFlags = NO_STYLE_FLAGS);
2333 ReleaseStyleContext(GtkStyleContext* style);