From 2af955e2571898aa06e5d254de2d7545076421df Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Wed, 18 Jan 2017 17:30:40 +0100 Subject: [PATCH] Update to 51.0 - updated widget patch and build fixes --- firefox-build-prbool.patch | 22 + firefox.spec | 4 +- widget-rebase.patch | 3076 +++++++++++------------------------- 3 files changed, 984 insertions(+), 2118 deletions(-) diff --git a/firefox-build-prbool.patch b/firefox-build-prbool.patch index 518aeb0..67443c3 100644 --- a/firefox-build-prbool.patch +++ b/firefox-build-prbool.patch @@ -20,3 +20,25 @@ diff -up firefox-48.0/security/certverifier/OCSPCache.h.prbool firefox-48.0/secu #include "hasht.h" #include "mozilla/Mutex.h" #include "mozilla/Vector.h" +diff -up firefox-51.0/security/certverifier/CTLogVerifier.cpp.old firefox-51.0/security/certverifier/CTLogVerifier.cpp +--- firefox-51.0/security/certverifier/CTLogVerifier.cpp.old 2017-01-18 13:03:34.758386735 +0100 ++++ firefox-51.0/security/certverifier/CTLogVerifier.cpp 2017-01-18 13:03:38.753367776 +0100 +@@ -7,6 +7,7 @@ + #include "CTLogVerifier.h" + + #include "CTSerialization.h" ++#include "prtypes.h" + #include "hasht.h" + #include "mozilla/ArrayUtils.h" + #include "mozilla/Assertions.h" +diff -up firefox-51.0/security/certverifier/CTObjectsExtractor.cpp.old firefox-51.0/security/certverifier/CTObjectsExtractor.cpp +--- firefox-51.0/security/certverifier/CTObjectsExtractor.cpp.old 2017-01-18 13:01:57.629847680 +0100 ++++ firefox-51.0/security/certverifier/CTObjectsExtractor.cpp 2017-01-18 13:02:01.892827449 +0100 +@@ -6,6 +6,7 @@ + + #include "CTObjectsExtractor.h" + ++#include "prtypes.h" + #include "hasht.h" + #include "mozilla/Assertions.h" + #include "mozilla/Casting.h" diff --git a/firefox.spec b/firefox.spec index 046a393..354deb5 100644 --- a/firefox.spec +++ b/firefox.spec @@ -137,7 +137,7 @@ Patch402: mozilla-1196777.patch Patch406: mozilla-256180.patch # Rebase Gtk3 widget code to latest trunk to # fix various rendering problems -#Patch407: widget-rebase.patch +Patch407: widget-rebase.patch # Debian patches Patch500: mozilla-440908.patch @@ -279,7 +279,7 @@ cd %{tarballdir} %patch406 -p1 -b .256180 # Rebase Gtk3 widget code to latest trunk to # fix various rendering problems -#%patch407 -p1 -b .widget-rebase +%patch407 -p1 -b .widget-rebase # Debian extension patch %patch500 -p1 -b .440908 diff --git a/widget-rebase.patch b/widget-rebase.patch index 85dcbc8..bb39e24 100644 --- a/widget-rebase.patch +++ b/widget-rebase.patch @@ -1,13 +1,11 @@ -diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widget/gtk/gtk3drawing.cpp ---- firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/gtk3drawing.cpp 2016-11-24 11:57:52.033064782 +0100 -@@ -18,27 +18,6 @@ +diff -up firefox-51.0/widget/gtk/gtk3drawing.cpp.old firefox-51.0/widget/gtk/gtk3drawing.cpp +--- firefox-51.0/widget/gtk/gtk3drawing.cpp.old 2017-01-18 16:24:56.375732107 +0100 ++++ firefox-51.0/widget/gtk/gtk3drawing.cpp 2017-01-10 11:28:15.000000000 +0100 +@@ -18,16 +18,6 @@ #include -static GtkWidget* gProtoLayout; --static GtkWidget* gHScaleWidget; --static GtkWidget* gVScaleWidget; -static GtkWidget* gComboBoxWidget; -static GtkWidget* gComboBoxButtonWidget; -static GtkWidget* gComboBoxArrowWidget; @@ -16,26 +14,14 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg -static GtkWidget* gComboBoxEntryTextareaWidget; -static GtkWidget* gComboBoxEntryButtonWidget; -static GtkWidget* gComboBoxEntryArrowWidget; --static GtkWidget* gTabWidget; --static GtkWidget* gImageMenuItemWidget; --static GtkWidget* gCheckMenuItemWidget; --static GtkWidget* gTreeViewWidget; --static GtkTreeViewColumn* gMiddleTreeViewColumn; --static GtkWidget* gTreeHeaderCellWidget; --static GtkWidget* gTreeHeaderSortArrowWidget; --static GtkWidget* gHPanedWidget; --static GtkWidget* gVPanedWidget; - static style_prop_t style_prop_func; static gboolean have_arrow_scaling; static gboolean checkbox_check_state; -@@ -54,6 +33,13 @@ static gboolean is_initialized; - #define GTK_STATE_FLAG_CHECKED (1 << 11) - #endif +@@ -46,6 +36,10 @@ static gboolean is_initialized; + static gint + moz_gtk_get_tab_thickness(GtkStyleContext *style); -+static gint -+moz_gtk_get_tab_thickness(GtkStyleContext *style); -+ +static gint +moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect, + GtkWidgetState* state, GtkTextDirection direction); @@ -43,17 +29,10 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg static GtkStateFlags GetStateFlagsFromGtkWidgetState(GtkWidgetState* state) { -@@ -73,338 +59,17 @@ GetStateFlagsFromGtkWidgetState(GtkWidge - return stateFlags; +@@ -79,212 +73,6 @@ moz_gtk_enable_style_props(style_prop_t + return MOZ_GTK_SUCCESS; } --gint --moz_gtk_enable_style_props(style_prop_t styleGetProp) --{ -- style_prop_func = styleGetProp; -- return MOZ_GTK_SUCCESS; --} -- -static gint -setup_widget_prototype(GtkWidget* widget) -{ @@ -64,40 +43,6 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - return MOZ_GTK_SUCCESS; -} - --static gint --ensure_hpaned_widget() --{ -- if (!gHPanedWidget) { -- gHPanedWidget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); -- setup_widget_prototype(gHPanedWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- --static gint --ensure_vpaned_widget() --{ -- if (!gVPanedWidget) { -- gVPanedWidget = gtk_paned_new(GTK_ORIENTATION_VERTICAL); -- setup_widget_prototype(gVPanedWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- --static gint --ensure_scale_widget() --{ -- if (!gHScaleWidget) { -- gHScaleWidget = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, NULL); -- setup_widget_prototype(gHScaleWidget); -- } -- if (!gVScaleWidget) { -- gVScaleWidget = gtk_scale_new(GTK_ORIENTATION_VERTICAL, NULL); -- setup_widget_prototype(gVScaleWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- -/* We need to have pointers to the inner widgets (button, separator, arrow) - * of the ComboBox to get the correct rendering from theme engines which - * special cases their look. Since the inner layout can change, we ask GTK @@ -294,124 +239,10 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - return MOZ_GTK_SUCCESS; -} - --static gint --ensure_tab_widget() --{ -- if (!gTabWidget) { -- gTabWidget = gtk_notebook_new(); -- setup_widget_prototype(gTabWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- --static gint --ensure_image_menu_item_widget() --{ -- if (!gImageMenuItemWidget) { -- gImageMenuItemWidget = gtk_image_menu_item_new(); -- gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), -- gImageMenuItemWidget); -- gtk_widget_realize(gImageMenuItemWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- --static gint --ensure_check_menu_item_widget() --{ -- if (!gCheckMenuItemWidget) { -- gCheckMenuItemWidget = gtk_check_menu_item_new(); -- gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), -- gCheckMenuItemWidget); -- gtk_widget_realize(gCheckMenuItemWidget); -- } -- return MOZ_GTK_SUCCESS; --} -- --static gint --ensure_tree_view_widget() -+static GtkStateFlags -+GetStateFlagsFromGtkTabFlags(GtkTabFlags flags) + gint + moz_gtk_init() { -- if (!gTreeViewWidget) { -- gTreeViewWidget = gtk_tree_view_new(); -- setup_widget_prototype(gTreeViewWidget); -- } -- return MOZ_GTK_SUCCESS; -+ return ((flags & MOZ_GTK_TAB_SELECTED) == 0) ? -+ GTK_STATE_FLAG_NORMAL : GTK_STATE_FLAG_ACTIVE; - } - --static gint --ensure_tree_header_cell_widget() -+gint -+moz_gtk_enable_style_props(style_prop_t styleGetProp) - { -- if(!gTreeHeaderCellWidget) { -- /* -- * Some GTK engines paint the first and last cell -- * of a TreeView header with a highlight. -- * Since we do not know where our widget will be relative -- * to the other buttons in the TreeView header, we must -- * paint it as a button that is between two others, -- * thus ensuring it is neither the first or last button -- * in the header. -- * GTK doesn't give us a way to do this explicitly, -- * so we must paint with a button that is between two -- * others. -- */ -- -- GtkTreeViewColumn* firstTreeViewColumn; -- GtkTreeViewColumn* lastTreeViewColumn; -- -- ensure_tree_view_widget(); -- -- /* Create and append our three columns */ -- firstTreeViewColumn = gtk_tree_view_column_new(); -- gtk_tree_view_column_set_title(firstTreeViewColumn, "M"); -- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), firstTreeViewColumn); -- -- gMiddleTreeViewColumn = gtk_tree_view_column_new(); -- gtk_tree_view_column_set_title(gMiddleTreeViewColumn, "M"); -- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), -- gMiddleTreeViewColumn); -- -- lastTreeViewColumn = gtk_tree_view_column_new(); -- gtk_tree_view_column_set_title(lastTreeViewColumn, "M"); -- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), lastTreeViewColumn); -- -- /* Use the middle column's header for our button */ -- gTreeHeaderCellWidget = gtk_tree_view_column_get_button(gMiddleTreeViewColumn); -- /* TODO, but it can't be NULL */ -- gTreeHeaderSortArrowWidget = gtk_button_new(); -- } -+ style_prop_func = styleGetProp; - return MOZ_GTK_SUCCESS; - } - -@@ -423,13 +88,17 @@ moz_gtk_init() - else - checkbox_check_state = GTK_STATE_FLAG_ACTIVE; - -- if(!gtk_check_version(3, 12, 0)) { -- ensure_tab_widget(); -- gtk_style_context_get_style(gtk_widget_get_style_context(gTabWidget), -+ if (gtk_check_version(3, 12, 0) == nullptr && -+ gtk_check_version(3, 20, 0) != nullptr) -+ { -+ // Deprecated for Gtk >= 3.20+ -+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TAB_TOP); -+ gtk_style_context_get_style(style, - "has-tab-gap", ¬ebook_has_tab_gap, NULL); -+ ReleaseStyleContext(style); - } - else { -- notebook_has_tab_gap = TRUE; -+ notebook_has_tab_gap = true; - } - - return MOZ_GTK_SUCCESS; -@@ -455,16 +124,24 @@ moz_gtk_radio_get_metrics(gint* indicato +@@ -336,16 +124,24 @@ moz_gtk_radio_get_metrics(gint* indicato return MOZ_GTK_SUCCESS; } @@ -439,60 +270,16 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -472,22 +149,22 @@ moz_gtk_get_focus_outline_size(gint* foc - gint - moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding) - { -- gtk_widget_style_get(GetWidget(MOZ_GTK_MENUITEM), -- "horizontal-padding", horizontal_padding, -- nullptr); -- -+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_MENUITEM); -+ gtk_style_context_get_style(style, -+ "horizontal-padding", horizontal_padding, -+ nullptr); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - +@@ -364,7 +160,7 @@ moz_gtk_menuitem_get_horizontal_padding( gint moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding) { -- ensure_check_menu_item_widget(); -- -- gtk_style_context_get_style(gtk_widget_get_style_context(gCheckMenuItemWidget), +- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM_CONTAINER); + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM); -+ gtk_style_context_get_style(style, + gtk_style_context_get_style(style, "horizontal-padding", horizontal_padding, -- NULL); -- -+ nullptr); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -543,15 +220,14 @@ moz_gtk_button_get_default_border(gint* - gint - moz_gtk_splitter_get_metrics(gint orientation, gint* size) - { -+ GtkStyleContext *style; - if (orientation == GTK_ORIENTATION_HORIZONTAL) { -- ensure_hpaned_widget(); -- gtk_style_context_get_style(gtk_widget_get_style_context(gHPanedWidget), -- "handle_size", size, NULL); -+ style = ClaimStyleContext(MOZ_GTK_SPLITTER_HORIZONTAL); - } else { -- ensure_vpaned_widget(); -- gtk_style_context_get_style(gtk_widget_get_style_context(gVPanedWidget), -- "handle_size", size, NULL); -+ style = ClaimStyleContext(MOZ_GTK_SPLITTER_VERTICAL); - } -+ gtk_style_context_get_style(style, "handle_size", size, NULL); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -756,8 +432,66 @@ calculate_arrow_rect(GtkWidget* arrow, G + nullptr); +@@ -636,8 +432,66 @@ calculate_arrow_rect(GtkWidget* arrow, G return MOZ_GTK_SUCCESS; } @@ -560,7 +347,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkWidgetState* state, GtkScrollbarButtonFlags flags, GtkTextDirection direction) -@@ -795,32 +529,38 @@ moz_gtk_scrollbar_button_paint(cairo_t * +@@ -675,32 +529,38 @@ moz_gtk_scrollbar_button_paint(cairo_t * gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOP); } @@ -617,7 +404,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg if (state_flags & GTK_STATE_FLAG_ACTIVE) { gtk_style_context_get_style(style, -@@ -862,19 +602,23 @@ moz_gtk_update_scrollbar_style(GtkStyleC +@@ -742,19 +602,23 @@ moz_gtk_update_scrollbar_style(GtkStyleC static void moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr, @@ -646,7 +433,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkWidgetState* state, GtkScrollbarTrackFlags flags, GtkTextDirection direction) -@@ -886,26 +630,28 @@ moz_gtk_scrollbar_trough_paint(WidgetNod +@@ -766,26 +630,28 @@ moz_gtk_scrollbar_trough_paint(WidgetNod ReleaseStyleContext(style); } @@ -693,7 +480,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg direction); moz_gtk_draw_styled_frame(style, cr, rect, state->focused); ReleaseStyleContext(style); -@@ -915,21 +661,21 @@ moz_gtk_scrollbar_trough_paint(WidgetNod +@@ -795,21 +661,21 @@ moz_gtk_scrollbar_trough_paint(WidgetNod static gint moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget, @@ -722,120 +509,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); -@@ -987,18 +733,15 @@ moz_gtk_scale_paint(cairo_t *cr, GdkRect - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - gint x, y, width, height, min_width, min_height; - GtkStyleContext* style; -- GtkWidget* widget; - GtkBorder margin; - -- ensure_scale_widget(); -- widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget); -- gtk_widget_set_direction(widget, direction); - moz_gtk_get_scale_metrics(flags, &min_width, &min_height); - -- style = gtk_widget_get_style_context(widget); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); -- gtk_style_context_get_margin(style, state_flags, &margin); -+ WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ? -+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL : -+ MOZ_GTK_SCALE_TROUGH_VERTICAL; -+ style = ClaimStyleContext(widget, direction, state_flags); -+ gtk_style_context_get_margin(style, state_flags, &margin); - - // Clamp the dimension perpendicular to the direction that the slider crosses - // to the minimum size. -@@ -1020,7 +763,8 @@ moz_gtk_scale_paint(cairo_t *cr, GdkRect - if (state->focused) - gtk_render_focus(style, cr, - rect->x, rect->y, rect->width, rect->height); -- gtk_style_context_restore(style); -+ -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -1031,17 +775,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G - { - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style; -- GtkWidget* widget; - gint thumb_width, thumb_height, x, y; - -- ensure_scale_widget(); -- widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget); -- gtk_widget_set_direction(widget, direction); -- -- style = gtk_widget_get_style_context(widget); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER); -- gtk_style_context_set_state(style, state_flags); - /* determine the thumb size, and position the thumb in the center in the opposite axis - */ - if (flags == GTK_ORIENTATION_HORIZONTAL) { -@@ -1055,8 +790,13 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G - y = rect->y; - } - -+ WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ? -+ MOZ_GTK_SCALE_THUMB_HORIZONTAL : -+ MOZ_GTK_SCALE_THUMB_VERTICAL; -+ style = ClaimStyleContext(widget, direction, state_flags); - gtk_render_slider(style, cr, x, y, thumb_width, thumb_height, flags); -- gtk_style_context_restore(style); -+ ReleaseStyleContext(style); -+ - return MOZ_GTK_SUCCESS; - } - -@@ -1078,17 +818,13 @@ static gint - moz_gtk_hpaned_paint(cairo_t *cr, GdkRectangle* rect, - GtkWidgetState* state) - { -- GtkStyleContext* style; -- -- ensure_hpaned_widget(); -- style = gtk_widget_get_style_context(gHPanedWidget); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PANE_SEPARATOR); -- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); -+ GtkStyleContext* style = -+ ClaimStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL, -+ GTK_TEXT_DIR_LTR, -+ GetStateFlagsFromGtkWidgetState(state)); - gtk_render_handle(style, cr, - rect->x, rect->y, rect->width, rect->height); -- gtk_style_context_restore(style); -- -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -1096,17 +832,13 @@ static gint - moz_gtk_vpaned_paint(cairo_t *cr, GdkRectangle* rect, - GtkWidgetState* state) - { -- GtkStyleContext* style; -- -- ensure_vpaned_widget(); -- style = gtk_widget_get_style_context(gVPanedWidget); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PANE_SEPARATOR); -- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); -+ GtkStyleContext* style = -+ ClaimStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL, -+ GTK_TEXT_DIR_LTR, -+ GetStateFlagsFromGtkWidgetState(state)); - gtk_render_handle(style, cr, - rect->x, rect->y, rect->width, rect->height); -- gtk_style_context_restore(style); -- -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -1114,60 +846,26 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec +@@ -980,65 +846,31 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec static gint moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state, @@ -899,126 +573,56 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg return MOZ_GTK_SUCCESS; } -@@ -1214,9 +912,6 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR - GtkStateFlags state_flags; - GtkBorder border; + static gint +-moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect, ++moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect, + GtkWidgetState* state, + GtkTextDirection direction) + { +@@ -1046,24 +878,29 @@ moz_gtk_text_view_paint(cairo_t *cr, Gdk -- ensure_tree_view_widget(); -- gtk_widget_set_direction(gTreeViewWidget, direction); -- - /* only handle disabled and normal states, otherwise the whole background - * area will be painted differently with other states */ - state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL; -@@ -1225,19 +920,19 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR - gtk_style_context_get_border(style, state_flags, &border); - xthickness = border.left; - ythickness = border.top; -+ ReleaseStyleContext(style); - -- style_tree = gtk_widget_get_style_context(gTreeViewWidget); -- gtk_style_context_save(style_tree); -- gtk_style_context_add_class(style_tree, GTK_STYLE_CLASS_VIEW); -- -+ style_tree = ClaimStyleContext(MOZ_GTK_TREEVIEW_VIEW, direction); - gtk_render_background(style_tree, cr, - rect->x + xthickness, rect->y + ythickness, - rect->width - 2 * xthickness, - rect->height - 2 * ythickness); -+ ReleaseStyleContext(style_tree); + GtkStyleContext* style_frame = + ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags); +- gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height); ++ gtk_render_frame(style_frame, cr, ++ aRect->x, aRect->y, aRect->width, aRect->height); + -+ style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction); - gtk_render_frame(style, cr, - rect->x, rect->y, rect->width, rect->height); ++ GdkRectangle rect = *aRect; ++ InsetByBorderPadding(&rect, style_frame); + +- GtkBorder border, padding; +- gtk_style_context_get_border(style_frame, state_flags, &border); +- gtk_style_context_get_padding(style_frame, state_flags, &padding); + ReleaseStyleContext(style_frame); + + GtkStyleContext* style = + ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags); +- +- gint xthickness = border.left + padding.left; +- gint ythickness = border.top + padding.top; +- +- gtk_render_background(style, cr, +- rect->x + xthickness, rect->y + ythickness, +- rect->width - 2 * xthickness, +- rect->height - 2 * ythickness); +- ++ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); ++ ReleaseStyleContext(style); ++ // There is a separate "text" window, which usually provides the ++ // background behind the text. However, this is transparent in Ambiance ++ // for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is ++ // visible. ++ // Workaround for Bug 1328899 - We don't want "selected" background color ++ // for active view class here which is set by Ambiance theme. ++ if (state->focused && !state->disabled) { ++ state_flags = static_cast(GTK_STATE_FLAG_FOCUSED); ++ } ++ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags); ++ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); ReleaseStyleContext(style); -- gtk_style_context_restore(style_tree); + return MOZ_GTK_SUCCESS; - } - -@@ -1247,7 +942,7 @@ moz_gtk_tree_header_cell_paint(cairo_t * - gboolean isSorted, GtkTextDirection direction) - { - moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL, -- gTreeHeaderCellWidget, direction); -+ GetWidget(MOZ_GTK_TREE_HEADER_CELL), direction); - return MOZ_GTK_SUCCESS; - } - -@@ -1260,18 +955,13 @@ moz_gtk_tree_header_sort_arrow_paint(cai - gdouble arrow_angle; - GtkStyleContext* style; - -- ensure_tree_header_cell_widget(); -- gtk_widget_set_direction(gTreeHeaderSortArrowWidget, direction); -- - /* hard code these values */ - arrow_rect.width = 11; - arrow_rect.height = 11; - arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2; - arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2; -- style = gtk_widget_get_style_context(gTreeHeaderSortArrowWidget); -- gtk_style_context_save(style); -- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); -- -+ style = ClaimStyleContext(MOZ_GTK_TREE_HEADER_SORTARROW, direction, -+ GetStateFlagsFromGtkWidgetState(state)); - switch (arrow_type) { - case GTK_ARROW_LEFT: - arrow_angle = ARROW_LEFT; -@@ -1290,7 +980,7 @@ moz_gtk_tree_header_sort_arrow_paint(cai - gtk_render_arrow(style, cr, arrow_angle, - arrow_rect.x, arrow_rect.y, - arrow_rect.width); -- gtk_style_context_restore(style); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -1302,37 +992,28 @@ moz_gtk_treeview_expander_paint(cairo_t - GtkExpanderStyle expander_state, - GtkTextDirection direction) - { -- GtkStyleContext *style; -- GtkStateFlags state_flags; -- -- ensure_tree_view_widget(); -- gtk_widget_set_direction(gTreeViewWidget, direction); -- -- style = gtk_widget_get_style_context(gTreeViewWidget); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_EXPANDER); -- - /* Because the frame we get is of the entire treeview, we can't get the precise - * event state of one expander, thus rendering hover and active feedback useless. */ -- state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL; -+ GtkStateFlags state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : -+ GTK_STATE_FLAG_NORMAL; - - /* GTK_STATE_FLAG_ACTIVE controls expanded/colapsed state rendering - * in gtk_render_expander() - */ - if (expander_state == GTK_EXPANDER_EXPANDED) -- state_flags = static_cast(state_flags|GTK_STATE_FLAG_ACTIVE); -+ state_flags = static_cast(state_flags|checkbox_check_state); - else -- state_flags = static_cast(state_flags&~(GTK_STATE_FLAG_ACTIVE)); -- -- gtk_style_context_set_state(style, state_flags); -+ state_flags = static_cast(state_flags&~(checkbox_check_state)); - -+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TREEVIEW_EXPANDER, -+ direction, state_flags); - gtk_render_expander(style, cr, - rect->x, - rect->y, - rect->width, - rect->height); - -- gtk_style_context_restore(style); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -1349,34 +1030,37 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk +@@ -1198,34 +1035,37 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk GtkStyleContext* style; GtkRequisition arrow_req; @@ -1065,7 +669,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg gtk_style_context_get_style(style, "wide-separators", &wide_separators, "separator-width", &separator_width, -@@ -1460,15 +1144,14 @@ moz_gtk_combo_box_entry_button_paint(cai +@@ -1309,15 +1149,14 @@ moz_gtk_combo_box_entry_button_paint(cai GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); GtkStyleContext* style; @@ -1086,7 +690,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg "child-displacement-x", &x_displacement, "child-displacement-y", &y_displacement, NULL); -@@ -1476,15 +1159,14 @@ moz_gtk_combo_box_entry_button_paint(cai +@@ -1325,15 +1164,14 @@ moz_gtk_combo_box_entry_button_paint(cai arrow_rect.y += y_displacement; } @@ -1105,7 +709,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg return MOZ_GTK_SUCCESS; } -@@ -1504,7 +1186,6 @@ moz_gtk_container_paint(cairo_t *cr, Gdk +@@ -1353,7 +1191,6 @@ moz_gtk_container_paint(cairo_t *cr, Gdk } ReleaseStyleContext(style); @@ -1113,7 +717,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg return MOZ_GTK_SUCCESS; } -@@ -1590,12 +1271,53 @@ moz_gtk_toolbar_separator_paint(cairo_t +@@ -1439,13 +1276,52 @@ moz_gtk_toolbar_separator_paint(cairo_t } static gint @@ -1133,9 +737,11 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction); - gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); - gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- ReleaseStyleContext(style); + GdkRectangle rect = *aRect; + gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); + gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height); ++ ReleaseStyleContext(style); + + // Horizontal Box drawing + // @@ -1145,8 +751,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg + // 6px margin. + // For drawing Horizontal Box we have to inset drawing area by that 6px + // plus its CSS margin. -+ GtkStyleContext* boxStyle = -+ CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), style); ++ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX, direction); + + rect.x += 6; + rect.y += 6; @@ -1159,219 +764,58 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg + + // Label drawing + InsetByBorderPadding(&rect, boxStyle); ++ ReleaseStyleContext(boxStyle); + + GtkStyleContext* labelStyle = -+ CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); ++ ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction); + moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false); -+ g_object_unref(labelStyle); ++ ReleaseStyleContext(labelStyle); + -+ g_object_unref(boxStyle); -+ - ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } -@@ -1721,46 +1443,35 @@ moz_gtk_progress_chunk_paint(cairo_t *cr return MOZ_GTK_SUCCESS; } --gint --moz_gtk_get_tab_thickness(void) -+static gint -+moz_gtk_get_tab_thickness(GtkStyleContext *style) - { -- GtkBorder border; -- GtkStyleContext * style; -- -- ensure_tab_widget(); - if (!notebook_has_tab_gap) - return 0; /* tabs do not overdraw the tabpanel border with "no gap" style */ - -- style = gtk_widget_get_style_context(gTabWidget); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK); -+ GtkBorder border; - gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -- - if (border.top < 2) - return 2; /* some themes don't set ythickness correctly */ - - return border.top; - } - --static void --moz_gtk_tab_prepare_style_context(GtkStyleContext *style, -- GtkTabFlags flags) --{ -- gtk_style_context_set_state(style, ((flags & MOZ_GTK_TAB_SELECTED) == 0) ? -- GTK_STATE_FLAG_NORMAL : -- GTK_STATE_FLAG_ACTIVE); -- gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, -- (flags & MOZ_GTK_TAB_FIRST) ? -- GTK_REGION_FIRST : static_cast(0)); -- gtk_style_context_add_class(style, (flags & MOZ_GTK_TAB_BOTTOM) ? -- GTK_STYLE_CLASS_BOTTOM : -- GTK_STYLE_CLASS_TOP); -+gint -+moz_gtk_get_tab_thickness(WidgetNodeType aNodeType) -+{ -+ GtkStyleContext *style = ClaimStyleContext(aNodeType); -+ int thickness = moz_gtk_get_tab_thickness(style); -+ ReleaseStyleContext(style); -+ return thickness; - } - - /* actual small tabs */ - static gint - moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect, - GtkWidgetState* state, -- GtkTabFlags flags, GtkTextDirection direction) -+ GtkTabFlags flags, GtkTextDirection direction, -+ WidgetNodeType widget) - { - /* When the tab isn't selected, we just draw a notebook extension. - * When it is selected, we overwrite the adjacent border of the tabpanel -@@ -1772,14 +1483,10 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - GdkRectangle focusRect; - GdkRectangle backRect; - int initial_gap = 0; -+ bool isBottomTab = (widget == MOZ_GTK_TAB_BOTTOM); - -- ensure_tab_widget(); -- gtk_widget_set_direction(gTabWidget, direction); -- -- style = gtk_widget_get_style_context(gTabWidget); -- gtk_style_context_save(style); -- moz_gtk_tab_prepare_style_context(style, flags); -- -+ style = ClaimStyleContext(widget, direction, -+ GetStateFlagsFromGtkTabFlags(flags)); - tabRect = *rect; - - if (flags & MOZ_GTK_TAB_FIRST) { -@@ -1798,8 +1505,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - /* Only draw the tab */ - gtk_render_extension(style, cr, - tabRect.x, tabRect.y, tabRect.width, tabRect.height, -- (flags & MOZ_GTK_TAB_BOTTOM) ? -- GTK_POS_TOP : GTK_POS_BOTTOM ); -+ isBottomTab ? GTK_POS_TOP : GTK_POS_BOTTOM ); - } else { - /* Draw the tab and the gap - * We want the gap to be positioned exactly on the tabpanel top -@@ -1840,7 +1546,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - gint gap_loffset, gap_roffset, gap_voffset, gap_height; - - /* Get height needed by the gap */ -- gap_height = moz_gtk_get_tab_thickness(); -+ gap_height = moz_gtk_get_tab_thickness(style); - - /* Extract gap_voffset from the first bits of flags */ - gap_voffset = flags & MOZ_GTK_TAB_MARGIN_MASK; -@@ -1856,7 +1562,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - gap_loffset = initial_gap; - } - -- if (flags & MOZ_GTK_TAB_BOTTOM) { -+ if (isBottomTab) { - /* Draw the tab on bottom */ - focusRect.y += gap_voffset; - focusRect.height -= gap_voffset; -@@ -1920,15 +1626,9 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - gtk_render_frame(style, cr, tabRect.x, tabRect.y, tabRect.width, tabRect.height); - } - -- gtk_style_context_restore(style); -- - if (state->focused) { - /* Paint the focus ring */ - GtkBorder padding; -- -- gtk_style_context_save(style); -- moz_gtk_tab_prepare_style_context(style, flags); -- - gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding); - - focusRect.x += padding.left; -@@ -1938,10 +1638,8 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - - gtk_render_focus(style, cr, - focusRect.x, focusRect.y, focusRect.width, focusRect.height); -- -- gtk_style_context_restore(style); - } -- -+ ReleaseStyleContext(style); - - return MOZ_GTK_SUCCESS; - } -@@ -1951,14 +1649,7 @@ static gint - moz_gtk_tabpanels_paint(cairo_t *cr, GdkRectangle* rect, - GtkTextDirection direction) +@@ -1454,17 +1330,9 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe + GtkWidgetState* state, + GtkTextDirection direction) { - GtkStyleContext* style; - -- ensure_tab_widget(); -- gtk_widget_set_direction(gTabWidget, direction); -- -- style = gtk_widget_get_style_context(gTabWidget); -- gtk_style_context_save(style); -- -+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TABPANELS, direction); - gtk_render_background(style, cr, rect->x, rect->y, - rect->width, rect->height); - /* -@@ -1982,7 +1673,7 @@ moz_gtk_tabpanels_paint(cairo_t *cr, Gdk - rect->width, rect->height, - GTK_POS_TOP, rect->width - 1, rect->width); - cairo_restore(cr); -- -+ - /* right side */ - cairo_save(cr); - cairo_rectangle(cr, rect->x + rect->width / 2, rect->y, -@@ -1995,7 +1686,7 @@ moz_gtk_tabpanels_paint(cairo_t *cr, Gdk - GTK_POS_TOP, 0, 1); - cairo_restore(cr); +- // gtk_render_handle() draws a background, so use GtkTextView and its +- // GTK_STYLE_CLASS_VIEW to match the background with textarea elements. +- // The resizer is drawn with shaded variants of the background color, and +- // so a transparent background would lead to a transparent resizer. +- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR, +- GetStateFlagsFromGtkWidgetState(state)); +- // TODO - we need to save/restore style when gtk 3.20 CSS node path +- // is used +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); ++ GtkStyleContext* style = ++ ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR, ++ GetStateFlagsFromGtkWidgetState(state)); -- gtk_style_context_restore(style); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -2005,17 +1696,12 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t * - GtkArrowType arrow_type, - GtkTextDirection direction) + // Workaround unico not respecting the text direction for resizers. + // See bug 1174248. +@@ -1511,17 +1379,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr + GtkTextDirection direction, + WidgetNodeType widget) { -- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style; - gdouble arrow_angle; - gint arrow_size = MIN(rect->width, rect->height); - gint x = rect->x + (rect->width - arrow_size) / 2; - gint y = rect->y + (rect->height - arrow_size) / 2; - -- ensure_tab_widget(); +- GtkStyleContext* style; - -- style = gtk_widget_get_style_context(gTabWidget); -- gtk_style_context_save(style); - if (direction == GTK_TEXT_DIR_RTL) { - arrow_type = (arrow_type == GTK_ARROW_LEFT) ? - GTK_ARROW_RIGHT : GTK_ARROW_LEFT; -@@ -2035,12 +1721,12 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t * - break; - } - if (arrow_type != GTK_ARROW_NONE) { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK); /* TODO TEST */ -- gtk_style_context_set_state(style, state_flags); -+ style = ClaimStyleContext(MOZ_GTK_TAB_SCROLLARROW, direction, -+ GetStateFlagsFromGtkWidgetState(state)); - gtk_render_arrow(style, cr, arrow_angle, - x, y, arrow_size); -+ ReleaseStyleContext(style); - } -- gtk_style_context_restore(style); - return MOZ_GTK_SUCCESS; - } +- if (gtk_check_version(3, 20, 0) != nullptr) { +- /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR +- * because ClaimStyleContext() saves/restores that style */ +- style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction); +- gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR); +- } else { +- style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction); +- } ++ GtkStyleContext* style = ++ ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction); -@@ -2092,22 +1778,25 @@ static gint + if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE || + widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) { +@@ -1905,6 +1764,13 @@ static gint moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect, GtkTextDirection direction) { @@ -1385,32 +829,14 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkStyleContext* style; gboolean wide_separators; gint separator_height; -- guint border_width; - gint x, y, w; - GtkBorder padding; - -- border_width = -- gtk_container_get_border_width(GTK_CONTAINER( -- GetWidget(MOZ_GTK_MENUSEPARATOR))); - style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR, direction); - gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); - -- x = rect->x + border_width; -- y = rect->y + border_width; -- w = rect->width - border_width * 2; -+ x = rect->x; -+ y = rect->y; -+ w = rect->width; - - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR); -@@ -2144,37 +1833,32 @@ moz_gtk_menu_item_paint(WidgetNodeType w +@@ -1952,36 +1818,39 @@ moz_gtk_menu_item_paint(WidgetNodeType w + GtkWidgetState* state, GtkTextDirection direction) { gint x, y, w, h; ++ guint minorVersion = gtk_get_minor_version(); ++ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - if (state->inHover && !state->disabled) { -- guint border_width = -- gtk_container_get_border_width(GTK_CONTAINER(GetWidget(widget))); - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style = - ClaimStyleContext(widget, direction, state_flags); @@ -1424,11 +850,15 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - if (widget == MOZ_GTK_MENUBARITEM) { - gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); - } -+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); ++ // GTK versions prior to 3.8 render the background and frame only when not ++ // a separator and in hover prelight. ++ if (minorVersion < 8 && (widget == MOZ_GTK_MENUSEPARATOR || ++ !(state_flags & GTK_STATE_FLAG_PRELIGHT))) ++ return MOZ_GTK_SUCCESS; ++ + GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags); + -+ bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr; -+ if (pre_3_6) { ++ if (minorVersion < 6) { + // GTK+ 3.4 saves the style context and adds the menubar class to + // menubar children, but does each of these only when drawing, not + // during layout. @@ -1438,10 +868,10 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg } + } -- x = rect->x + border_width; -- y = rect->y + border_width; -- w = rect->width - border_width * 2; -- h = rect->height - border_width * 2; +- x = rect->x; +- y = rect->y; +- w = rect->width; +- h = rect->height; + x = rect->x; + y = rect->y; + w = rect->width; @@ -1456,14 +886,14 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - gtk_style_context_restore(style); - } - ReleaseStyleContext(style); -+ if (pre_3_6) { ++ if (minorVersion < 6) { + gtk_style_context_restore(style); } + ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -2194,63 +1878,68 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd +@@ -2001,16 +1870,16 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd return MOZ_GTK_SUCCESS; } @@ -1482,21 +912,16 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); GtkStyleContext* style; - GtkBorder padding; -- gint offset; gint indicator_size, horizontal_padding; gint x, y; - moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction); - -- ensure_check_menu_item_widget(); -- gtk_widget_set_direction(gCheckMenuItemWidget, direction); -- -- style = gtk_widget_get_style_context(gCheckMenuItemWidget); -- gtk_style_context_save(style); -+ if (checked) { -+ state_flags = static_cast(state_flags|checkbox_check_state); -+ } +@@ -2020,35 +1889,44 @@ moz_gtk_check_menu_item_paint(cairo_t *c + state_flags = static_cast(state_flags|checkbox_check_state); + } +- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM_CONTAINER : +- MOZ_GTK_CHECKMENUITEM_CONTAINER, +- direction); + bool pre_3_20 = gtk_get_minor_version() < 20; + gint offset; + style = ClaimStyleContext(widgetType, direction); @@ -1504,31 +929,23 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg "indicator-size", &indicator_size, "horizontal-padding", &horizontal_padding, NULL); -- -- if (isradio) { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO); + if (pre_3_20) { + GtkBorder padding; + gtk_style_context_get_padding(style, state_flags, &padding); + offset = horizontal_padding + padding.left + 2; - } else { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK); -- } -- -- if (checked) { -- state_flags = static_cast(state_flags|checkbox_check_state); ++ } else { + GdkRectangle r = { 0 }; + InsetByMargin(&r, style); + InsetByBorderPadding(&r, style); + offset = r.x; - } -- -- gtk_style_context_set_state(style, state_flags); -- gtk_style_context_get_padding(style, state_flags, &padding); -+ ReleaseStyleContext(style); ++ } + ReleaseStyleContext(style); -- offset = gtk_container_get_border_width(GTK_CONTAINER(gCheckMenuItemWidget)) + -- padding.left + 2; +- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM : +- MOZ_GTK_CHECKMENUITEM, +- direction, state_flags); +- gtk_style_context_get_padding(style, state_flags, &padding); +- gint offset = padding.left + 2; + bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM); + WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR + : MOZ_GTK_CHECKMENUITEM_INDICATOR; @@ -1544,23 +961,18 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg } y = rect->y + (rect->height - indicator_size) / 2; -- if (isradio) { +- if (gtk_check_version(3, 20, 0) == nullptr) { + if (!pre_3_20) { -+ gtk_render_background(style, cr, x, y, indicator_size, indicator_size); -+ gtk_render_frame(style, cr, x, y, indicator_size, indicator_size); -+ } -+ + gtk_render_background(style, cr, x, y, indicator_size, indicator_size); + gtk_render_frame(style, cr, x, y, indicator_size, indicator_size); + } + +- if (isradio) { + if (isRadio) { gtk_render_option(style, cr, x, y, indicator_size, indicator_size); } else { gtk_render_check(style, cr, x, y, indicator_size, indicator_size); - } -- gtk_style_context_restore(style); -+ ReleaseStyleContext(style); - - return MOZ_GTK_SUCCESS; - } -@@ -2271,6 +1960,20 @@ moz_gtk_info_bar_paint(cairo_t *cr, GdkR +@@ -2074,6 +1952,20 @@ moz_gtk_info_bar_paint(cairo_t *cr, GdkR } static void @@ -1581,7 +993,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg moz_gtk_add_style_border(GtkStyleContext* style, gint* left, gint* top, gint* right, gint* bottom) { -@@ -2298,6 +2001,15 @@ moz_gtk_add_style_padding(GtkStyleContex +@@ -2101,6 +1993,15 @@ moz_gtk_add_style_padding(GtkStyleContex *bottom += padding.bottom; } @@ -1597,28 +1009,18 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg gint moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top, gint* right, gint* bottom, GtkTextDirection direction, -@@ -2362,26 +2074,24 @@ moz_gtk_get_widget_border(WidgetNodeType - * assigned. - * That is why the following code is the same as for MOZ_GTK_BUTTON. - * */ -- ensure_tree_header_cell_widget(); -- *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gTreeHeaderCellWidget)); -- -- style = gtk_widget_get_style_context(gTreeHeaderCellWidget); -+ *left = *top = *right = *bottom = -+ gtk_container_get_border_width(GTK_CONTAINER( -+ GetWidget(MOZ_GTK_TREE_HEADER_CELL))); +@@ -2129,9 +2030,6 @@ moz_gtk_get_widget_border(WidgetNodeType + if (widget == MOZ_GTK_TOOLBAR_BUTTON) + gtk_style_context_restore(style); -+ style = ClaimStyleContext(MOZ_GTK_TREE_HEADER_CELL); +- // XXX: Subtract 1 pixel from the border to account for the added +- // -moz-focus-inner border (Bug 1228281). +- *left -= 1; *top -= 1; *right -= 1; *bottom -= 1; moz_gtk_add_style_border(style, left, top, right, bottom); - moz_gtk_add_style_padding(style, left, top, right, bottom); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - case MOZ_GTK_TREE_HEADER_SORTARROW: -- ensure_tree_header_cell_widget(); -- w = gTreeHeaderSortArrowWidget; -+ w = GetWidget(MOZ_GTK_TREE_HEADER_SORTARROW); + + ReleaseStyleContext(style); +@@ -2179,12 +2077,10 @@ moz_gtk_get_widget_border(WidgetNodeType + w = GetWidget(MOZ_GTK_TREE_HEADER_SORTARROW); break; case MOZ_GTK_DROPDOWN_ENTRY: - ensure_combo_box_entry_widgets(); @@ -1632,7 +1034,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; case MOZ_GTK_DROPDOWN: { -@@ -2393,32 +2103,33 @@ moz_gtk_get_widget_border(WidgetNodeType +@@ -2196,32 +2092,33 @@ moz_gtk_get_widget_border(WidgetNodeType GtkRequisition arrow_req; GtkBorder border; @@ -1677,64 +1079,34 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg if (direction == GTK_TEXT_DIR_RTL) *left += separator_width + arrow_req.width; -@@ -2428,8 +2139,7 @@ moz_gtk_get_widget_border(WidgetNodeType - return MOZ_GTK_SUCCESS; - } - case MOZ_GTK_TABPANELS: -- ensure_tab_widget(); -- w = gTabWidget; -+ w = GetWidget(MOZ_GTK_TABPANELS); - break; - case MOZ_GTK_PROGRESSBAR: - w = GetWidget(MOZ_GTK_PROGRESSBAR); -@@ -2440,12 +2150,8 @@ moz_gtk_get_widget_border(WidgetNodeType - w = GetWidget(MOZ_GTK_SPINBUTTON); - break; - case MOZ_GTK_SCALE_HORIZONTAL: -- ensure_scale_widget(); -- w = gHScaleWidget; -- break; - case MOZ_GTK_SCALE_VERTICAL: -- ensure_scale_widget(); -- w = gVScaleWidget; -+ w = GetWidget(widget); - break; - case MOZ_GTK_FRAME: - w = GetWidget(MOZ_GTK_FRAME); -@@ -2471,17 +2177,18 @@ moz_gtk_get_widget_border(WidgetNodeType - case MOZ_GTK_CHECKMENUITEM: - case MOZ_GTK_RADIOMENUITEM: +@@ -2271,12 +2168,15 @@ moz_gtk_get_widget_border(WidgetNodeType { -- if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) { -- // Bug 1274143 for MOZ_GTK_MENUBARITEM -- w = GetWidget(MOZ_GTK_MENUITEM); -+ // Bug 1274143 for MOZ_GTK_MENUBARITEM -+ WidgetNodeType type = + // Bug 1274143 for MOZ_GTK_MENUBARITEM + WidgetNodeType type = +- widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM ? +- MOZ_GTK_MENUITEM : MOZ_GTK_CHECKMENUITEM_CONTAINER; + widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget; -+ style = ClaimStyleContext(type); -+ + style = ClaimStyleContext(type); + +- moz_gtk_add_style_padding(style, left, top, right, bottom); +- + if (gtk_get_minor_version() < 20) { + moz_gtk_add_style_padding(style, left, top, right, bottom); - } else { -- ensure_check_menu_item_widget(); -- w = gCheckMenuItemWidget; ++ } else { + moz_gtk_add_margin_border_padding(style, + left, top, right, bottom); - } -- -- *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w)); -- moz_gtk_add_style_padding(gtk_widget_get_style_context(w), -- left, top, right, bottom); -+ ReleaseStyleContext(style); ++ } + ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } - case MOZ_GTK_INFO_BAR: -@@ -2490,11 +2197,86 @@ moz_gtk_get_widget_border(WidgetNodeType +@@ -2285,12 +2185,81 @@ moz_gtk_get_widget_border(WidgetNodeType + break; case MOZ_GTK_TOOLTIP: { - style = ClaimStyleContext(MOZ_GTK_TOOLTIP); +- style = ClaimStyleContext(MOZ_GTK_TOOLTIP); - moz_gtk_add_style_border(style, left, top, right, bottom); - moz_gtk_add_style_padding(style, left, top, right, bottom); +- ReleaseStyleContext(style); + // In GTK 3 there are 6 pixels of additional margin around the box. + // See details there: + // https://github.com/GNOME/gtk/blob/5ea69a136bd7e4970b3a800390e20314665aaed2/gtk/ui/gtktooltipwindow.ui#L11 @@ -1743,21 +1115,16 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg + // We also need to add margin/padding/borders from Tooltip content. + // Tooltip contains horizontal box, where icon and label is put. + // We ignore icon as long as we don't have support for it. -+ GtkStyleContext* boxStyle = -+ CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), -+ style); ++ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX); + moz_gtk_add_margin_border_padding(boxStyle, + left, top, right, bottom); ++ ReleaseStyleContext(boxStyle); + -+ GtkStyleContext* labelStyle = -+ CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); ++ GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL); + moz_gtk_add_margin_border_padding(labelStyle, + left, top, right, bottom); ++ ReleaseStyleContext(labelStyle); + -+ g_object_unref(labelStyle); -+ g_object_unref(boxStyle); -+ - ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } + case MOZ_GTK_SCROLLBAR_VERTICAL: @@ -1818,7 +1185,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg /* These widgets have no borders, since they are not containers. */ case MOZ_GTK_CHECKBUTTON_LABEL: case MOZ_GTK_RADIOBUTTON_LABEL: -@@ -2503,10 +2285,6 @@ moz_gtk_get_widget_border(WidgetNodeType +@@ -2299,10 +2268,6 @@ moz_gtk_get_widget_border(WidgetNodeType case MOZ_GTK_CHECKBUTTON: case MOZ_GTK_RADIOBUTTON: case MOZ_GTK_SCROLLBAR_BUTTON: @@ -1829,77 +1196,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg case MOZ_GTK_SCALE_THUMB_HORIZONTAL: case MOZ_GTK_SCALE_THUMB_VERTICAL: case MOZ_GTK_GRIPPER: -@@ -2540,35 +2318,48 @@ moz_gtk_get_widget_border(WidgetNodeType - - gint - moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom, -- GtkTextDirection direction, GtkTabFlags flags) -+ GtkTextDirection direction, GtkTabFlags flags, -+ WidgetNodeType widget) - { -- GtkStyleContext* style; -- int tab_curvature; -- -- ensure_tab_widget(); -- -- style = gtk_widget_get_style_context(gTabWidget); -- gtk_style_context_save(style); -- moz_gtk_tab_prepare_style_context(style, flags); -+ GtkStyleContext* style = ClaimStyleContext(widget, direction, -+ GetStateFlagsFromGtkTabFlags(flags)); - - *left = *top = *right = *bottom = 0; - moz_gtk_add_style_padding(style, left, top, right, bottom); - -- gtk_style_context_get_style(style, "tab-curvature", &tab_curvature, NULL); -- *left += tab_curvature; -- *right += tab_curvature; -+ // Gtk >= 3.20 does not use those styles -+ if (gtk_check_version(3, 20, 0) != nullptr) { -+ int tab_curvature; - -- if (flags & MOZ_GTK_TAB_FIRST) { -- int initial_gap; -- gtk_style_context_get_style(style, "initial-gap", &initial_gap, NULL); -- if (direction == GTK_TEXT_DIR_RTL) -- *right += initial_gap; -- else -- *left += initial_gap; -- } -+ gtk_style_context_get_style(style, "tab-curvature", &tab_curvature, NULL); -+ *left += tab_curvature; -+ *right += tab_curvature; -+ -+ if (flags & MOZ_GTK_TAB_FIRST) { -+ int initial_gap = 0; -+ gtk_style_context_get_style(style, "initial-gap", &initial_gap, NULL); -+ if (direction == GTK_TEXT_DIR_RTL) -+ *right += initial_gap; -+ else -+ *left += initial_gap; -+ } -+ } else { -+ GtkBorder margin; - -- gtk_style_context_restore(style); -+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin); -+ *left += margin.left; -+ *right += margin.right; - -+ if (flags & MOZ_GTK_TAB_FIRST) { -+ ReleaseStyleContext(style); -+ style = ClaimStyleContext(MOZ_GTK_NOTEBOOK_HEADER, direction); -+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin); -+ *left += margin.left; -+ *right += margin.right; -+ } -+ } -+ -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -2581,9 +2372,9 @@ moz_gtk_get_combo_box_entry_button_size( +@@ -2390,9 +2355,9 @@ moz_gtk_get_combo_box_entry_button_size( * as well as the minimum arrow size and its padding * */ GtkRequisition requisition; @@ -1911,21 +1208,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg *width = requisition.width; *height = requisition.height; -@@ -2595,10 +2386,11 @@ moz_gtk_get_tab_scroll_arrow_size(gint* - { - gint arrow_size; - -- ensure_tab_widget(); -- gtk_style_context_get_style(gtk_widget_get_style_context(gTabWidget), -+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TABPANELS); -+ gtk_style_context_get_style(style, - "scroll-arrow-hlength", &arrow_size, - NULL); -+ ReleaseStyleContext(style); - - *height = *width = arrow_size; - -@@ -2611,8 +2403,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi +@@ -2421,8 +2386,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi GtkWidget* widget; switch (widgetType) { case MOZ_GTK_DROPDOWN: @@ -1935,128 +1218,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; default: widget = GetWidget(MOZ_GTK_BUTTON_ARROW); -@@ -2659,11 +2450,9 @@ moz_gtk_get_expander_size(gint* size) - gint - moz_gtk_get_treeview_expander_size(gint* size) - { -- ensure_tree_view_widget(); -- gtk_style_context_get_style(gtk_widget_get_style_context(gTreeViewWidget), -- "expander-size", size, -- NULL); -- -+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TREEVIEW); -+ gtk_style_context_get_style(style, "expander-size", size, NULL); -+ ReleaseStyleContext(style); - return MOZ_GTK_SUCCESS; - } - -@@ -2674,14 +2463,7 @@ moz_gtk_get_menu_separator_height(gint * - gboolean wide_separators; - gint separator_height; - GtkBorder padding; -- GtkStyleContext* style; -- guint border_width; -- -- border_width = -- gtk_container_get_border_width(GTK_CONTAINER( -- GetWidget(MOZ_GTK_MENUSEPARATOR))); -- -- style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR); -+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR); - gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); - - gtk_style_context_save(style); -@@ -2695,7 +2477,7 @@ moz_gtk_get_menu_separator_height(gint * - gtk_style_context_restore(style); - ReleaseStyleContext(style); - -- *size = padding.top + padding.bottom + border_width*2; -+ *size = padding.top + padding.bottom; - *size += (wide_separators) ? separator_height : 1; - - return MOZ_GTK_SUCCESS; -@@ -2726,34 +2508,60 @@ void - moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width, - gint* scale_height) - { -- gint thumb_length, thumb_height, trough_border; -- GtkWidget* widget = orient == GTK_ORIENTATION_HORIZONTAL ? -- gHScaleWidget : gVScaleWidget; -- moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height); -- gtk_style_context_get_style(gtk_widget_get_style_context(widget), -- "trough-border", &trough_border, NULL); -- -- if (orient == GTK_ORIENTATION_HORIZONTAL) { -- *scale_width = thumb_length + trough_border * 2; -- *scale_height = thumb_height + trough_border * 2; -+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? -+ MOZ_GTK_SCALE_HORIZONTAL : -+ MOZ_GTK_SCALE_VERTICAL; -+ -+ if (gtk_check_version(3, 20, 0) != nullptr) { -+ gint thumb_length, thumb_height, trough_border; -+ moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height); -+ -+ GtkStyleContext* style = ClaimStyleContext(widget); -+ gtk_style_context_get_style(style, "trough-border", &trough_border, NULL); -+ -+ if (orient == GTK_ORIENTATION_HORIZONTAL) { -+ *scale_width = thumb_length + trough_border * 2; -+ *scale_height = thumb_height + trough_border * 2; -+ } else { -+ *scale_width = thumb_height + trough_border * 2; -+ *scale_height = thumb_length + trough_border * 2; -+ } -+ ReleaseStyleContext(style); - } else { -- *scale_width = thumb_height + trough_border * 2; -- *scale_height = thumb_length + trough_border * 2; -+ GtkStyleContext* style = ClaimStyleContext(widget); -+ gtk_style_context_get(style, gtk_style_context_get_state(style), -+ "min-width", scale_width, -+ "min-height", scale_height, -+ nullptr); -+ ReleaseStyleContext(style); - } - } - - gint - moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height) - { -- GtkWidget* widget; - -- ensure_scale_widget(); -- widget = ((orient == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget); -- -- gtk_style_context_get_style(gtk_widget_get_style_context(widget), -- "slider_length", thumb_length, -- "slider_width", thumb_height, -- NULL); -+ if (gtk_check_version(3, 20, 0) != nullptr) { -+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? -+ MOZ_GTK_SCALE_HORIZONTAL: -+ MOZ_GTK_SCALE_VERTICAL; -+ GtkStyleContext* style = ClaimStyleContext(widget); -+ gtk_style_context_get_style(style, -+ "slider_length", thumb_length, -+ "slider_width", thumb_height, -+ NULL); -+ ReleaseStyleContext(style); -+ } else { -+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? -+ MOZ_GTK_SCALE_THUMB_HORIZONTAL: -+ MOZ_GTK_SCALE_THUMB_VERTICAL; -+ GtkStyleContext* style = ClaimStyleContext(widget); -+ gtk_style_context_get(style, gtk_style_context_get_state(style), -+ "min-width", thumb_length, -+ "min-height", thumb_height, -+ nullptr); -+ ReleaseStyleContext(style); -+ } - - return MOZ_GTK_SUCCESS; - } -@@ -2761,6 +2569,9 @@ moz_gtk_get_scalethumb_metrics(GtkOrient +@@ -2588,6 +2552,9 @@ moz_gtk_get_scalethumb_metrics(GtkOrient gint moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics) { @@ -2066,7 +1228,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL); gtk_style_context_get_style(style, "slider_width", &metrics->slider_width, -@@ -2771,41 +2582,9 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro +@@ -2598,40 +2565,9 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro nullptr); ReleaseStyleContext(style); @@ -2086,8 +1248,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - gboolean result; - GtkSettings* settings; - -- ensure_image_menu_item_widget(); -- settings = gtk_widget_get_settings(gImageMenuItemWidget); +- settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_IMAGEMENUITEM)); - - g_object_get(settings, "gtk-menu-images", &result, NULL); - return result; @@ -2108,7 +1269,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg /* cairo_t *cr argument has to be a system-cairo. */ gint moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr, -@@ -2846,10 +2625,25 @@ moz_gtk_widget_paint(WidgetNodeType widg +@@ -2672,10 +2608,25 @@ moz_gtk_widget_paint(WidgetNodeType widg break; case MOZ_GTK_SCROLLBAR_HORIZONTAL: case MOZ_GTK_SCROLLBAR_VERTICAL: @@ -2138,7 +1299,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL: case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL: -@@ -2876,9 +2670,13 @@ moz_gtk_widget_paint(WidgetNodeType widg +@@ -2702,9 +2653,13 @@ moz_gtk_widget_paint(WidgetNodeType widg state, direction); break; case MOZ_GTK_SPINBUTTON_ENTRY: @@ -2155,7 +1316,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; case MOZ_GTK_GRIPPER: return moz_gtk_gripper_paint(cr, rect, state, -@@ -2903,9 +2701,13 @@ moz_gtk_widget_paint(WidgetNodeType widg +@@ -2729,9 +2684,13 @@ moz_gtk_widget_paint(WidgetNodeType widg (GtkExpanderStyle) flags, direction); break; case MOZ_GTK_ENTRY: @@ -2172,7 +1333,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg case MOZ_GTK_TEXT_VIEW: return moz_gtk_text_view_paint(cr, rect, state, direction); break; -@@ -2917,9 +2719,13 @@ moz_gtk_widget_paint(WidgetNodeType widg +@@ -2743,9 +2702,13 @@ moz_gtk_widget_paint(WidgetNodeType widg state, flags, direction); break; case MOZ_GTK_DROPDOWN_ENTRY: @@ -2189,20 +1350,7 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; case MOZ_GTK_CHECKBUTTON_CONTAINER: case MOZ_GTK_RADIOBUTTON_CONTAINER: -@@ -2957,9 +2763,10 @@ moz_gtk_widget_paint(WidgetNodeType widg - return moz_gtk_progress_chunk_paint(cr, rect, - direction, widget); - break; -- case MOZ_GTK_TAB: -+ case MOZ_GTK_TAB_TOP: -+ case MOZ_GTK_TAB_BOTTOM: - return moz_gtk_tab_paint(cr, rect, state, -- (GtkTabFlags) flags, direction); -+ (GtkTabFlags) flags, direction, widget); - break; - case MOZ_GTK_TABPANELS: - return moz_gtk_tabpanels_paint(cr, rect, direction); -@@ -2992,10 +2799,8 @@ moz_gtk_widget_paint(WidgetNodeType widg +@@ -2819,10 +2782,8 @@ moz_gtk_widget_paint(WidgetNodeType widg break; case MOZ_GTK_CHECKMENUITEM: case MOZ_GTK_RADIOMENUITEM: @@ -2215,17 +1363,11 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg break; case MOZ_GTK_SPLITTER_HORIZONTAL: return moz_gtk_vpaned_paint(cr, rect, state); -@@ -3043,31 +2848,6 @@ moz_gtk_shutdown() +@@ -2870,16 +2831,6 @@ moz_gtk_shutdown() /* This will destroy all of our widgets */ ResetWidgetCache(); -- /* TODO - replace it with appropriate widget */ -- if (gTreeHeaderSortArrowWidget) -- gtk_widget_destroy(gTreeHeaderSortArrowWidget); -- - gProtoLayout = NULL; -- gHScaleWidget = NULL; -- gVScaleWidget = NULL; - gComboBoxWidget = NULL; - gComboBoxButtonWidget = NULL; - gComboBoxSeparatorWidget = NULL; @@ -2234,72 +1376,50 @@ diff -up firefox-50.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-50.0/widg - gComboBoxEntryButtonWidget = NULL; - gComboBoxEntryArrowWidget = NULL; - gComboBoxEntryTextareaWidget = NULL; -- gTabWidget = NULL; -- gImageMenuItemWidget = NULL; -- gCheckMenuItemWidget = NULL; -- gTreeViewWidget = NULL; -- gMiddleTreeViewColumn = NULL; -- gTreeHeaderCellWidget = NULL; -- gTreeHeaderSortArrowWidget = NULL; -- gHPanedWidget = NULL; -- gVPanedWidget = NULL; - is_initialized = FALSE; return MOZ_GTK_SUCCESS; -diff -up firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-50.0/widget/gtk/gtkdrawing.h ---- firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/gtkdrawing.h 2016-11-24 11:57:52.034064779 +0100 -@@ -61,8 +61,6 @@ typedef enum { - typedef enum { - /* first eight bits are used to pass a margin */ - MOZ_GTK_TAB_MARGIN_MASK = 0xFF, -- /* bottom tabs */ -- MOZ_GTK_TAB_BOTTOM = 1 << 8, - /* the first tab in the group */ - MOZ_GTK_TAB_FIRST = 1 << 9, - /* the selected tab */ -@@ -128,6 +126,11 @@ typedef enum { - /* Paints a GtkScale. */ - MOZ_GTK_SCALE_HORIZONTAL, - MOZ_GTK_SCALE_VERTICAL, -+ /* Paints a GtkScale trough. */ -+ MOZ_GTK_SCALE_CONTENTS_HORIZONTAL, -+ MOZ_GTK_SCALE_CONTENTS_VERTICAL, -+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL, -+ MOZ_GTK_SCALE_TROUGH_VERTICAL, - /* Paints a GtkScale thumb. */ - MOZ_GTK_SCALE_THUMB_HORIZONTAL, - MOZ_GTK_SCALE_THUMB_VERTICAL, -@@ -173,14 +176,22 @@ typedef enum { - MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE, - /* Paints a progress chunk of a vertical indeterminated GtkProgressBar. */ - MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE, -+ /* Used as root style of whole GtkNotebook widget */ -+ MOZ_GTK_NOTEBOOK, -+ /* Used as root style of active GtkNotebook area which contains tabs and arrows. */ -+ MOZ_GTK_NOTEBOOK_HEADER, - /* Paints a tab of a GtkNotebook. flags is a GtkTabFlags, defined above. */ -- MOZ_GTK_TAB, -+ MOZ_GTK_TAB_TOP, -+ /* Paints a tab of a GtkNotebook. flags is a GtkTabFlags, defined above. */ -+ MOZ_GTK_TAB_BOTTOM, - /* Paints the background and border of a GtkNotebook. */ - MOZ_GTK_TABPANELS, - /* Paints a GtkArrow for a GtkNotebook. flags is a GtkArrowType. */ - MOZ_GTK_TAB_SCROLLARROW, -- /* Paints the background and border of a GtkTreeView */ -+ /* Paints the expander and border of a GtkTreeView */ - MOZ_GTK_TREEVIEW, -+ /* Paints the border of a GtkTreeView */ -+ MOZ_GTK_TREEVIEW_VIEW, - /* Paints treeheader cells */ - MOZ_GTK_TREE_HEADER_CELL, - /* Paints sort arrows in treeheader cells */ -@@ -199,19 +210,44 @@ typedef enum { +diff -up firefox-51.0/widget/gtk/gtkdrawing.h.old firefox-51.0/widget/gtk/gtkdrawing.h +--- firefox-51.0/widget/gtk/gtkdrawing.h.old 2017-01-16 17:16:53.000000000 +0100 ++++ firefox-51.0/widget/gtk/gtkdrawing.h 2017-01-06 10:20:43.000000000 +0100 +@@ -145,8 +145,11 @@ typedef enum { + MOZ_GTK_ENTRY, + /* Paints a GtkExpander. */ + MOZ_GTK_EXPANDER, +- /* Paints a GtkTextView. */ ++ /* Paints a GtkTextView or gets the style context corresponding to the ++ root node of a GtkTextView. */ + MOZ_GTK_TEXT_VIEW, ++ /* The "text" window or node of a GtkTextView */ ++ MOZ_GTK_TEXT_VIEW_TEXT, + /* Paints a GtkOptionMenu. */ + MOZ_GTK_DROPDOWN, + /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */ +@@ -160,11 +163,15 @@ typedef enum { + MOZ_GTK_TOOLBAR_SEPARATOR, + /* Paints a GtkToolTip */ + MOZ_GTK_TOOLTIP, ++ /* Paints a GtkBox from GtkToolTip */ ++ MOZ_GTK_TOOLTIP_BOX, ++ /* Paints a GtkLabel of GtkToolTip */ ++ MOZ_GTK_TOOLTIP_BOX_LABEL, + /* Paints a GtkFrame (e.g. a status bar panel). */ + MOZ_GTK_FRAME, + /* Paints the border of a GtkFrame */ + MOZ_GTK_FRAME_BORDER, +- /* Paints a resize grip for a GtkWindow */ ++ /* Paints a resize grip for a GtkTextView */ + MOZ_GTK_RESIZER, + /* Paints a GtkProgressBar. */ + MOZ_GTK_PROGRESSBAR, +@@ -210,11 +217,13 @@ typedef enum { MOZ_GTK_MENUBARITEM, /* Paints items of popup menus. */ MOZ_GTK_MENUITEM, +- MOZ_GTK_IMAGEMENUITEM, +- MOZ_GTK_CHECKMENUITEM_CONTAINER, +- MOZ_GTK_RADIOMENUITEM_CONTAINER, + /* Paints a menuitem with check indicator, or the gets the style context for + a menuitem that contains a checkbox. */ MOZ_GTK_CHECKMENUITEM, @@ -2308,19 +1428,9 @@ diff -up firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-50.0/widget/ MOZ_GTK_RADIOMENUITEM, + MOZ_GTK_RADIOMENUITEM_INDICATOR, MOZ_GTK_MENUSEPARATOR, -- /* Paints a GtkVPaned separator */ -+ /* GtkVPaned base class */ + /* GtkVPaned base class */ MOZ_GTK_SPLITTER_HORIZONTAL, -- /* Paints a GtkHPaned separator */ -+ /* GtkHPaned base class */ - MOZ_GTK_SPLITTER_VERTICAL, -+ /* Paints a GtkVPaned separator */ -+ MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL, -+ /* Paints a GtkHPaned separator */ -+ MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL, - /* Paints the background of a window, dialog or page. */ - MOZ_GTK_WINDOW, - /* Window container for all widgets */ +@@ -230,6 +239,22 @@ typedef enum { MOZ_GTK_WINDOW_CONTAINER, /* Paints a GtkInfoBar, for notifications. */ MOZ_GTK_INFO_BAR, @@ -2343,29 +1453,10 @@ diff -up firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-50.0/widget/ /* Used for scrolled window shell. */ MOZ_GTK_SCROLLED_WINDOW, -@@ -300,12 +336,14 @@ gint moz_gtk_get_widget_border(WidgetNod - * top/bottom: [OUT] the tab's top/bottom border - * direction: the text direction for the widget - * flags: tab-dependant flags; see the GtkTabFlags definition. -+ * widget: tab widget - * - * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise - */ - gint - moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom, -- GtkTextDirection direction, GtkTabFlags flags); -+ GtkTextDirection direction, GtkTabFlags flags, -+ WidgetNodeType widget); +@@ -505,23 +530,18 @@ gint + moz_gtk_get_tab_thickness(WidgetNodeType aNodeType); /** - * Get the desired size of a GtkCheckButton -@@ -481,19 +519,8 @@ GtkWidget* moz_gtk_get_scrollbar_widget( - /** - * Get the YTHICKNESS of a tab (notebook extension). - */ --gint moz_gtk_get_tab_thickness(void); -- --/** - * Get a boolean which indicates whether or not to use images in menus. - * If TRUE, use images in menus. - */ @@ -2376,12 +1467,10 @@ diff -up firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-50.0/widget/ - * If TRUE, use images in buttons. - */ -gboolean moz_gtk_images_in_buttons(void); -+gint -+moz_gtk_get_tab_thickness(WidgetNodeType aNodeType); - - /** +- +-/** * Get a boolean which indicates whether the theme draws scrollbar buttons. -@@ -501,6 +528,13 @@ gboolean moz_gtk_images_in_buttons(void) + * If TRUE, draw scrollbar buttons. */ gboolean moz_gtk_has_scrollbar_buttons(void); @@ -2395,9 +1484,9 @@ diff -up firefox-50.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-50.0/widget/ #if (MOZ_WIDGET_GTK == 2) #ifdef __cplusplus } -diff -up firefox-50.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase firefox-50.0/widget/gtk/mozgtk/mozgtk.c ---- firefox-50.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/mozgtk/mozgtk.c 2016-11-24 11:57:52.034064779 +0100 +diff -up firefox-51.0/widget/gtk/mozgtk/mozgtk.c.old firefox-51.0/widget/gtk/mozgtk/mozgtk.c +--- firefox-51.0/widget/gtk/mozgtk/mozgtk.c.old 2017-01-18 16:26:11.416376760 +0100 ++++ firefox-51.0/widget/gtk/mozgtk/mozgtk.c 2016-12-21 13:10:28.000000000 +0100 @@ -9,6 +9,7 @@ STUB(gdk_atom_name) STUB(gdk_beep) STUB(gdk_cairo_create) @@ -2414,23 +1503,7 @@ diff -up firefox-50.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase firefox-50.0/widg STUB(gtk_image_new) STUB(gtk_image_new_from_stock) STUB(gtk_image_set_from_pixbuf) -@@ -530,6 +530,7 @@ STUB(gtk_get_minor_version) - STUB(gtk_menu_button_new) - STUB(gtk_offscreen_window_new) - STUB(gtk_paned_new) -+STUB(gtk_radio_menu_item_new) - STUB(gtk_render_activity) - STUB(gtk_render_arrow) - STUB(gtk_render_background) -@@ -561,6 +562,7 @@ STUB(gtk_style_context_get_state) - STUB(gtk_style_context_get_style) - STUB(gtk_style_context_has_class) - STUB(gtk_style_context_invalidate) -+STUB(gtk_style_context_list_classes) - STUB(gtk_style_context_new) - STUB(gtk_style_context_remove_class) - STUB(gtk_style_context_remove_region) -@@ -575,10 +577,10 @@ STUB(gtk_tree_view_column_get_button) +@@ -577,10 +577,10 @@ STUB(gtk_tree_view_column_get_button) STUB(gtk_widget_get_preferred_size) STUB(gtk_widget_get_state_flags) STUB(gtk_widget_get_style_context) @@ -2442,25 +1515,477 @@ diff -up firefox-50.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase firefox-50.0/widg STUB(gtk_widget_path_new) STUB(gtk_widget_path_unref) STUB(gtk_widget_set_visual) -diff -up firefox-50.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase firefox-50.0/widget/gtk/nsLookAndFeel.cpp ---- firefox-50.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase 2016-11-24 12:00:04.563704500 +0100 -+++ firefox-50.0/widget/gtk/nsLookAndFeel.cpp 2016-11-24 12:00:47.316588277 +0100 -@@ -786,10 +786,10 @@ nsLookAndFeel::GetIntImpl(IntID aID, int +@@ -612,6 +612,9 @@ STUB(gdkx_visual_get) + STUB(gtk_object_get_type) + #endif + ++#ifndef GTK3_SYMBOLS ++// Only define the following workaround when using GTK3, which we detect ++// by checking if GTK3 stubs are not provided. + #include + // Bug 1271100 + // We need to trick system Cairo into not using the XShm extension due to +@@ -625,4 +628,5 @@ XShmQueryExtension(Display* aDisplay) + { + return False; + } ++#endif + +diff -up firefox-51.0/widget/gtk/nsLookAndFeel.cpp.old firefox-51.0/widget/gtk/nsLookAndFeel.cpp +--- firefox-51.0/widget/gtk/nsLookAndFeel.cpp.old 2017-01-18 16:25:23.072605687 +0100 ++++ firefox-51.0/widget/gtk/nsLookAndFeel.cpp 2017-01-06 10:20:43.000000000 +0100 +@@ -47,9 +47,6 @@ nsLookAndFeel::nsLookAndFeel() + : nsXPLookAndFeel(), + #if (MOZ_WIDGET_GTK == 2) + mStyle(nullptr), +-#else +- mBackgroundStyle(nullptr), +- mButtonStyle(nullptr), + #endif + mDefaultFontCached(false), mButtonFontCached(false), + mFieldFontCached(false), mMenuFontCached(false) +@@ -61,13 +58,27 @@ nsLookAndFeel::~nsLookAndFeel() + { + #if (MOZ_WIDGET_GTK == 2) + g_object_unref(mStyle); +-#else +- g_object_unref(mBackgroundStyle); +- g_object_unref(mButtonStyle); + #endif + } + + #if MOZ_WIDGET_GTK != 2 ++// Modifies color |*aDest| as if a pattern of color |aSource| was painted with ++// CAIRO_OPERATOR_OVER to a surface with color |*aDest|. ++static void ++ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) { ++ gdouble sourceCoef = aSource.alpha; ++ gdouble destCoef = aDest->alpha * (1.0 - sourceCoef); ++ gdouble resultAlpha = sourceCoef + destCoef; ++ if (resultAlpha != 0.0) { // don't divide by zero ++ destCoef /= resultAlpha; ++ sourceCoef /= resultAlpha; ++ aDest->red = sourceCoef * aSource.red + destCoef * aDest->red; ++ aDest->green = sourceCoef * aSource.green + destCoef * aDest->green; ++ aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue; ++ aDest->alpha = resultAlpha; ++ } ++} ++ + static void + GetLightAndDarkness(const GdkRGBA& aColor, + double* aLightness, double* aDarkness) +@@ -157,30 +168,55 @@ GetUnicoBorderGradientColors(GtkStyleCon + return result; + } + +- +-static void ++// Sets |aLightColor| and |aDarkColor| to colors from |aContext|. Returns ++// true if |aContext| uses these colors to render a visible border. ++// If returning false, then the colors returned are a fallback from the ++// border-color value even though |aContext| does not use these colors to ++// render a border. ++static bool + GetBorderColors(GtkStyleContext* aContext, + GdkRGBA* aLightColor, GdkRGBA* aDarkColor) + { +- if (GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor)) +- return; +- ++ // Determine whether the border on this style context is visible. + GtkStateFlags state = gtk_style_context_get_state(aContext); ++ GtkBorderStyle borderStyle; ++ gtk_style_context_get(aContext, state, GTK_STYLE_PROPERTY_BORDER_STYLE, ++ &borderStyle, nullptr); ++ bool visible = borderStyle != GTK_BORDER_STYLE_NONE && ++ borderStyle != GTK_BORDER_STYLE_HIDDEN; ++ if (visible) { ++ // GTK has an initial value of zero for border-widths, and so themes ++ // need to explicitly set border-widths to make borders visible. ++ GtkBorder border; ++ gtk_style_context_get_border(aContext, GTK_STATE_FLAG_NORMAL, &border); ++ visible = border.top != 0 || border.right != 0 || ++ border.bottom != 0 || border.left != 0; ++ } ++ ++ if (visible && ++ GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor)) ++ return true; ++ ++ // The initial value for the border-color is the foreground color, and so ++ // this will usually return a color distinct from the background even if ++ // there is no visible border detected. + gtk_style_context_get_border_color(aContext, state, aDarkColor); + // TODO GTK3 - update aLightColor + // for GTK_BORDER_STYLE_INSET/OUTSET/GROVE/RIDGE border styles. + // https://bugzilla.mozilla.org/show_bug.cgi?id=978172#c25 + *aLightColor = *aDarkColor; ++ return visible; + } + +-static void ++static bool + GetBorderColors(GtkStyleContext* aContext, + nscolor* aLightColor, nscolor* aDarkColor) + { + GdkRGBA lightColor, darkColor; +- GetBorderColors(aContext, &lightColor, &darkColor); ++ bool ret = GetBorderColors(aContext, &lightColor, &darkColor); + *aLightColor = GDK_RGBA_TO_NS_RGBA(lightColor); + *aDarkColor = GDK_RGBA_TO_NS_RGBA(darkColor); ++ return ret; + } + #endif + +@@ -352,30 +388,39 @@ nsLookAndFeel::NativeGetColor(ColorID aI + break; + #else + // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors +- case eColorID_activeborder: ++ case eColorID_activeborder: { + // active window border +- gtk_style_context_get_border_color(mBackgroundStyle, ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); ++ gtk_style_context_get_border_color(style, + GTK_STATE_FLAG_NORMAL, &gdk_color); + aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); ++ ReleaseStyleContext(style); + break; +- case eColorID_inactiveborder: ++ } ++ case eColorID_inactiveborder: { + // inactive window border +- gtk_style_context_get_border_color(mBackgroundStyle, +- GTK_STATE_FLAG_INSENSITIVE, ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); ++ gtk_style_context_get_border_color(style, ++ GTK_STATE_FLAG_INSENSITIVE, + &gdk_color); + aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); ++ ReleaseStyleContext(style); + break; ++ } + case eColorID_graytext: // disabled text in windows, menus, etc. + case eColorID_inactivecaptiontext: // text in inactive window caption + aColor = sMenuTextInactive; + break; +- case eColorID_inactivecaption: ++ case eColorID_inactivecaption: { + // inactive window caption +- gtk_style_context_get_background_color(mBackgroundStyle, ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); ++ gtk_style_context_get_background_color(style, + GTK_STATE_FLAG_INSENSITIVE, + &gdk_color); + aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); ++ ReleaseStyleContext(style); + break; ++ } + #endif + case eColorID_infobackground: + // tooltip background color +@@ -496,18 +541,24 @@ nsLookAndFeel::NativeGetColor(ColorID aI + case eColorID__moz_fieldtext: + aColor = sMozFieldText; + break; +- case eColorID__moz_buttondefault: +- // default button border color +- gtk_style_context_get_border_color(mButtonStyle, ++ case eColorID__moz_buttondefault: { ++ // default button border color ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); ++ gtk_style_context_get_border_color(style, + GTK_STATE_FLAG_NORMAL, &gdk_color); + aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); ++ ReleaseStyleContext(style); + break; +- case eColorID__moz_buttonhoverface: +- gtk_style_context_get_background_color(mButtonStyle, ++ } ++ case eColorID__moz_buttonhoverface: { ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); ++ gtk_style_context_get_background_color(style, + GTK_STATE_FLAG_PRELIGHT, + &gdk_color); + aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); ++ ReleaseStyleContext(style); + break; ++ } + case eColorID__moz_buttonhovertext: + aColor = sButtonHoverText; + break; +@@ -784,12 +835,6 @@ nsLookAndFeel::GetIntImpl(IntID aID, int + case eIntID_SpellCheckerUnderlineStyle: aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; break; - case eIntID_ImagesInMenus: +- case eIntID_ImagesInMenus: - aResult = moz_gtk_images_in_menus(); -+ aResult = 0; - break; - case eIntID_ImagesInButtons: +- break; +- case eIntID_ImagesInButtons: - aResult = moz_gtk_images_in_buttons(); -+ aResult = 0; - break; +- break; case eIntID_MenuBarDrag: aResult = sMenuSupportsDrag; -diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp ---- firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp 2016-11-24 11:57:52.034064779 +0100 + break; +@@ -1010,16 +1055,6 @@ nsLookAndFeel::GetFontImpl(FontID aID, n + return true; + } + +-#if (MOZ_WIDGET_GTK == 3) +-static GtkStyleContext* +-create_context(GtkWidgetPath *path) +-{ +- GtkStyleContext *style = gtk_style_context_new(); +- gtk_style_context_set_path(style, path); +- return(style); +-} +-#endif +- + void + nsLookAndFeel::Init() + { +@@ -1110,78 +1145,54 @@ nsLookAndFeel::Init() + g_object_set(settings, dark_setting, FALSE, nullptr); + } + +- GtkWidgetPath *path = gtk_widget_path_new(); +- gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); +- +- mBackgroundStyle = create_context(path); +- gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND); +- +- mButtonStyle = create_context(path); +- gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON); +- + // Scrollbar colors +- style = create_context(path); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); ++ style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color); +- g_object_unref(style); ++ ReleaseStyleContext(style); + + // Window colors +- style = create_context(path); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); ++ style = ClaimStyleContext(MOZ_GTK_WINDOW); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMozWindowText = GDK_RGBA_TO_NS_RGBA(color); +- gtk_style_context_restore(style); +- g_object_unref(style); ++ ReleaseStyleContext(style); + + // tooltip foreground and background + style = ClaimStyleContext(MOZ_GTK_TOOLTIP); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); + sInfoBackground = GDK_RGBA_TO_NS_RGBA(color); +- { +- GtkStyleContext* boxStyle = +- CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), +- style); +- GtkStyleContext* labelStyle = +- CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); +- gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color); +- g_object_unref(labelStyle); +- g_object_unref(boxStyle); +- } +- sInfoText = GDK_RGBA_TO_NS_RGBA(color); + ReleaseStyleContext(style); + +- // menu foreground & menu background +- GtkWidget *accel_label = gtk_accel_label_new("M"); +- GtkWidget *menuitem = gtk_menu_item_new(); +- GtkWidget *menu = gtk_menu_new(); +- +- g_object_ref_sink(menu); +- +- gtk_container_add(GTK_CONTAINER(menuitem), accel_label); +- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); +- +- style = gtk_widget_get_style_context(accel_label); ++ style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL); + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); +- sMenuText = GDK_RGBA_TO_NS_RGBA(color); +- gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color); +- sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color); ++ sInfoText = GDK_RGBA_TO_NS_RGBA(color); ++ ReleaseStyleContext(style); + +- style = gtk_widget_get_style_context(menu); ++ style = ClaimStyleContext(MOZ_GTK_MENUITEM); ++ { ++ GtkStyleContext* accelStyle = ++ CreateStyleForWidget(gtk_accel_label_new("M"), style); ++ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_NORMAL, &color); ++ sMenuText = GDK_RGBA_TO_NS_RGBA(color); ++ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_INSENSITIVE, &color); ++ sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color); ++ g_object_unref(accelStyle); ++ } ++ ReleaseStyleContext(style); ++ ++ style = ClaimStyleContext(MOZ_GTK_MENUPOPUP); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMenuBackground = GDK_RGBA_TO_NS_RGBA(color); ++ ReleaseStyleContext(style); + +- style = gtk_widget_get_style_context(menuitem); ++ style = ClaimStyleContext(MOZ_GTK_MENUITEM); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color); + sMenuHover = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); + sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color); +- +- g_object_unref(menu); ++ ReleaseStyleContext(style); + #endif + + // button styles +@@ -1192,9 +1203,6 @@ nsLookAndFeel::Init() + GtkWidget *combobox = gtk_combo_box_new(); + GtkWidget *comboboxLabel = gtk_label_new("M"); + gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel); +-#else +- GtkWidget *combobox = gtk_combo_box_new_with_entry(); +- GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox)); + #endif + GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); + GtkWidget *treeView = gtk_tree_view_new(); +@@ -1208,7 +1216,9 @@ nsLookAndFeel::Init() + gtk_container_add(GTK_CONTAINER(parent), button); + gtk_container_add(GTK_CONTAINER(parent), treeView); + gtk_container_add(GTK_CONTAINER(parent), linkButton); ++#if (MOZ_WIDGET_GTK == 2) + gtk_container_add(GTK_CONTAINER(parent), combobox); ++#endif + gtk_container_add(GTK_CONTAINER(parent), menuBar); + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuBarItem); + gtk_container_add(GTK_CONTAINER(window), parent); +@@ -1291,11 +1301,19 @@ nsLookAndFeel::Init() + } + #else + // Text colors +- style = gtk_widget_get_style_context(textView); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW); +- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); +- sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color); ++ GdkRGBA bgColor; ++ // If the text window background is translucent, then the background of ++ // the textview root node is visible. ++ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW); ++ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, ++ &bgColor); ++ ReleaseStyleContext(style); ++ ++ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT); ++ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, ++ &color); ++ ApplyColorOver(color, &bgColor); ++ sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor); + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMozFieldText = GDK_RGBA_TO_NS_RGBA(color); + +@@ -1308,26 +1326,34 @@ nsLookAndFeel::Init() + static_cast(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED), + &color); + sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color); +- gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + +- // Button text, background, border +- style = gtk_widget_get_style_context(label); +- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); +- sButtonText = GDK_RGBA_TO_NS_RGBA(color); +- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); +- sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); ++ // Button text color ++ style = ClaimStyleContext(MOZ_GTK_BUTTON); ++ { ++ GtkStyleContext* labelStyle = ++ CreateStyleForWidget(gtk_label_new("M"), style); ++ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color); ++ sButtonText = GDK_RGBA_TO_NS_RGBA(color); ++ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color); ++ sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); ++ g_object_unref(labelStyle); ++ } ++ ReleaseStyleContext(style); + + // Combobox text color +- style = gtk_widget_get_style_context(comboboxLabel); ++ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA); + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); + sComboBoxText = GDK_RGBA_TO_NS_RGBA(color); ++ ReleaseStyleContext(style); + + // Menubar text and hover text colors +- style = gtk_widget_get_style_context(menuBarItem); ++ style = ClaimStyleContext(MOZ_GTK_MENUBARITEM); + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); + sMenuBarText = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); + sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color); ++ ReleaseStyleContext(style); + + // GTK's guide to fancy odd row background colors: + // 1) Check if a theme explicitly defines an odd row color +@@ -1335,7 +1361,7 @@ nsLookAndFeel::Init() + // slightly by a hardcoded value (gtkstyle.c) + // 3) If neither are defined, take the base background color and + // darken that by a hardcoded value +- style = gtk_widget_get_style_context(treeView); ++ style = ClaimStyleContext(MOZ_GTK_TREEVIEW); + + // Get odd row background color + gtk_style_context_save(style); +@@ -1343,12 +1369,21 @@ nsLookAndFeel::Init() + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); + sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + +- gtk_widget_path_free(path); +- ++ // GtkFrame has a "border" subnode on which Adwaita draws the border. ++ // Some themes do not draw on this node but draw a border on the widget ++ // root node, so check the root node if no border is found on the border ++ // node. + style = ClaimStyleContext(MOZ_GTK_FRAME_BORDER); +- GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder); ++ bool themeUsesColors = ++ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder); + ReleaseStyleContext(style); ++ if (!themeUsesColors) { ++ style = ClaimStyleContext(MOZ_GTK_FRAME); ++ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder); ++ ReleaseStyleContext(style); ++ } + + // GtkInfoBar + // TODO - Use WidgetCache for it? +@@ -1419,12 +1454,6 @@ nsLookAndFeel::RefreshImpl() + #if (MOZ_WIDGET_GTK == 2) + g_object_unref(mStyle); + mStyle = nullptr; +-#else +- g_object_unref(mBackgroundStyle); +- g_object_unref(mButtonStyle); +- +- mBackgroundStyle = nullptr; +- mButtonStyle = nullptr; + #endif + + Init(); +diff -up firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp.old firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp +--- firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp.old 2017-01-16 17:16:53.000000000 +0100 ++++ firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp 2016-10-31 11:52:13.000000000 +0100 @@ -149,19 +149,15 @@ static void SetWidgetStateSafe(uint8_t * aSafeVector[key >> 3] |= (1 << (key & 7)); } @@ -2489,388 +2014,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 } // Returns positive for negative margins (otherwise 0). -@@ -193,205 +189,199 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - gint* aWidgetFlags) - { - if (aState) { -- if (!aFrame) { -- // reset the entire struct to zero -- memset(aState, 0, sizeof(GtkWidgetState)); -- } else { -+ // For XUL checkboxes and radio buttons, the state of the parent -+ // determines our state. -+ nsIFrame *stateFrame = aFrame; -+ if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX || -+ aWidgetType == NS_THEME_RADIO)) || -+ aWidgetType == NS_THEME_CHECKBOX_LABEL || -+ aWidgetType == NS_THEME_RADIO_LABEL)) { - -- // For XUL checkboxes and radio buttons, the state of the parent -- // determines our state. -- nsIFrame *stateFrame = aFrame; -- if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX || -- aWidgetType == NS_THEME_RADIO)) || -- aWidgetType == NS_THEME_CHECKBOX_LABEL || -- aWidgetType == NS_THEME_RADIO_LABEL)) { -- -- nsIAtom* atom = nullptr; -- if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) { -- if (aWidgetType == NS_THEME_CHECKBOX_LABEL || -- aWidgetType == NS_THEME_RADIO_LABEL) { -- // Adjust stateFrame so GetContentState finds the correct state. -- stateFrame = aFrame = aFrame->GetParent()->GetParent(); -- } else { -- // GetContentState knows to look one frame up for radio/checkbox -- // widgets, so don't adjust stateFrame here. -- aFrame = aFrame->GetParent(); -+ nsIAtom* atom = nullptr; -+ if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) { -+ if (aWidgetType == NS_THEME_CHECKBOX_LABEL || -+ aWidgetType == NS_THEME_RADIO_LABEL) { -+ // Adjust stateFrame so GetContentState finds the correct state. -+ stateFrame = aFrame = aFrame->GetParent()->GetParent(); -+ } else { -+ // GetContentState knows to look one frame up for radio/checkbox -+ // widgets, so don't adjust stateFrame here. -+ aFrame = aFrame->GetParent(); -+ } -+ if (aWidgetFlags) { -+ if (!atom) { -+ atom = (aWidgetType == NS_THEME_CHECKBOX || -+ aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked -+ : nsGkAtoms::selected; - } -- if (aWidgetFlags) { -- if (!atom) { -- atom = (aWidgetType == NS_THEME_CHECKBOX || -- aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked -- : nsGkAtoms::selected; -- } -- *aWidgetFlags = CheckBooleanAttr(aFrame, atom); -+ *aWidgetFlags = CheckBooleanAttr(aFrame, atom); -+ } -+ } else { -+ if (aWidgetFlags) { -+ nsCOMPtr inputElt(do_QueryInterface(aFrame->GetContent())); -+ *aWidgetFlags = 0; -+ if (inputElt) { -+ bool isHTMLChecked; -+ inputElt->GetChecked(&isHTMLChecked); -+ if (isHTMLChecked) -+ *aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED; - } -- } else { -- if (aWidgetFlags) { -- nsCOMPtr inputElt(do_QueryInterface(aFrame->GetContent())); -- *aWidgetFlags = 0; -- if (inputElt) { -- bool isHTMLChecked; -- inputElt->GetChecked(&isHTMLChecked); -- if (isHTMLChecked) -- *aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED; -- } - -- if (GetIndeterminate(aFrame)) -- *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT; -- } -+ if (GetIndeterminate(aFrame)) -+ *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT; - } -- } else if (aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_TREEHEADERSORTARROW || -- aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS || -- aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || -- aWidgetType == NS_THEME_BUTTON_ARROW_UP || -- aWidgetType == NS_THEME_BUTTON_ARROW_DOWN) { -- // The state of an arrow comes from its parent. -- stateFrame = aFrame = aFrame->GetParent(); -- } -- -- EventStates eventState = GetContentState(stateFrame, aWidgetType); -- -- aState->disabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame); -- aState->active = eventState.HasState(NS_EVENT_STATE_ACTIVE); -- aState->focused = eventState.HasState(NS_EVENT_STATE_FOCUS); -- aState->inHover = eventState.HasState(NS_EVENT_STATE_HOVER); -- aState->isDefault = IsDefaultButton(aFrame); -- aState->canDefault = FALSE; // XXX fix me -- aState->depressed = FALSE; -- -- if (aWidgetType == NS_THEME_FOCUS_OUTLINE) { -- aState->disabled = FALSE; -- aState->active = FALSE; -- aState->inHover = FALSE; -- aState->isDefault = FALSE; -- aState->canDefault = FALSE; -- -- aState->focused = TRUE; -- aState->depressed = TRUE; // see moz_gtk_entry_paint() -- } else if (aWidgetType == NS_THEME_BUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON || -- aWidgetType == NS_THEME_DUALBUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_MENULIST || -- aWidgetType == NS_THEME_MENULIST_BUTTON) { -- aState->active &= aState->inHover; - } -- -- if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) { -- // For these widget types, some element (either a child or parent) -- // actually has element focus, so we check the focused attribute -- // to see whether to draw in the focused state. -- if (aWidgetType == NS_THEME_NUMBER_INPUT || -- aWidgetType == NS_THEME_TEXTFIELD || -- aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || -- aWidgetType == NS_THEME_MENULIST_TEXTFIELD || -- aWidgetType == NS_THEME_SPINNER_TEXTFIELD || -- aWidgetType == NS_THEME_RADIO_CONTAINER || -- aWidgetType == NS_THEME_RADIO_LABEL) { -- aState->focused = IsFocused(aFrame); -- } else if (aWidgetType == NS_THEME_RADIO || -- aWidgetType == NS_THEME_CHECKBOX) { -- // In XUL, checkboxes and radios shouldn't have focus rings, their labels do -- aState->focused = FALSE; -+ } else if (aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -+ aWidgetType == NS_THEME_TREEHEADERSORTARROW || -+ aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS || -+ aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || -+ aWidgetType == NS_THEME_BUTTON_ARROW_UP || -+ aWidgetType == NS_THEME_BUTTON_ARROW_DOWN) { -+ // The state of an arrow comes from its parent. -+ stateFrame = aFrame = aFrame->GetParent(); -+ } -+ -+ EventStates eventState = GetContentState(stateFrame, aWidgetType); -+ -+ aState->disabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame); -+ aState->active = eventState.HasState(NS_EVENT_STATE_ACTIVE); -+ aState->focused = eventState.HasState(NS_EVENT_STATE_FOCUS); -+ aState->inHover = eventState.HasState(NS_EVENT_STATE_HOVER); -+ aState->isDefault = IsDefaultButton(aFrame); -+ aState->canDefault = FALSE; // XXX fix me -+ aState->depressed = FALSE; -+ -+ if (aWidgetType == NS_THEME_FOCUS_OUTLINE) { -+ aState->disabled = FALSE; -+ aState->active = FALSE; -+ aState->inHover = FALSE; -+ aState->isDefault = FALSE; -+ aState->canDefault = FALSE; -+ -+ aState->focused = TRUE; -+ aState->depressed = TRUE; // see moz_gtk_entry_paint() -+ } else if (aWidgetType == NS_THEME_BUTTON || -+ aWidgetType == NS_THEME_TOOLBARBUTTON || -+ aWidgetType == NS_THEME_DUALBUTTON || -+ aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -+ aWidgetType == NS_THEME_MENULIST || -+ aWidgetType == NS_THEME_MENULIST_BUTTON) { -+ aState->active &= aState->inHover; -+ } -+ -+ if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) { -+ // For these widget types, some element (either a child or parent) -+ // actually has element focus, so we check the focused attribute -+ // to see whether to draw in the focused state. -+ if (aWidgetType == NS_THEME_NUMBER_INPUT || -+ aWidgetType == NS_THEME_TEXTFIELD || -+ aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || -+ aWidgetType == NS_THEME_MENULIST_TEXTFIELD || -+ aWidgetType == NS_THEME_SPINNER_TEXTFIELD || -+ aWidgetType == NS_THEME_RADIO_CONTAINER || -+ aWidgetType == NS_THEME_RADIO_LABEL) { -+ aState->focused = IsFocused(aFrame); -+ } else if (aWidgetType == NS_THEME_RADIO || -+ aWidgetType == NS_THEME_CHECKBOX) { -+ // In XUL, checkboxes and radios shouldn't have focus rings, their labels do -+ aState->focused = FALSE; -+ } -+ -+ if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || -+ aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) { -+ // for scrollbars we need to go up two to go from the thumb to -+ // the slider to the actual scrollbar object -+ nsIFrame *tmpFrame = aFrame->GetParent()->GetParent(); -+ -+ aState->curpos = CheckIntAttr(tmpFrame, nsGkAtoms::curpos, 0); -+ aState->maxpos = CheckIntAttr(tmpFrame, nsGkAtoms::maxpos, 100); -+ -+ if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) { -+ aState->active = TRUE; -+ // Set hover state to emulate Gtk style of active scrollbar thumb -+ aState->inHover = TRUE; - } -+ } - -- if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || -- aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) { -- // for scrollbars we need to go up two to go from the thumb to -- // the slider to the actual scrollbar object -- nsIFrame *tmpFrame = aFrame->GetParent()->GetParent(); -- -- aState->curpos = CheckIntAttr(tmpFrame, nsGkAtoms::curpos, 0); -- aState->maxpos = CheckIntAttr(tmpFrame, nsGkAtoms::maxpos, 100); -- -- if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) { -- aState->active = TRUE; -- // Set hover state to emulate Gtk style of active scrollbar thumb -- aState->inHover = TRUE; -- } -+ if (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || -+ aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || -+ aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || -+ aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) { -+ // set the state to disabled when the scrollbar is scrolled to -+ // the beginning or the end, depending on the button type. -+ int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0); -+ int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100); -+ if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) { -+ aState->disabled = true; - } - -- if (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) { -- // set the state to disabled when the scrollbar is scrolled to -- // the beginning or the end, depending on the button type. -- int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0); -- int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100); -- if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) { -- aState->disabled = true; -- } -+ // In order to simulate native GTK scrollbar click behavior, -+ // we set the active attribute on the element to true if it's -+ // pressed with any mouse button. -+ // This allows us to show that it's active without setting :active -+ else if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) -+ aState->active = true; -+ -+ if (aWidgetFlags) { -+ *aWidgetFlags = GetScrollbarButtonType(aFrame); -+ if (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP < 2) -+ *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL; -+ } -+ } - -- // In order to simulate native GTK scrollbar click behavior, -- // we set the active attribute on the element to true if it's -- // pressed with any mouse button. -- // This allows us to show that it's active without setting :active -- else if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) -- aState->active = true; -- -- if (aWidgetFlags) { -- *aWidgetFlags = GetScrollbarButtonType(aFrame); -- if (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP < 2) -- *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL; -- } -+ // menu item state is determined by the attribute "_moz-menuactive", -+ // and not by the mouse hovering (accessibility). as a special case, -+ // menus which are children of a menu bar are only marked as prelight -+ // if they are open, not on normal hover. -+ -+ if (aWidgetType == NS_THEME_MENUITEM || -+ aWidgetType == NS_THEME_CHECKMENUITEM || -+ aWidgetType == NS_THEME_RADIOMENUITEM || -+ aWidgetType == NS_THEME_MENUSEPARATOR || -+ aWidgetType == NS_THEME_MENUARROW) { -+ bool isTopLevel = false; -+ nsMenuFrame *menuFrame = do_QueryFrame(aFrame); -+ if (menuFrame) { -+ isTopLevel = menuFrame->IsOnMenuBar(); - } - -- // menu item state is determined by the attribute "_moz-menuactive", -- // and not by the mouse hovering (accessibility). as a special case, -- // menus which are children of a menu bar are only marked as prelight -- // if they are open, not on normal hover. -- -- if (aWidgetType == NS_THEME_MENUITEM || -- aWidgetType == NS_THEME_CHECKMENUITEM || -- aWidgetType == NS_THEME_RADIOMENUITEM || -- aWidgetType == NS_THEME_MENUSEPARATOR || -- aWidgetType == NS_THEME_MENUARROW) { -- bool isTopLevel = false; -- nsMenuFrame *menuFrame = do_QueryFrame(aFrame); -- if (menuFrame) { -- isTopLevel = menuFrame->IsOnMenuBar(); -- } -+ if (isTopLevel) { -+ aState->inHover = menuFrame->IsOpen(); -+ } else { -+ aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); -+ } - -- if (isTopLevel) { -- aState->inHover = menuFrame->IsOpen(); -- } else { -- aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); -- } -+ aState->active = FALSE; - -- aState->active = FALSE; -- -- if (aWidgetType == NS_THEME_CHECKMENUITEM || -- aWidgetType == NS_THEME_RADIOMENUITEM) { -- *aWidgetFlags = 0; -- if (aFrame && aFrame->GetContent()) { -- *aWidgetFlags = aFrame->GetContent()-> -- AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked, -- nsGkAtoms::_true, eIgnoreCase); -- } -+ if (aWidgetType == NS_THEME_CHECKMENUITEM || -+ aWidgetType == NS_THEME_RADIOMENUITEM) { -+ *aWidgetFlags = 0; -+ if (aFrame && aFrame->GetContent()) { -+ *aWidgetFlags = aFrame->GetContent()-> -+ AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked, -+ nsGkAtoms::_true, eIgnoreCase); - } - } -+ } - -- // A button with drop down menu open or an activated toggle button -- // should always appear depressed. -- if (aWidgetType == NS_THEME_BUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON || -- aWidgetType == NS_THEME_DUALBUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_MENULIST || -- aWidgetType == NS_THEME_MENULIST_BUTTON) { -- bool menuOpen = IsOpenButton(aFrame); -- aState->depressed = IsCheckedButton(aFrame) || menuOpen; -- // we must not highlight buttons with open drop down menus on hover. -- aState->inHover = aState->inHover && !menuOpen; -- } -- -- // When the input field of the drop down button has focus, some themes -- // should draw focus for the drop down button as well. -- if (aWidgetType == NS_THEME_MENULIST_BUTTON && aWidgetFlags) { -- *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused); -- } -+ // A button with drop down menu open or an activated toggle button -+ // should always appear depressed. -+ if (aWidgetType == NS_THEME_BUTTON || -+ aWidgetType == NS_THEME_TOOLBARBUTTON || -+ aWidgetType == NS_THEME_DUALBUTTON || -+ aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -+ aWidgetType == NS_THEME_MENULIST || -+ aWidgetType == NS_THEME_MENULIST_BUTTON) { -+ bool menuOpen = IsOpenButton(aFrame); -+ aState->depressed = IsCheckedButton(aFrame) || menuOpen; -+ // we must not highlight buttons with open drop down menus on hover. -+ aState->inHover = aState->inHover && !menuOpen; -+ } -+ -+ // When the input field of the drop down button has focus, some themes -+ // should draw focus for the drop down button as well. -+ if (aWidgetType == NS_THEME_MENULIST_BUTTON && aWidgetFlags) { -+ *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused); - } - } - } -@@ -435,6 +425,20 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u +@@ -429,6 +425,20 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u else *aWidgetFlags = 0; break; @@ -2891,93 +2035,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 case NS_THEME_SCROLLBARTHUMB_VERTICAL: aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL; break; -@@ -644,17 +648,17 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - break; - case NS_THEME_TAB: - { -+ if (IsBottomTab(aFrame)) { -+ aGtkWidgetType = MOZ_GTK_TAB_BOTTOM; -+ } else { -+ aGtkWidgetType = MOZ_GTK_TAB_TOP; -+ } -+ - if (aWidgetFlags) { - /* First bits will be used to store max(0,-bmargin) where bmargin - * is the bottom margin of the tab in pixels (resp. top margin, - * for bottom tabs). */ -- if (IsBottomTab(aFrame)) { -- *aWidgetFlags = MOZ_GTK_TAB_BOTTOM; -- } else { -- *aWidgetFlags = 0; -- } -- -- *aWidgetFlags |= GetTabMarginPixels(aFrame); -+ *aWidgetFlags = GetTabMarginPixels(aFrame); - - if (IsSelectedTab(aFrame)) - *aWidgetFlags |= MOZ_GTK_TAB_SELECTED; -@@ -662,8 +666,6 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - if (IsFirstTab(aFrame)) - *aWidgetFlags |= MOZ_GTK_TAB_FIRST; - } -- -- aGtkWidgetType = MOZ_GTK_TAB; - } - break; - case NS_THEME_SPLITTER: -@@ -862,12 +864,19 @@ DrawThemeWithCairo(gfxContext* aContext, - cairo_matrix_t mat; - GfxMatrixToCairoMatrix(transform, mat); - -+ nsIntSize clipSize((aDrawSize.width + aScaleFactor - 1) / aScaleFactor, -+ (aDrawSize.height + aScaleFactor - 1) / aScaleFactor); -+ - #ifndef MOZ_TREE_CAIRO - // Directly use the Cairo draw target to render the widget if using system Cairo everywhere. - BorrowedCairoContext borrowCairo(aDrawTarget); - if (borrowCairo.mCairo) { - cairo_set_matrix(borrowCairo.mCairo, &mat); - -+ cairo_new_path(borrowCairo.mCairo); -+ cairo_rectangle(borrowCairo.mCairo, 0, 0, clipSize.width, clipSize.height); -+ cairo_clip(borrowCairo.mCairo); -+ - moz_gtk_widget_paint(aGTKWidgetType, borrowCairo.mCairo, &aGDKRect, &aState, aFlags, aDirection); - - borrowCairo.Finish(); -@@ -908,6 +917,10 @@ DrawThemeWithCairo(gfxContext* aContext, - - cairo_set_matrix(cr, &mat); - -+ cairo_new_path(cr); -+ cairo_rectangle(cr, 0, 0, clipSize.width, clipSize.height); -+ cairo_clip(cr); -+ - moz_gtk_widget_paint(aGTKWidgetType, cr, &aGDKRect, &aState, aFlags, aDirection); - - cairo_destroy(cr); -@@ -942,6 +955,10 @@ DrawThemeWithCairo(gfxContext* aContext, - - cairo_set_matrix(cr, &mat); - -+ cairo_new_path(cr); -+ cairo_rectangle(cr, 0, 0, clipSize.width, clipSize.height); -+ cairo_clip(cr); -+ - moz_gtk_widget_paint(aGTKWidgetType, cr, &aGDKRect, &aState, aFlags, aDirection); - - cairo_destroy(cr); -@@ -1062,7 +1079,8 @@ nsNativeThemeGTK::GetExtraSizeForWidget( - if (!IsSelectedTab(aFrame)) - return false; - -- gint gap_height = moz_gtk_get_tab_thickness(); -+ gint gap_height = moz_gtk_get_tab_thickness(IsBottomTab(aFrame) ? -+ MOZ_GTK_TAB_BOTTOM : MOZ_GTK_TAB_TOP); - if (!gap_height) - return false; - -@@ -1097,14 +1115,7 @@ nsNativeThemeGTK::DrawWidgetBackground(n +@@ -1105,14 +1115,7 @@ nsNativeThemeGTK::DrawWidgetBackground(n { GtkWidgetState state; WidgetNodeType gtkWidgetType; @@ -2993,7 +2051,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 gint flags; if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, &state, &flags)) -@@ -1240,6 +1251,21 @@ nsNativeThemeGTK::DrawWidgetBackground(n +@@ -1248,6 +1251,21 @@ nsNativeThemeGTK::DrawWidgetBackground(n return NS_OK; } @@ -3015,7 +2073,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 NS_IMETHODIMP nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, nsIntMargin* aResult) -@@ -1247,24 +1273,6 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi +@@ -1255,24 +1273,6 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi GtkTextDirection direction = GetTextDirection(aFrame); aResult->top = aResult->left = aResult->right = aResult->bottom = 0; switch (aWidgetType) { @@ -3040,16 +2098,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 case NS_THEME_TOOLBOX: // gtk has no toolbox equivalent. So, although we map toolbox to // gtk's 'toolbar' for purposes of painting the widget background, -@@ -1289,7 +1297,7 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi - - moz_gtk_get_tab_border(&aResult->left, &aResult->top, - &aResult->right, &aResult->bottom, direction, -- (GtkTabFlags)flags); -+ (GtkTabFlags)flags, gtkWidgetType); - } - break; - case NS_THEME_MENUITEM: -@@ -1304,8 +1312,9 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi +@@ -1312,8 +1312,9 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi default: { WidgetNodeType gtkWidgetType; @@ -3060,7 +2109,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 moz_gtk_get_widget_border(gtkWidgetType, &aResult->left, &aResult->top, &aResult->right, &aResult->bottom, direction, IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML)); -@@ -1418,22 +1427,33 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n +@@ -1426,22 +1427,33 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n case NS_THEME_SCROLLBARBUTTON_UP: case NS_THEME_SCROLLBARBUTTON_DOWN: { @@ -3102,7 +2151,7 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 *aIsOverridable = false; } break; -@@ -1460,39 +1480,65 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n +@@ -1468,39 +1480,65 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n * the thumb isn't a direct child of the scrollbar, unlike the buttons * or track. So add a minimum size to the track as well to prevent a * 0-width scrollbar. */ @@ -3190,9 +2239,9 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.cpp.widget-rebase firefox-50.0 *aIsOverridable = false; } break; -diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.h.widget-rebase firefox-50.0/widget/gtk/nsNativeThemeGTK.h ---- firefox-50.0/widget/gtk/nsNativeThemeGTK.h.widget-rebase 2016-07-25 22:22:07.000000000 +0200 -+++ firefox-50.0/widget/gtk/nsNativeThemeGTK.h 2016-11-24 11:57:52.035064777 +0100 +diff -up firefox-51.0/widget/gtk/nsNativeThemeGTK.h.old firefox-51.0/widget/gtk/nsNativeThemeGTK.h +--- firefox-51.0/widget/gtk/nsNativeThemeGTK.h.old 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-51.0/widget/gtk/nsNativeThemeGTK.h 2016-10-27 16:22:27.000000000 +0200 @@ -74,6 +74,7 @@ protected: virtual ~nsNativeThemeGTK(); @@ -3209,44 +2258,54 @@ diff -up firefox-50.0/widget/gtk/nsNativeThemeGTK.h.widget-rebase firefox-50.0/w uint8_t mDisabledWidgetTypes[32]; uint8_t mSafeWidgetStates[1024]; // 256 widgets * 32 bits per widget -diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0/widget/gtk/WidgetStyleCache.cpp ---- firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/WidgetStyleCache.cpp 2016-11-24 11:57:52.035064777 +0100 -@@ -25,6 +25,8 @@ static bool sStyleContextNeedsRestore; - static GtkStyleContext* sCurrentStyleContext; - #endif - static GtkStyleContext* -+GetWidgetRootStyle(WidgetNodeType aNodeType); -+static GtkStyleContext* - GetCssNodeStyleInternal(WidgetNodeType aNodeType); - - static GtkWidget* -@@ -93,14 +95,6 @@ CreateMenuPopupWidget() - } - - static GtkWidget* --CreateMenuItemWidget(WidgetNodeType aShellType) --{ -- GtkWidget* widget = gtk_menu_item_new(); -- gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(aShellType)), widget); -- return widget; --} -- --static GtkWidget* - CreateProgressWidget() +diff -up firefox-51.0/widget/gtk/WidgetStyleCache.cpp.old firefox-51.0/widget/gtk/WidgetStyleCache.cpp +--- firefox-51.0/widget/gtk/WidgetStyleCache.cpp.old 2017-01-16 17:16:53.000000000 +0100 ++++ firefox-51.0/widget/gtk/WidgetStyleCache.cpp 2017-01-06 10:20:43.000000000 +0100 +@@ -33,7 +33,6 @@ static GtkWidget* + CreateWindowWidget() { - GtkWidget* widget = gtk_progress_bar_new(); -@@ -211,6 +205,235 @@ CreateEntryWidget() + GtkWidget *widget = gtk_window_new(GTK_WINDOW_POPUP); +- gtk_widget_realize(widget); + gtk_widget_set_name(widget, "MozillaGtkWidget"); + return widget; + } +@@ -50,7 +49,6 @@ static void + AddToWindowContainer(GtkWidget* widget) + { + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_WINDOW_CONTAINER)), widget); +- gtk_widget_realize(widget); } static GtkWidget* +@@ -142,7 +140,6 @@ CreateToolbarWidget() + { + GtkWidget* widget = gtk_toolbar_new(); + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget); +- gtk_widget_realize(widget); + return widget; + } + +@@ -183,7 +180,6 @@ CreateButtonArrowWidget() + { + GtkWidget* widget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_TOGGLE_BUTTON)), widget); +- gtk_widget_realize(widget); + gtk_widget_show(widget); + return widget; + } +@@ -205,19 +201,235 @@ CreateEntryWidget() + } + + static GtkWidget* +-CreateScrolledWindowWidget() +CreateComboBoxWidget() -+{ + { +- GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr); + GtkWidget* widget = gtk_combo_box_new(); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ + AddToWindowContainer(widget); + return widget; + } + +typedef struct +{ + GType type; @@ -3261,8 +2320,6 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 + if (G_TYPE_CHECK_INSTANCE_TYPE(widget, info->type)) { + *info->widget = widget; + } -+ -+ gtk_widget_realize(widget); +} + +static GtkWidget* @@ -3322,7 +2379,6 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 + /* appears-as-list = TRUE, or cell-view = FALSE; + * the button only contains an arrow */ + comboBoxArrow = buttonChild; -+ gtk_widget_realize(comboBoxArrow); + } + + if (!comboBoxArrow) { @@ -3429,9 +2485,13 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 + return comboBoxButton; +} + -+static GtkWidget* + static GtkWidget* +-CreateTextViewWidget() +CreateComboBoxEntryArrowWidget() -+{ + { +- GtkWidget* widget = gtk_text_view_new(); +- gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)), +- widget); + GtkWidget* comboBoxArrow = nullptr; + + /* Get the Arrow inside the Button */ @@ -3451,7 +2511,6 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 + /* appears-as-list = TRUE, or cell-view = FALSE; + * the button only contains an arrow */ + comboBoxArrow = buttonChild; -+ gtk_widget_realize(comboBoxArrow); + } + + if (!comboBoxArrow) { @@ -3469,136 +2528,58 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 +} + +static GtkWidget* - CreateScrolledWindowWidget() - { - GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr); -@@ -237,6 +460,95 @@ CreateMenuSeparatorWidget() ++CreateScrolledWindowWidget() ++{ ++ GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr); ++ AddToWindowContainer(widget); return widget; } -+static GtkWidget* -+CreateTreeViewWidget() -+{ -+ GtkWidget* widget = gtk_tree_view_new(); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ -+static GtkWidget* -+CreateTreeHeaderCellWidget() -+{ -+ /* -+ * Some GTK engines paint the first and last cell -+ * of a TreeView header with a highlight. -+ * Since we do not know where our widget will be relative -+ * to the other buttons in the TreeView header, we must -+ * paint it as a button that is between two others, -+ * thus ensuring it is neither the first or last button -+ * in the header. -+ * GTK doesn't give us a way to do this explicitly, -+ * so we must paint with a button that is between two -+ * others. -+ */ -+ GtkTreeViewColumn* firstTreeViewColumn; -+ GtkTreeViewColumn* middleTreeViewColumn; -+ GtkTreeViewColumn* lastTreeViewColumn; -+ -+ GtkWidget *treeView = GetWidget(MOZ_GTK_TREEVIEW); -+ -+ /* Create and append our three columns */ -+ firstTreeViewColumn = gtk_tree_view_column_new(); -+ gtk_tree_view_column_set_title(firstTreeViewColumn, "M"); -+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), -+ firstTreeViewColumn); -+ -+ middleTreeViewColumn = gtk_tree_view_column_new(); -+ gtk_tree_view_column_set_title(middleTreeViewColumn, "M"); -+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), -+ middleTreeViewColumn); -+ -+ lastTreeViewColumn = gtk_tree_view_column_new(); -+ gtk_tree_view_column_set_title(lastTreeViewColumn, "M"); -+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), -+ lastTreeViewColumn); -+ -+ /* Use the middle column's header for our button */ -+ return gtk_tree_view_column_get_button(middleTreeViewColumn); -+} -+ -+static GtkWidget* -+CreateTreeHeaderSortArrowWidget() -+{ -+ /* TODO, but it can't be NULL */ -+ GtkWidget* widget = gtk_button_new(); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ -+static GtkWidget* -+CreateHPanedWidget() -+{ -+ GtkWidget* widget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ -+static GtkWidget* -+CreateVPanedWidget() -+{ -+ GtkWidget* widget = gtk_paned_new(GTK_ORIENTATION_VERTICAL); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ -+static GtkWidget* -+CreateScaleWidget(GtkOrientation aOrientation) -+{ -+ GtkWidget* widget = gtk_scale_new(aOrientation, nullptr); -+ AddToWindowContainer(widget); -+ return widget; -+} -+ -+static GtkWidget* -+CreateNotebookWidget() -+{ -+ GtkWidget* widget = gtk_notebook_new(); -+ AddToWindowContainer(widget); -+ return widget; -+} +@@ -227,7 +439,6 @@ CreateMenuSeparatorWidget() + GtkWidget* widget = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), + widget); +- gtk_widget_realize(widget); + return widget; + } + +@@ -306,15 +517,6 @@ CreateVPanedWidget() + } static GtkWidget* - CreateWidget(WidgetNodeType aWidgetType) -@@ -262,10 +574,6 @@ CreateWidget(WidgetNodeType aWidgetType) - return CreateMenuBarWidget(); - case MOZ_GTK_MENUPOPUP: - return CreateMenuPopupWidget(); -- case MOZ_GTK_MENUBARITEM: -- return CreateMenuItemWidget(MOZ_GTK_MENUBAR); -- case MOZ_GTK_MENUITEM: -- return CreateMenuItemWidget(MOZ_GTK_MENUPOPUP); - case MOZ_GTK_MENUSEPARATOR: - return CreateMenuSeparatorWidget(); - case MOZ_GTK_EXPANDER: -@@ -294,6 +602,38 @@ CreateWidget(WidgetNodeType aWidgetType) +-CreateImageMenuItemWidget() +-{ +- GtkWidget* widget = gtk_image_menu_item_new(); +- gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), widget); +- gtk_widget_realize(widget); +- return widget; +-} +- +-static GtkWidget* + CreateScaleWidget(GtkOrientation aOrientation) + { + GtkWidget* widget = gtk_scale_new(aOrientation, nullptr); +@@ -380,8 +582,6 @@ CreateWidget(WidgetNodeType aWidgetType) + return CreateEntryWidget(); + case MOZ_GTK_SCROLLED_WINDOW: return CreateScrolledWindowWidget(); - case MOZ_GTK_TEXT_VIEW: - return CreateTextViewWidget(); -+ case MOZ_GTK_TREEVIEW: -+ return CreateTreeViewWidget(); -+ case MOZ_GTK_TREE_HEADER_CELL: -+ return CreateTreeHeaderCellWidget(); -+ case MOZ_GTK_TREE_HEADER_SORTARROW: -+ return CreateTreeHeaderSortArrowWidget(); -+ case MOZ_GTK_SPLITTER_HORIZONTAL: -+ return CreateHPanedWidget(); -+ case MOZ_GTK_SPLITTER_VERTICAL: -+ return CreateVPanedWidget(); -+ case MOZ_GTK_SCALE_HORIZONTAL: -+ return CreateScaleWidget(GTK_ORIENTATION_HORIZONTAL); -+ case MOZ_GTK_SCALE_VERTICAL: -+ return CreateScaleWidget(GTK_ORIENTATION_VERTICAL); -+ case MOZ_GTK_NOTEBOOK: -+ return CreateNotebookWidget(); +- case MOZ_GTK_TEXT_VIEW: +- return CreateTextViewWidget(); + case MOZ_GTK_TREEVIEW: + return CreateTreeViewWidget(); + case MOZ_GTK_TREE_HEADER_CELL: +@@ -392,14 +592,28 @@ CreateWidget(WidgetNodeType aWidgetType) + return CreateHPanedWidget(); + case MOZ_GTK_SPLITTER_VERTICAL: + return CreateVPanedWidget(); +- case MOZ_GTK_IMAGEMENUITEM: +- return CreateImageMenuItemWidget(); + case MOZ_GTK_SCALE_HORIZONTAL: + return CreateScaleWidget(GTK_ORIENTATION_HORIZONTAL); + case MOZ_GTK_SCALE_VERTICAL: + return CreateScaleWidget(GTK_ORIENTATION_VERTICAL); + case MOZ_GTK_NOTEBOOK: + return CreateNotebookWidget(); + case MOZ_GTK_COMBOBOX: + return CreateComboBoxWidget(); + case MOZ_GTK_COMBOBOX_BUTTON: @@ -3618,74 +2599,7 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 default: /* Not implemented */ return nullptr; -@@ -314,27 +654,53 @@ GetWidget(WidgetNodeType aWidgetType) - GtkStyleContext* - CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle) - { -- GtkWidgetPath* path = aParentStyle ? -- gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) : -- gtk_widget_path_new(); -- -- // Work around https://bugzilla.gnome.org/show_bug.cgi?id=767312 -- // which exists in GTK+ 3.20. -- gtk_widget_get_style_context(aWidget); -+ static auto sGtkWidgetClassGetCSSName = -+ reinterpret_cast -+ (dlsym(RTLD_DEFAULT, "gtk_widget_class_get_css_name")); -+ -+ GtkWidgetClass *widgetClass = GTK_WIDGET_GET_CLASS(aWidget); -+ const gchar* name = sGtkWidgetClassGetCSSName ? -+ sGtkWidgetClassGetCSSName(widgetClass) : nullptr; -+ -+ GtkStyleContext *context = -+ CreateCSSNode(name, aParentStyle, G_TYPE_FROM_CLASS(widgetClass)); -+ -+ // Classes are stored on the style context instead of the path so that any -+ // future gtk_style_context_save() will inherit classes on the head CSS -+ // node, in the same way as happens when called on a style context owned by -+ // a widget. -+ // -+ // Classes can be stored on a GtkCssNodeDeclaration and/or the path. -+ // gtk_style_context_save() reuses the GtkCssNodeDeclaration, and appends a -+ // new object to the path, without copying the classes from the old path -+ // head. The new head picks up classes from the GtkCssNodeDeclaration, but -+ // not the path. GtkWidgets store their classes on the -+ // GtkCssNodeDeclaration, so make sure to add classes there. -+ // -+ // Picking up classes from the style context also means that -+ // https://bugzilla.gnome.org/show_bug.cgi?id=767312, which can stop -+ // gtk_widget_path_append_for_widget() from finding classes in GTK 3.20, -+ // is not a problem. -+ GtkStyleContext* widgetStyle = gtk_widget_get_style_context(aWidget); -+ GList* classes = gtk_style_context_list_classes(widgetStyle); -+ for (GList* link = classes; link; link = link->next) { -+ gtk_style_context_add_class(context, static_cast(link->data)); -+ } -+ g_list_free(classes); - -- gtk_widget_path_append_for_widget(path, aWidget); - // Release any floating reference on aWidget. - g_object_ref_sink(aWidget); - g_object_unref(aWidget); - -- GtkStyleContext *context = gtk_style_context_new(); -- gtk_style_context_set_path(context, path); -- gtk_style_context_set_parent(context, aParentStyle); -- gtk_widget_path_unref(path); -- - return context; - } - -+static GtkStyleContext* -+CreateStyleForWidget(GtkWidget* aWidget, WidgetNodeType aParentType) -+{ -+ return CreateStyleForWidget(aWidget, GetWidgetRootStyle(aParentType)); -+} -+ - GtkStyleContext* - CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType) - { -@@ -342,13 +708,26 @@ CreateCSSNode(const char* aName, GtkStyl +@@ -474,9 +688,20 @@ CreateCSSNode(const char* aName, GtkStyl reinterpret_cast (dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name")); @@ -3709,64 +2623,48 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 gtk_widget_path_append_type(path, aType); -- (*sGtkWidgetPathIterSetObjectName)(path, -1, aName); -+ if (sGtkWidgetPathIterSetObjectName) { -+ (*sGtkWidgetPathIterSetObjectName)(path, -1, aName); -+ } - - GtkStyleContext *context = gtk_style_context_new(); - gtk_style_context_set_path(context, path); -@@ -358,6 +737,40 @@ CreateCSSNode(const char* aName, GtkStyl - return context; - } - -+// Return a style context matching that of the root CSS node of a widget. -+// This is used by all GTK versions. -+static GtkStyleContext* -+GetWidgetRootStyle(WidgetNodeType aNodeType) -+{ -+ GtkStyleContext* style = sStyleStorage[aNodeType]; -+ if (style) -+ return style; -+ -+ switch (aNodeType) { -+ case MOZ_GTK_MENUBARITEM: -+ style = CreateStyleForWidget(gtk_menu_item_new(), MOZ_GTK_MENUBAR); -+ break; -+ case MOZ_GTK_MENUITEM: -+ style = CreateStyleForWidget(gtk_menu_item_new(), MOZ_GTK_MENUPOPUP); -+ break; +@@ -508,13 +733,38 @@ GetWidgetRootStyle(WidgetNodeType aNodeT + case MOZ_GTK_MENUITEM: + style = CreateStyleForWidget(gtk_menu_item_new(), MOZ_GTK_MENUPOPUP); + break; +- case MOZ_GTK_CHECKMENUITEM_CONTAINER: + case MOZ_GTK_CHECKMENUITEM: -+ style = CreateStyleForWidget(gtk_check_menu_item_new(), MOZ_GTK_MENUPOPUP); -+ break; + style = CreateStyleForWidget(gtk_check_menu_item_new(), MOZ_GTK_MENUPOPUP); + break; +- case MOZ_GTK_RADIOMENUITEM_CONTAINER: + case MOZ_GTK_RADIOMENUITEM: -+ style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr), -+ MOZ_GTK_MENUPOPUP); + style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr), + MOZ_GTK_MENUPOPUP); + break; ++ case MOZ_GTK_TEXT_VIEW: ++ style = CreateStyleForWidget(gtk_text_view_new(), ++ MOZ_GTK_SCROLLED_WINDOW); + break; -+ default: -+ GtkWidget* widget = GetWidget(aNodeType); -+ MOZ_ASSERT(widget); -+ return gtk_widget_get_style_context(widget); -+ } -+ -+ MOZ_ASSERT(style); -+ sStyleStorage[aNodeType] = style; -+ return style; -+} -+ - static GtkStyleContext* - CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType) - { -@@ -367,7 +780,7 @@ CreateChildCSSNode(const char* aName, Wi - static GtkStyleContext* - GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass) - { -- GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType)); -+ GtkStyleContext* style = GetWidgetRootStyle(aWidgetType); - gtk_style_context_save(style); - MOZ_ASSERT(!sStyleContextNeedsRestore); - sStyleContextNeedsRestore = true; -@@ -408,6 +821,10 @@ GetCssNodeStyleInternal(WidgetNodeType a ++ case MOZ_GTK_TOOLTIP: ++ if (gtk_check_version(3, 20, 0) != nullptr) { ++ // The tooltip style class is added first in CreateTooltipWidget() ++ // and transfered to style in CreateStyleForWidget(). ++ GtkWidget* tooltipWindow = CreateTooltipWidget(); ++ style = CreateStyleForWidget(tooltipWindow, nullptr); ++ gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference. ++ } else { ++ // We create this from the path because GtkTooltipWindow is not public. ++ style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP); ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); ++ } ++ break; ++ case MOZ_GTK_TOOLTIP_BOX: ++ style = CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), ++ MOZ_GTK_TOOLTIP); ++ break; ++ case MOZ_GTK_TOOLTIP_BOX_LABEL: ++ style = CreateStyleForWidget(gtk_label_new(nullptr), ++ MOZ_GTK_TOOLTIP_BOX); ++ break; + default: + GtkWidget* widget = GetWidget(aNodeType); + MOZ_ASSERT(widget); +@@ -576,6 +826,10 @@ GetCssNodeStyleInternal(WidgetNodeType a style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER, MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL); break; @@ -3777,186 +2675,132 @@ diff -up firefox-50.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-50.0 case MOZ_GTK_RADIOBUTTON: style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO, MOZ_GTK_RADIOBUTTON_CONTAINER); -@@ -416,6 +833,14 @@ GetCssNodeStyleInternal(WidgetNodeType a +@@ -584,13 +838,13 @@ GetCssNodeStyleInternal(WidgetNodeType a style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, MOZ_GTK_CHECKBUTTON_CONTAINER); break; +- case MOZ_GTK_RADIOMENUITEM: + case MOZ_GTK_RADIOMENUITEM_INDICATOR: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO, + style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO, +- MOZ_GTK_RADIOMENUITEM_CONTAINER); + MOZ_GTK_RADIOMENUITEM); -+ break; + break; +- case MOZ_GTK_CHECKMENUITEM: + case MOZ_GTK_CHECKMENUITEM_INDICATOR: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, + style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, +- MOZ_GTK_CHECKMENUITEM_CONTAINER); + MOZ_GTK_CHECKMENUITEM); -+ break; + break; case MOZ_GTK_PROGRESS_TROUGH: /* Progress bar background (trough) */ - style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, -@@ -451,11 +876,77 @@ GetCssNodeStyleInternal(WidgetNodeType a - return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, - GTK_STYLE_CLASS_VIEW); +@@ -601,11 +855,6 @@ GetCssNodeStyleInternal(WidgetNodeType a + style = CreateChildCSSNode("progress", + MOZ_GTK_PROGRESS_TROUGH); + break; +- case MOZ_GTK_TOOLTIP: +- // We create this from the path because GtkTooltipWindow is not public. +- style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); +- break; + case MOZ_GTK_GRIPPER: + // TODO - create from CSS node + return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER, +@@ -622,10 +871,28 @@ GetCssNodeStyleInternal(WidgetNodeType a + // TODO - create from CSS node + return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, + GTK_STYLE_CLASS_FRAME); +- case MOZ_GTK_TEXT_VIEW: +- // TODO - create from CSS node +- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, +- GTK_STYLE_CLASS_VIEW); ++ case MOZ_GTK_TEXT_VIEW_TEXT: ++ case MOZ_GTK_RESIZER: ++ style = CreateChildCSSNode("text", MOZ_GTK_TEXT_VIEW); ++ if (aNodeType == MOZ_GTK_RESIZER) { ++ // The "grip" class provides the correct builtin icon from ++ // gtk_render_handle(). The icon is drawn with shaded variants of ++ // the background color, and so a transparent background would lead to ++ // a transparent resizer. gtk_render_handle() also uses the ++ // background color to draw a background, and so this style otherwise ++ // matches what is used in GtkTextView to match the background with ++ // textarea elements. ++ GdkRGBA color; ++ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, ++ &color); ++ if (color.alpha == 0.0) { ++ g_object_unref(style); ++ style = CreateStyleForWidget(gtk_text_view_new(), ++ MOZ_GTK_SCROLLED_WINDOW); ++ } ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); ++ } ++ break; case MOZ_GTK_FRAME_BORDER: -- return CreateChildCSSNode("border", MOZ_GTK_FRAME); -- default: -- // TODO - create style from style path -- GtkWidget* widget = GetWidget(aNodeType); -+ style = CreateChildCSSNode("border", MOZ_GTK_FRAME); -+ break; -+ case MOZ_GTK_TREEVIEW_VIEW: -+ // TODO - create from CSS node -+ return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW, -+ GTK_STYLE_CLASS_VIEW); -+ case MOZ_GTK_TREEVIEW_EXPANDER: -+ // TODO - create from CSS node -+ return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW, -+ GTK_STYLE_CLASS_EXPANDER); -+ case MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL: -+ style = CreateChildCSSNode("separator", -+ MOZ_GTK_SPLITTER_HORIZONTAL); -+ break; -+ case MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL: -+ style = CreateChildCSSNode("separator", -+ MOZ_GTK_SPLITTER_VERTICAL); -+ break; -+ case MOZ_GTK_SCALE_CONTENTS_HORIZONTAL: -+ style = CreateChildCSSNode("contents", -+ MOZ_GTK_SCALE_HORIZONTAL); -+ break; -+ case MOZ_GTK_SCALE_CONTENTS_VERTICAL: -+ style = CreateChildCSSNode("contents", -+ MOZ_GTK_SCALE_VERTICAL); -+ break; -+ case MOZ_GTK_SCALE_TROUGH_HORIZONTAL: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, -+ MOZ_GTK_SCALE_CONTENTS_HORIZONTAL); -+ break; -+ case MOZ_GTK_SCALE_TROUGH_VERTICAL: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, -+ MOZ_GTK_SCALE_CONTENTS_VERTICAL); -+ break; -+ case MOZ_GTK_SCALE_THUMB_HORIZONTAL: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER, -+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL); -+ break; -+ case MOZ_GTK_SCALE_THUMB_VERTICAL: -+ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER, -+ MOZ_GTK_SCALE_TROUGH_VERTICAL); -+ break; -+ case MOZ_GTK_TAB_TOP: -+ { -+ // TODO - create from CSS node -+ style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK, -+ GTK_STYLE_CLASS_TOP); -+ gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, -+ static_cast(0)); -+ return style; -+ } -+ case MOZ_GTK_TAB_BOTTOM: -+ { -+ // TODO - create from CSS node -+ style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK, -+ GTK_STYLE_CLASS_BOTTOM); -+ gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, -+ static_cast(0)); -+ return style; -+ } -+ case MOZ_GTK_NOTEBOOK: -+ case MOZ_GTK_NOTEBOOK_HEADER: -+ case MOZ_GTK_TABPANELS: -+ case MOZ_GTK_TAB_SCROLLARROW: -+ { -+ // TODO - create from CSS node -+ GtkWidget* widget = GetWidget(MOZ_GTK_NOTEBOOK); - return gtk_widget_get_style_context(widget); -+ } -+ default: -+ return GetWidgetRootStyle(aNodeType); - } - - MOZ_ASSERT(style, "missing style context for node type"); -@@ -486,6 +977,12 @@ GetWidgetStyleInternal(WidgetNodeType aN + style = CreateChildCSSNode("border", MOZ_GTK_FRAME); + break; +@@ -728,27 +995,20 @@ GetWidgetStyleInternal(WidgetNodeType aN case MOZ_GTK_CHECKBUTTON: return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER, GTK_STYLE_CLASS_CHECK); +- case MOZ_GTK_RADIOMENUITEM: +- return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM_CONTAINER, + case MOZ_GTK_RADIOMENUITEM_INDICATOR: + return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM, -+ GTK_STYLE_CLASS_RADIO); + GTK_STYLE_CLASS_RADIO); +- case MOZ_GTK_CHECKMENUITEM: +- return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM_CONTAINER, + case MOZ_GTK_CHECKMENUITEM_INDICATOR: + return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM, -+ GTK_STYLE_CLASS_CHECK); + GTK_STYLE_CLASS_CHECK); case MOZ_GTK_PROGRESS_TROUGH: return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR, GTK_STYLE_CLASS_TROUGH); -@@ -519,11 +1016,57 @@ GetWidgetStyleInternal(WidgetNodeType aN - return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, - GTK_STYLE_CLASS_VIEW); +- case MOZ_GTK_TOOLTIP: { +- GtkStyleContext* style = sStyleStorage[aNodeType]; +- if (style) +- return style; +- +- // The tooltip style class is added first in CreateTooltipWidget() so +- // that gtk_widget_path_append_for_widget() in CreateStyleForWidget() +- // will find it. +- GtkWidget* tooltipWindow = CreateTooltipWidget(); +- style = CreateStyleForWidget(tooltipWindow, nullptr); +- gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference. +- sStyleStorage[aNodeType] = style; ++ case MOZ_GTK_PROGRESS_CHUNK: { ++ GtkStyleContext* style = ++ GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR, ++ GTK_STYLE_CLASS_PROGRESSBAR); ++ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); + return style; + } + case MOZ_GTK_GRIPPER: +@@ -763,9 +1023,25 @@ GetWidgetStyleInternal(WidgetNodeType aN + case MOZ_GTK_SCROLLED_WINDOW: + return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, + GTK_STYLE_CLASS_FRAME); +- case MOZ_GTK_TEXT_VIEW: +- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, +- GTK_STYLE_CLASS_VIEW); ++ case MOZ_GTK_TEXT_VIEW_TEXT: ++ case MOZ_GTK_RESIZER: { ++ // GTK versions prior to 3.20 do not have the view class on the root ++ // node, but add this to determine the background for the text window. ++ GtkStyleContext* style = ++ GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, GTK_STYLE_CLASS_VIEW); ++ if (aNodeType == MOZ_GTK_RESIZER) { ++ // The "grip" class provides the correct builtin icon from ++ // gtk_render_handle(). The icon is drawn with shaded variants of ++ // the background color, and so a transparent background would lead to ++ // a transparent resizer. gtk_render_handle() also uses the ++ // background color to draw a background, and so this style otherwise ++ // matches MOZ_GTK_TEXT_VIEW_TEXT to match the background with ++ // textarea elements. GtkTextView creates a separate text window and ++ // so the background should not be transparent. ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); ++ } ++ return style; ++ } case MOZ_GTK_FRAME_BORDER: -- return GetWidgetStyleInternal(MOZ_GTK_FRAME); -- default: -- GtkWidget* widget = GetWidget(aNodeType); -- MOZ_ASSERT(widget); -+ return GetWidgetRootStyle(MOZ_GTK_FRAME); -+ case MOZ_GTK_TREEVIEW_VIEW: -+ return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW, -+ GTK_STYLE_CLASS_VIEW); -+ case MOZ_GTK_TREEVIEW_EXPANDER: -+ return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW, -+ GTK_STYLE_CLASS_EXPANDER); -+ case MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SPLITTER_HORIZONTAL, -+ GTK_STYLE_CLASS_PANE_SEPARATOR); -+ case MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SPLITTER_VERTICAL, -+ GTK_STYLE_CLASS_PANE_SEPARATOR); -+ case MOZ_GTK_SCALE_TROUGH_HORIZONTAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL, -+ GTK_STYLE_CLASS_TROUGH); -+ case MOZ_GTK_SCALE_TROUGH_VERTICAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SCALE_VERTICAL, -+ GTK_STYLE_CLASS_TROUGH); -+ case MOZ_GTK_SCALE_THUMB_HORIZONTAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL, -+ GTK_STYLE_CLASS_SLIDER); -+ case MOZ_GTK_SCALE_THUMB_VERTICAL: -+ return GetWidgetStyleWithClass(MOZ_GTK_SCALE_VERTICAL, -+ GTK_STYLE_CLASS_SLIDER); -+ case MOZ_GTK_TAB_TOP: -+ { -+ GtkStyleContext* style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK, -+ GTK_STYLE_CLASS_TOP); -+ gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, -+ static_cast(0)); -+ return style; -+ } -+ case MOZ_GTK_TAB_BOTTOM: -+ { -+ GtkStyleContext* style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK, -+ GTK_STYLE_CLASS_BOTTOM); -+ gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, -+ static_cast(0)); -+ return style; -+ } -+ case MOZ_GTK_NOTEBOOK: -+ case MOZ_GTK_NOTEBOOK_HEADER: -+ case MOZ_GTK_TABPANELS: -+ case MOZ_GTK_TAB_SCROLLARROW: -+ { -+ GtkWidget* widget = GetWidget(MOZ_GTK_NOTEBOOK); - return gtk_widget_get_style_context(widget); -+ } -+ default: -+ return GetWidgetRootStyle(aNodeType); - } - } - -diff -up firefox-50.0/widget/gtk/WidgetStyleCache.h.widget-rebase firefox-50.0/widget/gtk/WidgetStyleCache.h ---- firefox-50.0/widget/gtk/WidgetStyleCache.h.widget-rebase 2016-10-31 21:15:38.000000000 +0100 -+++ firefox-50.0/widget/gtk/WidgetStyleCache.h 2016-11-24 11:57:52.035064777 +0100 -@@ -28,7 +28,6 @@ GetWidget(WidgetNodeType aNodeType); - GtkStyleContext* - CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle); - --// CreateCSSNode is implemented for gtk >= 3.20 only. - GtkStyleContext* - CreateCSSNode(const char* aName, - GtkStyleContext* aParentStyle, + return GetWidgetRootStyle(MOZ_GTK_FRAME); + case MOZ_GTK_TREEVIEW_VIEW: