]> git.pld-linux.org Git - packages/firefox.git/blame - firefox-gtk3-20.patch
- rebuild with libvpx 1.6
[packages/firefox.git] / firefox-gtk3-20.patch
CommitLineData
a0850653
JR
1diff -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 @@
f0a96e4f
JR
5
6 #include <math.h>
7
a0850653 8-static GtkWidget* gProtoWindow;
f0a96e4f
JR
9 static GtkWidget* gProtoLayout;
10-static GtkWidget* gButtonWidget;
a0850653
JR
11-static GtkWidget* gToggleButtonWidget;
12-static GtkWidget* gButtonArrowWidget;
f0a96e4f 13-static GtkWidget* gSpinWidget;
f0a96e4f
JR
14 static GtkWidget* gHScaleWidget;
15 static GtkWidget* gVScaleWidget;
16-static GtkWidget* gEntryWidget;
f0a96e4f
JR
17 static GtkWidget* gComboBoxWidget;
18 static GtkWidget* gComboBoxButtonWidget;
19 static GtkWidget* gComboBoxArrowWidget;
a0850653
JR
20@@ -35,30 +29,15 @@ static GtkWidget* gComboBoxEntryWidget;
21 static GtkWidget* gComboBoxEntryTextareaWidget;
f0a96e4f
JR
22 static GtkWidget* gComboBoxEntryButtonWidget;
23 static GtkWidget* gComboBoxEntryArrowWidget;
a0850653
JR
24-static GtkWidget* gHandleBoxWidget;
25-static GtkWidget* gToolbarWidget;
26-static GtkWidget* gFrameWidget;
f0a96e4f 27-static GtkWidget* gProgressWidget;
f0a96e4f 28 static GtkWidget* gTabWidget;
a0850653 29-static GtkWidget* gTextViewWidget;
f0a96e4f 30-static GtkWidget* gTooltipWidget;
a0850653
JR
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
f0a96e4f
JR
52 return stateFlags;
53 }
54
a0850653
JR
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)
f0a96e4f 66 {
a0850653 67@@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t
f0a96e4f 68 }
a0850653 69
f0a96e4f 70 static gint
a0850653
JR
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)
f0a96e4f 81 {
a0850653
JR
82 if (!gProtoLayout) {
83@@ -130,16 +91,6 @@ setup_widget_prototype(GtkWidget* widget
f0a96e4f 84 }
a0850653 85
f0a96e4f 86 static gint
a0850653
JR
87-ensure_button_widget()
88-{
89- if (!gButtonWidget) {
90- gButtonWidget = gtk_button_new_with_label("M");
91- setup_widget_prototype(gButtonWidget);
f0a96e4f 92- }
a0850653
JR
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()
f0a96e4f
JR
101 }
102
103 static gint
a0850653
JR
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-{
f0a96e4f
JR
130- if (!gSpinWidget) {
131- gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
132- setup_widget_prototype(gSpinWidget);
133- }
134- return MOZ_GTK_SUCCESS;
a0850653
JR
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;
f0a96e4f
JR
143 }
144
a0850653
JR
145-static gint
146-ensure_entry_widget()
147-{
f0a96e4f
JR
148- if (!gEntryWidget) {
149- gEntryWidget = gtk_entry_new();
150- setup_widget_prototype(gEntryWidget);
a0850653
JR
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);
f0a96e4f 183 }
a0850653
JR
184
185 /* We don't test the validity of gComboBoxSeparatorWidget since there
186@@ -316,15 +221,6 @@ ensure_combo_box_widgets()
f0a96e4f
JR
187 return MOZ_GTK_SUCCESS;
188 }
a0850653
JR
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()
f0a96e4f
JR
212 NULL);
213
a0850653
JR
214 if (!gComboBoxEntryTextareaWidget) {
215- ensure_entry_widget();
f0a96e4f 216- gComboBoxEntryTextareaWidget = gEntryWidget;
a0850653 217+ gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
f0a96e4f
JR
218 }
219
220 if (gComboBoxEntryButtonWidget) {
a0850653
JR
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-{
f0a96e4f
JR
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);
a0850653
JR
285- }
286- return MOZ_GTK_SUCCESS;
287-}
288-
f0a96e4f 289 static gint
a0850653 290 ensure_tab_widget()
f0a96e4f 291 {
a0850653
JR
292@@ -485,81 +331,11 @@ ensure_tab_widget()
293 }
294
295 static gint
296-ensure_progress_widget()
297-{
f0a96e4f
JR
298- if (!gProgressWidget) {
299- gProgressWidget = gtk_progress_bar_new();
300- setup_widget_prototype(gProgressWidget);
a0850653
JR
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);
f0a96e4f 374 }
a0850653 375@@ -567,25 +343,11 @@ ensure_image_menu_item_widget()
f0a96e4f 376 }
a0850653
JR
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
f0a96e4f
JR
392 ensure_check_menu_item_widget()
393 {
394 if (!gCheckMenuItemWidget) {
a0850653
JR
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()
f0a96e4f 440 {
a0850653 441@@ -729,26 +460,21 @@ moz_gtk_get_focus_outline_size(gint* foc
f0a96e4f
JR
442 {
443 GtkBorder border;
444 GtkBorder padding;
445- GtkStyleContext *style;
a0850653
JR
446-
447- ensure_entry_widget();
f0a96e4f 448- style = gtk_widget_get_style_context(gEntryWidget);
a0850653
JR
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);
f0a96e4f
JR
453 *focus_h_width = border.left + padding.left;
454 *focus_v_width = border.top + padding.top;
a0850653 455+ ReleaseStyleContext(style);
f0a96e4f 456 return MOZ_GTK_SUCCESS;
a0850653 457 }
f0a96e4f 458
a0850653
JR
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);
f0a96e4f 470
a0850653
JR
471 return MOZ_GTK_SUCCESS;
472 }
473@@ -771,10 +497,11 @@ moz_gtk_button_get_default_overflow(gint
474 {
475 GtkBorder* default_outside_border;
f0a96e4f 476
a0850653
JR
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;
f0a96e4f 490
a0850653
JR
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;
f0a96e4f 506-
a0850653
JR
507- ensure_window_widget();
508- gtk_widget_set_direction(gProtoWindow, direction);
509+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
f0a96e4f 510
a0850653
JR
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);
f0a96e4f 516
a0850653 517+ ReleaseStyleContext(style);
f0a96e4f 518+
a0850653
JR
519 return MOZ_GTK_SUCCESS;
520 }
f0a96e4f 521
a0850653 522@@ -1118,6 +844,36 @@ moz_gtk_scrollbar_button_paint(cairo_t *
f0a96e4f
JR
523 return MOZ_GTK_SUCCESS;
524 }
a0850653
JR
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
f0a96e4f
JR
560 GtkTextDirection direction)
561 {
f0a96e4f 562 if (flags & MOZ_GTK_TRACK_OPAQUE) {
a0850653
JR
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);
f0a96e4f
JR
570 }
571
a0850653
JR
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;
f0a96e4f 581
a0850653
JR
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);
f0a96e4f 600 }
a0850653
JR
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);
f0a96e4f 607
a0850653
JR
608 return MOZ_GTK_SUCCESS;
609@@ -1160,12 +924,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode
f0a96e4f 610 GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
f0a96e4f
JR
611 GtkBorder margin;
612
a0850653 613- GtkStyleContext* style = ClaimStyleContext(widget, direction);
f0a96e4f 614-
a0850653
JR
615- // TODO - integate those with ClaimStyleContext()?
616- gtk_style_context_set_state(style, state_flags);
617- gtk_style_context_set_direction(style, direction);
f0a96e4f 618-
a0850653 619+ GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
f0a96e4f
JR
620 gtk_style_context_get_margin (style, state_flags, &margin);
621
622 gtk_render_slider(style, cr,
a0850653
JR
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);
f0a96e4f
JR
637- gtk_style_context_restore(style);
638-
a0850653 639+ ReleaseStyleContext(style);
f0a96e4f
JR
640 return MOZ_GTK_SUCCESS;
641 }
642
a0850653
JR
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();
f0a96e4f 651- style = gtk_widget_get_style_context(gSpinWidget);
a0850653 652- gtk_style_context_save(style);
f0a96e4f 653- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
a0850653 654- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
f0a96e4f 655- gtk_widget_set_direction(gSpinWidget, direction);
a0850653
JR
656+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction,
657+ GetStateFlagsFromGtkWidgetState(state));
f0a96e4f
JR
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);
a0850653
JR
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)
f0a96e4f 691 {
f0a96e4f 692- GtkStyleContext* style;
f0a96e4f 693-
a0850653
JR
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 }
f0a96e4f 712
a0850653
JR
713@@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
714 return MOZ_GTK_SUCCESS;
715 }
f0a96e4f 716
a0850653
JR
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;
f0a96e4f 754
a0850653
JR
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);
f0a96e4f
JR
770 xthickness = border.left;
771 ythickness = border.top;
a0850653
JR
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)
f0a96e4f 784 {
f0a96e4f 785- GtkStyleContext* style;
a0850653
JR
786- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
787 GdkRectangle arrow_rect;
788 gdouble arrow_angle;
f0a96e4f 789
a0850653
JR
790- ensure_button_arrow_widget();
791- style = gtk_widget_get_style_context(gButtonArrowWidget);
f0a96e4f
JR
792- gtk_style_context_save(style);
793- gtk_style_context_set_state(style, state_flags);
a0850653
JR
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;
f0a96e4f 805 }
a0850653
JR
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);
f0a96e4f 809- gtk_style_context_restore(style);
a0850653
JR
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);
f0a96e4f
JR
821 return MOZ_GTK_SUCCESS;
822 }
f0a96e4f 823
a0850653
JR
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);
f0a96e4f 834- gtk_style_context_save(style);
a0850653
JR
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);
f0a96e4f 840- gtk_style_context_restore(style);
a0850653
JR
841-
842+ ReleaseStyleContext(style);
843 return MOZ_GTK_SUCCESS;
844 }
f0a96e4f 845
a0850653
JR
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);
f0a96e4f
JR
881 return MOZ_GTK_SUCCESS;
882 }
f0a96e4f 883
a0850653
JR
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();
f0a96e4f 891- gtk_widget_set_direction(gTooltipWidget, direction);
a0850653 892-
f0a96e4f 893- style = gtk_widget_get_style_context(gTooltipWidget);
a0850653 894+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction);
f0a96e4f
JR
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);
a0850653
JR
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
f0a96e4f 927 return MOZ_GTK_SUCCESS;
a0850653
JR
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
f0a96e4f
JR
949 moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
950 GtkTextDirection direction)
951 {
952- GtkStyleContext* style;
953-
a0850653 954- ensure_progress_widget();
f0a96e4f 955- gtk_widget_set_direction(gProgressWidget, direction);
a0850653 956-
f0a96e4f
JR
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-
a0850653
JR
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);
f0a96e4f 965- gtk_style_context_restore(style);
a0850653 966+ ReleaseStyleContext(style);
f0a96e4f
JR
967
968 return MOZ_GTK_SUCCESS;
969 }
a0850653 970@@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
f0a96e4f 971 {
a0850653
JR
972 GtkStyleContext* style;
973
974- ensure_progress_widget();
f0a96e4f
JR
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);
a0850653
JR
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+ }
f0a96e4f
JR
990
991 if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
992 widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
a0850653 993@@ -1990,7 +1720,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
f0a96e4f 994 } else {
a0850653 995 gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
f0a96e4f
JR
996 }
997- gtk_style_context_restore(style);
a0850653 998+ ReleaseStyleContext(style);
f0a96e4f
JR
999
1000 return MOZ_GTK_SUCCESS;
1001 }
a0850653
JR
1002@@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR
1003 {
1004 GtkStyleContext* style;
f0a96e4f 1005
a0850653
JR
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);
f0a96e4f 1010
a0850653
JR
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;
f0a96e4f 1019
a0850653
JR
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);
f0a96e4f 1024
a0850653
JR
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);
f0a96e4f 1028
a0850653
JR
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;
f0a96e4f 1037
a0850653
JR
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);
f0a96e4f
JR
1049
1050 x = rect->x + border_width;
a0850653
JR
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);
f0a96e4f 1082- gtk_style_context_save(style);
a0850653
JR
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 }
f0a96e4f 1101
a0850653
JR
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
f0a96e4f
JR
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);
a0850653
JR
1116+
1117+ if (pre_3_6) {
1118+ gtk_style_context_restore(style);
1119+ }
1120+ ReleaseStyleContext(style);
f0a96e4f
JR
1121 }
1122
1123 return MOZ_GTK_SUCCESS;
a0850653
JR
1124@@ -2462,21 +2188,13 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
1125 GtkWidgetState* state,
1126 GtkTextDirection direction)
f0a96e4f 1127 {
a0850653
JR
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 }
f0a96e4f 1148
a0850653
JR
1149@@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
1150 gint indicator_size, horizontal_padding;
1151 gint x, y;
f0a96e4f 1152
a0850653
JR
1153- moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction);
1154+ moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
f0a96e4f 1155
a0850653
JR
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)
f0a96e4f 1161 {
a0850653
JR
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);
f0a96e4f 1181
a0850653 1182 return MOZ_GTK_SUCCESS;
f0a96e4f 1183 }
a0850653
JR
1184@@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType
1185 case MOZ_GTK_BUTTON:
f0a96e4f
JR
1186 case MOZ_GTK_TOOLBAR_BUTTON:
1187 {
a0850653 1188- ensure_button_widget();
f0a96e4f 1189- style = gtk_widget_get_style_context(gButtonWidget);
a0850653
JR
1190+ style = ClaimStyleContext(MOZ_GTK_BUTTON);
1191
f0a96e4f 1192- *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
a0850653
JR
1193+ *left = *top = *right = *bottom =
1194+ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
f0a96e4f 1195
a0850653
JR
1196 if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
1197 gtk_style_context_save(style);
1198 gtk_style_context_add_class(style, "image-button");
1199 }
f0a96e4f 1200-
a0850653
JR
1201+
1202 moz_gtk_add_style_padding(style, left, top, right, bottom);
f0a96e4f 1203-
a0850653
JR
1204+
1205 if (widget == MOZ_GTK_TOOLBAR_BUTTON)
1206 gtk_style_context_restore(style);
f0a96e4f 1207
a0850653 1208@@ -2624,12 +2334,13 @@ moz_gtk_get_widget_border(WidgetNodeType
f0a96e4f
JR
1209 // -moz-focus-inner border (Bug 1228281).
1210 *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
a0850653 1211 moz_gtk_add_style_border(style, left, top, right, bottom);
f0a96e4f 1212+
a0850653 1213+ ReleaseStyleContext(style);
f0a96e4f
JR
1214 return MOZ_GTK_SUCCESS;
1215 }
1216 case MOZ_GTK_ENTRY:
1217 {
a0850653 1218- ensure_entry_widget();
f0a96e4f 1219- style = gtk_widget_get_style_context(gEntryWidget);
a0850653 1220+ style = ClaimStyleContext(MOZ_GTK_ENTRY);
f0a96e4f
JR
1221
1222 // XXX: Subtract 1 pixel from the padding to account for the default
1223 // padding in forms.css. See bug 1187385.
a0850653
JR
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);
f0a96e4f 1227
a0850653 1228+ ReleaseStyleContext(style);
f0a96e4f
JR
1229 return MOZ_GTK_SUCCESS;
1230 }
a0850653 1231+ case MOZ_GTK_TEXT_VIEW:
f0a96e4f 1232 case MOZ_GTK_TREEVIEW:
a0850653
JR
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
f0a96e4f
JR
1246 w = gTabWidget;
1247 break;
1248 case MOZ_GTK_PROGRESSBAR:
1249- ensure_progress_widget();
1250- w = gProgressWidget;
a0850653
JR
1251+ w = GetWidget(MOZ_GTK_PROGRESSBAR);
1252 break;
f0a96e4f
JR
1253 case MOZ_GTK_SPINBUTTON_ENTRY:
1254 case MOZ_GTK_SPINBUTTON_UP:
1255 case MOZ_GTK_SPINBUTTON_DOWN:
a0850653 1256- ensure_spin_widget();
f0a96e4f 1257- w = gSpinWidget;
a0850653 1258+ w = GetWidget(MOZ_GTK_SPINBUTTON);
f0a96e4f
JR
1259 break;
1260 case MOZ_GTK_SCALE_HORIZONTAL:
1261 ensure_scale_widget();
a0850653
JR
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:
f0a96e4f 1284 {
a0850653
JR
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;
f0a96e4f 1297 }
a0850653
JR
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
f0a96e4f
JR
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:
a0850653
JR
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 }
f0a96e4f 1334
a0850653 1335@@ -2924,11 +2634,9 @@ moz_gtk_get_toolbar_separator_width(gint
f0a96e4f 1336 {
a0850653
JR
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
f0a96e4f 1349 /* Just in case... */
a0850653 1350 gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
f0a96e4f 1351 *size = MAX(*size, (wide_separators ? separator_width : border.left));
a0850653
JR
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);
f0a96e4f
JR
1367 return MOZ_GTK_SUCCESS;
1368 }
f0a96e4f 1369
a0850653
JR
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);
f0a96e4f
JR
1384
1385 gtk_style_context_save(style);
a0850653
JR
1386@@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint *
1387 NULL);
f0a96e4f 1388
a0850653
JR
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);
f0a96e4f 1409 }
a0850653
JR
1410
1411 void
1412@@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons()
1413 gboolean result;
f0a96e4f
JR
1414 GtkSettings* settings;
1415
a0850653 1416- ensure_button_widget();
f0a96e4f 1417- settings = gtk_widget_get_settings(gButtonWidget);
a0850653 1418+ settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
f0a96e4f
JR
1419
1420 g_object_get(settings, "gtk-button-images", &result, NULL);
1421 return result;
a0850653
JR
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);
f0a96e4f 1432 }
a0850653 1433- ensure_button_widget();
f0a96e4f
JR
1434 return moz_gtk_button_paint(cr, rect, state,
1435- (GtkReliefStyle) flags, gButtonWidget,
a0850653
JR
1436+ (GtkReliefStyle) flags,
1437+ GetWidget(MOZ_GTK_BUTTON),
f0a96e4f
JR
1438 direction);
1439 break;
1440 case MOZ_GTK_CHECKBUTTON:
a0850653
JR
1441@@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
1442 state, direction);
1443 break;
f0a96e4f 1444 case MOZ_GTK_SPINBUTTON_ENTRY:
a0850653
JR
1445- ensure_spin_widget();
1446+ // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly
f0a96e4f
JR
1447 return moz_gtk_entry_paint(cr, rect, state,
1448- gSpinWidget, direction);
a0850653 1449+ GetWidget(MOZ_GTK_SPINBUTTON), direction);
f0a96e4f
JR
1450 break;
1451 case MOZ_GTK_GRIPPER:
1452 return moz_gtk_gripper_paint(cr, rect, state,
a0850653
JR
1453@@ -3198,9 +2907,11 @@ moz_gtk_widget_paint(WidgetNodeType widg
1454 (GtkExpanderStyle) flags, direction);
1455 break;
f0a96e4f 1456 case MOZ_GTK_ENTRY:
a0850653
JR
1457- ensure_entry_widget();
1458- return moz_gtk_entry_paint(cr, rect, state,
f0a96e4f 1459- gEntryWidget, direction);
a0850653
JR
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);
f0a96e4f
JR
1465 break;
1466 case MOZ_GTK_DROPDOWN:
1467 return moz_gtk_combo_box_paint(cr, rect, state, direction);
a0850653
JR
1468@@ -3271,9 +2982,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
1469 return moz_gtk_menu_separator_paint(cr, rect,
1470 direction);
f0a96e4f 1471 break;
a0850653
JR
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);
f0a96e4f 1477 break;
a0850653
JR
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
f0a96e4f
JR
1481 gint
1482 moz_gtk_shutdown()
1483 {
1484- if (gTooltipWidget)
1485- gtk_widget_destroy(gTooltipWidget);
f0a96e4f 1486 /* This will destroy all of our widgets */
a0850653
JR
1487-
1488 ResetWidgetCache();
f0a96e4f 1489
a0850653
JR
1490 /* TODO - replace it with appropriate widget */
1491 if (gTreeHeaderSortArrowWidget)
1492 gtk_widget_destroy(gTreeHeaderSortArrowWidget);
1493
1494- gProtoWindow = NULL;
f0a96e4f
JR
1495 gProtoLayout = NULL;
1496- gButtonWidget = NULL;
a0850653
JR
1497- gToggleButtonWidget = NULL;
1498- gButtonArrowWidget = NULL;
f0a96e4f 1499- gSpinWidget = NULL;
f0a96e4f
JR
1500 gHScaleWidget = NULL;
1501 gVScaleWidget = NULL;
1502- gEntryWidget = NULL;
f0a96e4f
JR
1503 gComboBoxWidget = NULL;
1504 gComboBoxButtonWidget = NULL;
1505 gComboBoxSeparatorWidget = NULL;
a0850653 1506@@ -3360,29 +3062,15 @@ moz_gtk_shutdown()
f0a96e4f
JR
1507 gComboBoxEntryButtonWidget = NULL;
1508 gComboBoxEntryArrowWidget = NULL;
a0850653
JR
1509 gComboBoxEntryTextareaWidget = NULL;
1510- gHandleBoxWidget = NULL;
1511- gToolbarWidget = NULL;
1512- gFrameWidget = NULL;
f0a96e4f 1513- gProgressWidget = NULL;
f0a96e4f 1514 gTabWidget = NULL;
a0850653 1515- gTextViewWidget = nullptr;
f0a96e4f 1516- gTooltipWidget = NULL;
a0850653
JR
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
1536diff -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 {
f0a96e4f
JR
1540 MOZ_GTK_TAB_SELECTED = 1 << 10
1541 } GtkTabFlags;
1542
a0850653
JR
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;
1619diff -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)
3de22d0e 1626+STUB(gtk_box_new)
a0850653
JR
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)
f0a96e4f
JR
1639 STUB(gtk_color_chooser_set_rgba)
1640 STUB(gtk_color_chooser_get_rgba)
1641 STUB(gtk_color_chooser_set_use_alpha)
a0850653
JR
1642+STUB(gtk_check_menu_item_new)
1643+STUB(gtk_style_context_get_direction)
1644+STUB(gtk_style_context_invalidate)
f0a96e4f
JR
1645+STUB(gtk_tooltip_get_type)
1646 #endif
1647
1648 #ifdef GTK2_SYMBOLS
a0850653
JR
1649diff -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"
3de22d0e
JR
1657 #endif
1658
a0850653
JR
1659 using mozilla::LookAndFeel;
1660@@ -1135,15 +1136,24 @@ nsLookAndFeel::Init()
1661 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
f0a96e4f 1662 sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
a0850653 1663 gtk_style_context_restore(style);
f0a96e4f
JR
1664+ g_object_unref(style);
1665
1666 // tooltip foreground and background
1667- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
3de22d0e 1668- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
a0850653
JR
1669+ style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
1670 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
f0a96e4f
JR
1671 sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
1672- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
3de22d0e
JR
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);
a0850653
JR
1684- g_object_unref(style);
1685+ ReleaseStyleContext(style);
1686
1687 // menu foreground & menu background
1688 GtkWidget *accel_label = gtk_accel_label_new("M");
1689diff -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:
1732diff -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 }
f0a96e4f 1753
a0850653
JR
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 }
f0a96e4f 1983
a0850653
JR
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();
f0a96e4f 1992+
a0850653
JR
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);
f0a96e4f 1996+
a0850653
JR
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);
f0a96e4f 2001+
a0850653
JR
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"));
f0a96e4f 2016
a0850653
JR
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();
f0a96e4f 2022
a0850653
JR
2023- gtk_widget_path_append_type(path, G_TYPE_NONE);
2024+ gtk_widget_path_append_type(path, aType);
f0a96e4f 2025
a0850653
JR
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;
f0a96e4f 2282 #endif
a0850653
JR
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);
f0a96e4f 2301+ }
a0850653
JR
2302+ }
2303 return style;
2304 }
2305
2306diff -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.511263 seconds and 4 git commands to generate.