mozilla-gtk3_20.patch
branchfirefox46
changeset 909 c6717354928b
parent 908 b29b47737173
child 919 6838f0c032f8
equal deleted inserted replaced
901:eb9ebe3e2e6a 909:c6717354928b
       
     1 diff -up firefox-46.0/widget/gtk/gtk3drawing.c.gtk3-20 firefox-46.0/widget/gtk/gtk3drawing.c
       
     2 --- firefox-46.0/widget/gtk/gtk3drawing.c.gtk3-20	2016-04-22 02:37:27.000000000 +0200
       
     3 +++ firefox-46.0/widget/gtk/gtk3drawing.c	2016-04-25 14:56:19.006992927 +0200
       
     4 @@ -17,32 +17,79 @@
       
     5  
       
     6  #include <math.h>
       
     7  
       
     8 +#define MOZ_WIDGET_STYLES 4
       
     9 +
       
    10 +typedef struct {
       
    11 +    GtkWidget*            widget;
       
    12 +
       
    13 +    union {
       
    14 +        struct {
       
    15 +            GtkStyleContext*  style;
       
    16 +            GtkStyleContext*  styleSelection;
       
    17 +        } entry;
       
    18 +
       
    19 +        struct {
       
    20 +            GtkStyleContext*  style;
       
    21 +        } button;
       
    22 +
       
    23 +        struct {
       
    24 +            GtkStyleContext*  style;
       
    25 +            GtkStyleContext*  styleContents;
       
    26 +            GtkStyleContext*  styleTrough;
       
    27 +            GtkStyleContext*  styleSlider;
       
    28 +        } scroll;
       
    29 +
       
    30 +        struct {
       
    31 +            GtkStyleContext*  style;
       
    32 +            GtkStyleContext*  styleCheck;
       
    33 +            GtkStyleContext*  styleLabel;
       
    34 +        } check;
       
    35 +
       
    36 +        struct {
       
    37 +            GtkStyleContext*  style;
       
    38 +            GtkStyleContext*  styleTrough;
       
    39 +            GtkStyleContext*  styleProgress;
       
    40 +        } progress;
       
    41 +
       
    42 +        struct {
       
    43 +            GtkStyleContext*  style;
       
    44 +            GtkStyleContext*  styleEntry;
       
    45 +            GtkStyleContext*  styleButtonUp;
       
    46 +            GtkStyleContext*  styleButtonDown;
       
    47 +        } spin;
       
    48 +
       
    49 +        struct {
       
    50 +            GtkStyleContext*  style[MOZ_WIDGET_STYLES];
       
    51 +        } all;
       
    52 +    };
       
    53 +} MozGtkWidget;
       
    54 +
       
    55  static GtkWidget* gProtoWindow;
       
    56  static GtkWidget* gProtoLayout;
       
    57 -static GtkWidget* gButtonWidget;
       
    58 +static MozGtkWidget gButton;
       
    59  static GtkWidget* gToggleButtonWidget;
       
    60  static GtkWidget* gButtonArrowWidget;
       
    61 -static GtkWidget* gCheckboxWidget;
       
    62 -static GtkWidget* gRadiobuttonWidget;
       
    63 -static GtkWidget* gHorizScrollbarWidget;
       
    64 -static GtkWidget* gVertScrollbarWidget;
       
    65 -static GtkWidget* gSpinWidget;
       
    66 +static MozGtkWidget gCheckbox;
       
    67 +static MozGtkWidget gRadiobutton;
       
    68 +static MozGtkWidget gVertScrollbar;
       
    69 +static MozGtkWidget gHorizScrollbar;
       
    70 +static MozGtkWidget gSpin;
       
    71  static GtkWidget* gHScaleWidget;
       
    72  static GtkWidget* gVScaleWidget;
       
    73 -static GtkWidget* gEntryWidget;
       
    74 +static MozGtkWidget gEntry;
       
    75  static GtkWidget* gComboBoxWidget;
       
    76  static GtkWidget* gComboBoxButtonWidget;
       
    77  static GtkWidget* gComboBoxArrowWidget;
       
    78  static GtkWidget* gComboBoxSeparatorWidget;
       
    79  static GtkWidget* gComboBoxEntryWidget;
       
    80 -static GtkWidget* gComboBoxEntryTextareaWidget;
       
    81 +static MozGtkWidget gComboBoxEntryTextarea;
       
    82  static GtkWidget* gComboBoxEntryButtonWidget;
       
    83  static GtkWidget* gComboBoxEntryArrowWidget;
       
    84  static GtkWidget* gHandleBoxWidget;
       
    85  static GtkWidget* gToolbarWidget;
       
    86  static GtkWidget* gFrameWidget;
       
    87  static GtkWidget* gStatusbarWidget;
       
    88 -static GtkWidget* gProgressWidget;
       
    89 +static MozGtkWidget gProgressBar;
       
    90  static GtkWidget* gTabWidget;
       
    91  static GtkWidget* gTooltipWidget;
       
    92  static GtkWidget* gMenuBarWidget;
       
    93 @@ -78,6 +125,37 @@ static gboolean is_initialized;
       
    94  #define GTK_STATE_FLAG_CHECKED (1 << 11)
       
    95  #endif
       
    96  
       
    97 +void moz_gtk_widget_free(MozGtkWidget *aMozWidget)
       
    98 +{
       
    99 +    // This was removed as a child of gProtoWindow
       
   100 +    if (aMozWidget->widget) {
       
   101 +        aMozWidget->widget = NULL;
       
   102 +    }
       
   103 +
       
   104 +    for(int i = 0; i < MOZ_WIDGET_STYLES; i++) {
       
   105 +        if (aMozWidget->all.style[i]) {
       
   106 +            g_object_unref(aMozWidget->all.style[i]);
       
   107 +            aMozWidget->all.style[i] = NULL;
       
   108 +        }
       
   109 +    }
       
   110 +}
       
   111 +
       
   112 +// TODO - weak dep!! (dlsym)
       
   113 +#if GTK_CHECK_VERSION(3, 19, 2)
       
   114 +#define moz_gtk_path_set_class_name    gtk_widget_path_iter_set_object_name
       
   115 +#else
       
   116 +#define moz_gtk_path_set_class_name    gtk_widget_path_iter_add_class
       
   117 +#endif
       
   118 +//gtk_widget_path_iter_get_state
       
   119 +
       
   120 +static void
       
   121 +moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags,
       
   122 +                         GtkBorder *border);
       
   123 +
       
   124 +static void
       
   125 +moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags,
       
   126 +                          GtkBorder *padding);
       
   127 +
       
   128  static GtkStateFlags
       
   129  GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
       
   130  {
       
   131 @@ -97,6 +175,41 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
       
   132      return stateFlags;
       
   133  }
       
   134  
       
   135 +GtkStyleContext *
       
   136 +moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent)
       
   137 +{
       
   138 +  GtkWidgetPath *path;
       
   139 +  GtkStyleContext *context;
       
   140 +
       
   141 +  if (parent)
       
   142 +    path = gtk_widget_path_copy (gtk_style_context_get_path (parent));
       
   143 +  else
       
   144 +    path = gtk_widget_path_new ();
       
   145 +
       
   146 +  gtk_widget_path_append_type (path, node->type);
       
   147 +  if (node->name)
       
   148 +    moz_gtk_path_set_class_name(path, -1, node->name);
       
   149 +  if (node->class1)
       
   150 +    gtk_widget_path_iter_add_class(path, -1, node->class1);
       
   151 +  if (node->class2)
       
   152 +    gtk_widget_path_iter_add_class(path, -1, node->class2);
       
   153 +
       
   154 +  context = gtk_style_context_new ();
       
   155 +  gtk_style_context_set_path (context, path);
       
   156 +  gtk_style_context_set_parent (context, parent);
       
   157 +
       
   158 +  if(!gtk_check_version(3, 14, 0)) {
       
   159 +      /* Unfortunately, we have to explicitly set the state again here
       
   160 +       * for it to take effect
       
   161 +       */
       
   162 +      gtk_style_context_set_state (context, gtk_widget_path_iter_get_state (path, -1));
       
   163 +  }
       
   164 +
       
   165 +  gtk_widget_path_unref (path);
       
   166 +
       
   167 +  return context;
       
   168 +}
       
   169 +
       
   170  /* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
       
   171     that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
       
   172     things they may want to do. */
       
   173 @@ -141,9 +254,16 @@ setup_widget_prototype(GtkWidget* widget
       
   174  static gint
       
   175  ensure_button_widget()
       
   176  {
       
   177 -    if (!gButtonWidget) {
       
   178 -        gButtonWidget = gtk_button_new_with_label("M");
       
   179 -        setup_widget_prototype(gButtonWidget);
       
   180 +    if (!gButton.widget) {
       
   181 +        GtkCssNode path[] = { 
       
   182 +            { GTK_TYPE_BUTTON, "button", NULL, NULL }
       
   183 +        };
       
   184 +
       
   185 +        gButton.widget = gtk_button_new_with_label("M");
       
   186 +        setup_widget_prototype(gButton.widget);
       
   187 +        gtk_widget_show(gButton.widget);
       
   188 +
       
   189 +        gButton.button.style = moz_gtk_style_create(&path[0], NULL);
       
   190      }
       
   191      return MOZ_GTK_SUCCESS;
       
   192  }
       
   193 @@ -195,9 +315,21 @@ ensure_button_arrow_widget()
       
   194  static gint
       
   195  ensure_checkbox_widget()
       
   196  {
       
   197 -    if (!gCheckboxWidget) {
       
   198 -        gCheckboxWidget = gtk_check_button_new_with_label("M");
       
   199 -        setup_widget_prototype(gCheckboxWidget);
       
   200 +   if (!gCheckbox.widget) {
       
   201 +        GtkCssNode path[] = {
       
   202 +           { GTK_TYPE_TOGGLE_BUTTON, "checkbutton", NULL, NULL },
       
   203 +           { G_TYPE_NONE, "check", NULL, NULL },
       
   204 +           { G_TYPE_NONE, "label", NULL, NULL }
       
   205 +        };
       
   206 +
       
   207 +        gCheckbox.widget = gtk_check_button_new_with_label("M");
       
   208 +        setup_widget_prototype(gCheckbox.widget);
       
   209 +
       
   210 +        gCheckbox.check.style = moz_gtk_style_create(&path[0], NULL);
       
   211 +        gCheckbox.check.styleCheck = moz_gtk_style_create(&path[1],
       
   212 +                                       gCheckbox.check.style);
       
   213 +        gCheckbox.check.styleLabel = moz_gtk_style_create(&path[2],
       
   214 +                                       gCheckbox.check.style);
       
   215      }
       
   216      return MOZ_GTK_SUCCESS;
       
   217  }
       
   218 @@ -205,9 +337,21 @@ ensure_checkbox_widget()
       
   219  static gint
       
   220  ensure_radiobutton_widget()
       
   221  {
       
   222 -    if (!gRadiobuttonWidget) {
       
   223 -        gRadiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M");
       
   224 -        setup_widget_prototype(gRadiobuttonWidget);
       
   225 +    if (!gRadiobutton.widget) {
       
   226 +        GtkCssNode path[] = {
       
   227 +           { GTK_TYPE_TOGGLE_BUTTON, "radiobutton", NULL, NULL },
       
   228 +           { G_TYPE_NONE, "radio", NULL, NULL },
       
   229 +           { G_TYPE_NONE, "label", NULL, NULL }
       
   230 +        };
       
   231 +
       
   232 +        gRadiobutton.widget = gtk_radio_button_new_with_label(NULL, "M");
       
   233 +        setup_widget_prototype(gRadiobutton.widget);
       
   234 +
       
   235 +        gRadiobutton.check.style = moz_gtk_style_create(&path[0], NULL);
       
   236 +        gRadiobutton.check.styleCheck = moz_gtk_style_create(&path[1],
       
   237 +                                          gRadiobutton.check.style);
       
   238 +        gRadiobutton.check.styleLabel = moz_gtk_style_create(&path[2],
       
   239 +                                          gRadiobutton.check.style);
       
   240      }
       
   241      return MOZ_GTK_SUCCESS;
       
   242  }
       
   243 @@ -215,25 +359,62 @@ ensure_radiobutton_widget()
       
   244  static gint
       
   245  ensure_scrollbar_widget()
       
   246  {
       
   247 -    if (!gVertScrollbarWidget) {
       
   248 -        gVertScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
       
   249 -        setup_widget_prototype(gVertScrollbarWidget);
       
   250 -    }
       
   251 -    if (!gHorizScrollbarWidget) {
       
   252 -        gHorizScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
       
   253 -        setup_widget_prototype(gHorizScrollbarWidget);
       
   254 -    }
       
   255 +    if (!gVertScrollbar.widget && !gHorizScrollbar.widget) {
       
   256 +        GtkCssNode path[] = {
       
   257 +            { GTK_TYPE_SCROLLBAR, "scrollbar", "horizontal", "bottom"},
       
   258 +            { GTK_TYPE_SCROLLBAR, "scrollbar", "vertical", "right" },
       
   259 +            { G_TYPE_NONE, "contents", NULL, NULL },
       
   260 +            { G_TYPE_NONE, "trough", NULL, NULL },
       
   261 +            { G_TYPE_NONE, "slider", NULL, NULL }
       
   262 +        };
       
   263 +
       
   264 +        gHorizScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
       
   265 +        setup_widget_prototype(gHorizScrollbar.widget);
       
   266 +
       
   267 +        gHorizScrollbar.scroll.style = moz_gtk_style_create(path, NULL);
       
   268 +        gHorizScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, 
       
   269 +                                               gHorizScrollbar.scroll.style);
       
   270 +        gHorizScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, 
       
   271 +                                               gHorizScrollbar.scroll.styleContents);
       
   272 +        gHorizScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, 
       
   273 +                                               gHorizScrollbar.scroll.styleTrough);
       
   274 +
       
   275 +        gVertScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
       
   276 +        setup_widget_prototype(gVertScrollbar.widget);
       
   277 +
       
   278 +        gVertScrollbar.scroll.style = moz_gtk_style_create(path+1, NULL);
       
   279 +        gVertScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, 
       
   280 +                                              gVertScrollbar.scroll.style);
       
   281 +        gVertScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, 
       
   282 +                                              gVertScrollbar.scroll.styleContents);
       
   283 +        gVertScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, 
       
   284 +                                              gVertScrollbar.scroll.styleTrough);
       
   285 +
       
   286 +     }
       
   287      return MOZ_GTK_SUCCESS;
       
   288  }
       
   289  
       
   290  static gint
       
   291  ensure_spin_widget()
       
   292  {
       
   293 -  if (!gSpinWidget) {
       
   294 -    gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
       
   295 -    setup_widget_prototype(gSpinWidget);
       
   296 -  }
       
   297 -  return MOZ_GTK_SUCCESS;
       
   298 +    if (!gSpin.widget) {
       
   299 +        GtkCssNode path[] = {
       
   300 +            { GTK_TYPE_SPIN_BUTTON, "spinbutton", "horizontal", NULL },
       
   301 +            { GTK_TYPE_SPIN_BUTTON, "spinbutton", "vertical", NULL },
       
   302 +            { GTK_TYPE_ENTRY, "entry", NULL, NULL },
       
   303 +            { G_TYPE_NONE, "button", "up", NULL },
       
   304 +            { G_TYPE_NONE, "button", "down", NULL }
       
   305 +        };
       
   306 +
       
   307 +        gSpin.widget = gtk_spin_button_new(NULL, 1, 0);
       
   308 +        setup_widget_prototype(gSpin.widget);
       
   309 +
       
   310 +        gSpin.spin.style = moz_gtk_style_create(path, NULL);
       
   311 +        gSpin.spin.styleButtonUp = moz_gtk_style_create(path+3, gSpin.spin.style);
       
   312 +        gSpin.spin.styleButtonDown = moz_gtk_style_create(path+4, gSpin.spin.style);
       
   313 +        gSpin.spin.styleEntry = moz_gtk_style_create(path+2, gSpin.spin.style);
       
   314 +    }
       
   315 +    return MOZ_GTK_SUCCESS;
       
   316  }
       
   317  
       
   318  static gint
       
   319 @@ -253,9 +434,19 @@ ensure_scale_widget()
       
   320  static gint
       
   321  ensure_entry_widget()
       
   322  {
       
   323 -    if (!gEntryWidget) {
       
   324 -        gEntryWidget = gtk_entry_new();
       
   325 -        setup_widget_prototype(gEntryWidget);
       
   326 +    if (!gEntry.widget) {
       
   327 +        GtkCssNode path[] = { 
       
   328 +            { GTK_TYPE_ENTRY, "entry", NULL, NULL },
       
   329 +            { G_TYPE_NONE, "selection", NULL, NULL }
       
   330 +        };
       
   331 +
       
   332 +        gEntry.widget = gtk_entry_new();
       
   333 +        setup_widget_prototype(gEntry.widget);
       
   334 +        gtk_widget_show(gEntry.widget);
       
   335 +
       
   336 +        gEntry.entry.style = moz_gtk_style_create(&path[0], NULL);
       
   337 +        gEntry.entry.styleSelection = moz_gtk_style_create(&path[1], 
       
   338 +                                                           gEntry.entry.style);
       
   339      }
       
   340      return MOZ_GTK_SUCCESS;
       
   341  }
       
   342 @@ -387,9 +578,9 @@ moz_gtk_get_combo_box_entry_inner_widget
       
   343          g_object_add_weak_pointer(G_OBJECT(widget),
       
   344                                    (gpointer) &gComboBoxEntryButtonWidget);
       
   345      } else if (GTK_IS_ENTRY(widget)) {
       
   346 -        gComboBoxEntryTextareaWidget = widget;
       
   347 +        gComboBoxEntryTextarea.widget = widget;
       
   348          g_object_add_weak_pointer(G_OBJECT(widget),
       
   349 -                                  (gpointer) &gComboBoxEntryTextareaWidget);
       
   350 +                                  (gpointer) &gComboBoxEntryTextarea.widget);
       
   351      } else
       
   352          return;
       
   353      gtk_widget_realize(widget);
       
   354 @@ -411,7 +602,7 @@ ensure_combo_box_entry_widgets()
       
   355  {
       
   356      GtkWidget* buttonChild;
       
   357  
       
   358 -    if (gComboBoxEntryTextareaWidget &&
       
   359 +    if (gComboBoxEntryTextarea.widget &&
       
   360              gComboBoxEntryButtonWidget &&
       
   361              gComboBoxEntryArrowWidget)
       
   362          return MOZ_GTK_SUCCESS;
       
   363 @@ -427,9 +618,9 @@ ensure_combo_box_entry_widgets()
       
   364                           moz_gtk_get_combo_box_entry_inner_widgets,
       
   365                           NULL);
       
   366  
       
   367 -    if (!gComboBoxEntryTextareaWidget) {
       
   368 +    if (!gComboBoxEntryTextarea.widget) {
       
   369          ensure_entry_widget();
       
   370 -        gComboBoxEntryTextareaWidget = gEntryWidget;
       
   371 +        gComboBoxEntryTextarea.widget = gEntry.widget;
       
   372      }
       
   373  
       
   374      if (gComboBoxEntryButtonWidget) {
       
   375 @@ -530,9 +721,21 @@ ensure_tab_widget()
       
   376  static gint
       
   377  ensure_progress_widget()
       
   378  {
       
   379 -    if (!gProgressWidget) {
       
   380 -        gProgressWidget = gtk_progress_bar_new();
       
   381 -        setup_widget_prototype(gProgressWidget);
       
   382 +    if (!gProgressBar.widget) {
       
   383 +        GtkCssNode path[] = {
       
   384 +           { GTK_TYPE_LABEL, "progressbar", NULL, NULL },
       
   385 +           { G_TYPE_NONE, "trough", NULL, NULL },
       
   386 +           { G_TYPE_NONE, "progress", NULL, NULL },
       
   387 +        };
       
   388 +
       
   389 +        gProgressBar.widget = gtk_progress_bar_new();
       
   390 +        setup_widget_prototype(gProgressBar.widget);
       
   391 +
       
   392 +        gProgressBar.progress.style = moz_gtk_style_create(&path[0], NULL);
       
   393 +        gProgressBar.progress.styleTrough = moz_gtk_style_create(&path[1],
       
   394 +                                              gProgressBar.progress.style);
       
   395 +        gProgressBar.progress.styleProgress = moz_gtk_style_create(&path[2],
       
   396 +                                                gProgressBar.progress.styleTrough);
       
   397      }
       
   398      return MOZ_GTK_SUCCESS;
       
   399  }
       
   400 @@ -638,6 +841,11 @@ static gint
       
   401  ensure_check_menu_item_widget()
       
   402  {
       
   403      if (!gCheckMenuItemWidget) {
       
   404 +        GtkCssNode path[] = {
       
   405 +           { GTK_TYPE_CHECK_MENU_ITEM, "menuitem", NULL, NULL },
       
   406 +           { G_TYPE_NONE, "check", NULL, NULL }
       
   407 +        };
       
   408 +
       
   409          ensure_menu_popup_widget();
       
   410          gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
       
   411          gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
       
   412 @@ -752,7 +960,7 @@ moz_gtk_checkbox_get_metrics(gint* indic
       
   413  {
       
   414      ensure_checkbox_widget();
       
   415  
       
   416 -    gtk_widget_style_get (gCheckboxWidget,
       
   417 +    gtk_widget_style_get (gCheckbox.widget,
       
   418                            "indicator_size", indicator_size,
       
   419                            "indicator_spacing", indicator_spacing,
       
   420                            NULL);
       
   421 @@ -765,7 +973,7 @@ moz_gtk_radio_get_metrics(gint* indicato
       
   422  {
       
   423      ensure_radiobutton_widget();
       
   424  
       
   425 -    gtk_widget_style_get (gRadiobuttonWidget,
       
   426 +    gtk_widget_style_get (gRadiobutton.widget,
       
   427                            "indicator_size", indicator_size,
       
   428                            "indicator_spacing", indicator_spacing,
       
   429                            NULL);
       
   430 @@ -778,13 +986,12 @@ moz_gtk_get_focus_outline_size(gint* foc
       
   431  {
       
   432      GtkBorder border;
       
   433      GtkBorder padding;
       
   434 -    GtkStyleContext *style;
       
   435 +    GtkStyleContext* style = gEntry.entry.style;
       
   436  
       
   437      ensure_entry_widget();
       
   438 -    style = gtk_widget_get_style_context(gEntryWidget);
       
   439  
       
   440 -    gtk_style_context_get_border(style, 0, &border);
       
   441 -    gtk_style_context_get_padding(style, 0, &padding);
       
   442 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   443 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   444      *focus_h_width = border.left + padding.left;
       
   445      *focus_v_width = border.top + padding.top;
       
   446      return MOZ_GTK_SUCCESS;
       
   447 @@ -821,7 +1028,7 @@ moz_gtk_button_get_default_overflow(gint
       
   448      GtkBorder* default_outside_border;
       
   449  
       
   450      ensure_button_widget();
       
   451 -    gtk_widget_style_get(gButtonWidget,
       
   452 +    gtk_widget_style_get(gButton.widget,
       
   453                           "default-outside-border", &default_outside_border,
       
   454                           NULL);
       
   455  
       
   456 @@ -844,7 +1051,7 @@ moz_gtk_button_get_default_border(gint*
       
   457      GtkBorder* default_border;
       
   458  
       
   459      ensure_button_widget();
       
   460 -    gtk_widget_style_get(gButtonWidget,
       
   461 +    gtk_widget_style_get(gButton.widget,
       
   462                           "default-border", &default_border,
       
   463                           NULL);
       
   464  
       
   465 @@ -935,7 +1142,7 @@ moz_gtk_button_paint(cairo_t *cr, GdkRec
       
   466  
       
   467      if (state->focused) {
       
   468          GtkBorder border;
       
   469 -        gtk_style_context_get_border(style, state_flags, &border);
       
   470 +        moz_gtk_get_style_border(style, state_flags, &border);
       
   471          x += border.left;
       
   472          y += border.top;
       
   473          width -= (border.left + border.right);
       
   474 @@ -956,15 +1163,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   475      gint indicator_size, indicator_spacing;
       
   476      gint x, y, width, height;
       
   477      gint focus_x, focus_y, focus_width, focus_height;
       
   478 -    GtkWidget *w;
       
   479 -    GtkStyleContext *style;
       
   480 +    MozGtkWidget *w;
       
   481  
       
   482      if (isradio) {
       
   483          moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
       
   484 -        w = gRadiobuttonWidget;
       
   485 +        w = &gRadiobutton;
       
   486      } else {
       
   487          moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
       
   488 -        w = gCheckboxWidget;
       
   489 +        w = &gCheckbox;
       
   490      }
       
   491  
       
   492      // XXX we should assert rect->height >= indicator_size too
       
   493 @@ -983,11 +1189,9 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   494      focus_width = width + 2 * indicator_spacing;
       
   495      focus_height = height + 2 * indicator_spacing;
       
   496    
       
   497 -    style = gtk_widget_get_style_context(w);
       
   498 -
       
   499 -    gtk_widget_set_sensitive(w, !state->disabled);
       
   500 -    gtk_widget_set_direction(w, direction);
       
   501 -    gtk_style_context_save(style);
       
   502 +    gtk_widget_set_sensitive(w->widget, !state->disabled);
       
   503 +    gtk_widget_set_direction(w->widget, direction);
       
   504 +    gtk_style_context_save(w->check.styleCheck);
       
   505  
       
   506      if (selected)
       
   507          state_flags |= checkbox_check_state;
       
   508 @@ -995,13 +1199,15 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   509      if (inconsistent)
       
   510          state_flags |= GTK_STATE_FLAG_INCONSISTENT;
       
   511  
       
   512 -    gtk_style_context_set_state(style, state_flags);
       
   513 +    gtk_style_context_set_state(w->check.styleCheck, state_flags);
       
   514 +
       
   515 +    gtk_render_background(w->check.styleCheck, cr, x, y, width, height);
       
   516 +    gtk_render_frame(w->check.styleCheck, cr, x, y, width, height);
       
   517  
       
   518      if (isradio) {
       
   519 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
       
   520 -        gtk_render_option(style, cr, x, y, width, height);
       
   521 +        gtk_render_option(w->check.styleCheck, cr, x, y, width, height);
       
   522          if (state->focused) {
       
   523 -            gtk_render_focus(style, cr, focus_x, focus_y,
       
   524 +            gtk_render_focus(w->check.styleCheck, cr, focus_x, focus_y,
       
   525                              focus_width, focus_height);
       
   526          }
       
   527      }
       
   528 @@ -1010,15 +1216,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec
       
   529          * 'indeterminate' type on checkboxes. In GTK, the shadow type
       
   530          * must also be changed for the state to be drawn.
       
   531          */        
       
   532 -        gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
       
   533 -        gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), inconsistent);
       
   534 -        gtk_render_check(style, cr, x, y, width, height);        
       
   535 +        gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(w->widget), inconsistent);
       
   536 +        gtk_render_check(w->check.styleCheck, cr, x, y, width, height);
       
   537          if (state->focused) {
       
   538 -            gtk_render_focus(style, cr, 
       
   539 +            gtk_render_focus(w->check.styleCheck, cr,
       
   540                               focus_x, focus_y, focus_width, focus_height);
       
   541          }
       
   542      }
       
   543 -    gtk_style_context_restore(style);
       
   544 +    gtk_style_context_restore(w->check.styleCheck);
       
   545  
       
   546      return MOZ_GTK_SUCCESS;
       
   547  }
       
   548 @@ -1035,8 +1240,8 @@ calculate_button_inner_rect(GtkWidget* b
       
   549      style = gtk_widget_get_style_context(button);
       
   550  
       
   551      /* This mirrors gtkbutton's child positioning */
       
   552 -    gtk_style_context_get_border(style, 0, &border);
       
   553 -    gtk_style_context_get_padding(style, 0, &padding);
       
   554 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   555 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   556  
       
   557      inner_rect->x = rect->x + border.left + padding.left;
       
   558      inner_rect->y = rect->y + padding.top + border.top;
       
   559 @@ -1099,9 +1304,9 @@ moz_gtk_scrollbar_button_paint(cairo_t *
       
   560      ensure_scrollbar_widget();
       
   561  
       
   562      if (flags & MOZ_GTK_STEPPER_VERTICAL)
       
   563 -        scrollbar = gVertScrollbarWidget;
       
   564 +        scrollbar = gVertScrollbar.widget;
       
   565      else
       
   566 -        scrollbar = gHorizScrollbarWidget;
       
   567 +        scrollbar = gHorizScrollbar.widget;
       
   568  
       
   569      gtk_widget_set_direction(scrollbar, direction);
       
   570  
       
   571 @@ -1181,25 +1386,22 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW
       
   572                                 GtkTextDirection direction)
       
   573  {
       
   574      GtkStyleContext* style;
       
   575 -    GtkScrollbar *scrollbar;
       
   576  
       
   577      ensure_scrollbar_widget();
       
   578  
       
   579 -    if (widget ==  MOZ_GTK_SCROLLBAR_HORIZONTAL)
       
   580 -        scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
       
   581 -    else
       
   582 -        scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
       
   583 -
       
   584 -    gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
       
   585 -    
       
   586      if (flags & MOZ_GTK_TRACK_OPAQUE) {
       
   587          style = gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow));
       
   588          gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   589      }
       
   590  
       
   591 -    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
       
   592 -    gtk_style_context_save(style);
       
   593 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
       
   594 +     if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
       
   595 +        gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction);
       
   596 +        style = gHorizScrollbar.scroll.style;
       
   597 +    }
       
   598 +    else {
       
   599 +        gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction);
       
   600 +        style = gVertScrollbar.scroll.style;
       
   601 +    }
       
   602  
       
   603      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   604      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   605 @@ -1208,7 +1410,6 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW
       
   606          gtk_render_focus(style, cr,
       
   607                           rect->x, rect->y, rect->width, rect->height);
       
   608      }
       
   609 -    gtk_style_context_restore(style);
       
   610      return MOZ_GTK_SUCCESS;
       
   611  }
       
   612  
       
   613 @@ -1220,24 +1421,20 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi
       
   614  {
       
   615      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   616      GtkStyleContext* style;
       
   617 -    GtkScrollbar *scrollbar;
       
   618      GtkBorder margin;
       
   619  
       
   620      ensure_scrollbar_widget();
       
   621  
       
   622 -    if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL)
       
   623 -        scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
       
   624 -    else
       
   625 -        scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
       
   626 -
       
   627 -    gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
       
   628 -
       
   629 -    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
       
   630 -    gtk_style_context_save(style);
       
   631 +    if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) {
       
   632 +        style = gHorizScrollbar.scroll.styleSlider;
       
   633 +        gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction);
       
   634 +    }
       
   635 +    else {
       
   636 +        style = gVertScrollbar.scroll.styleSlider; 
       
   637 +        gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction);
       
   638 +    }
       
   639  
       
   640 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
       
   641      gtk_style_context_set_state(style, state_flags);
       
   642 -
       
   643      gtk_style_context_get_margin (style, state_flags, &margin);
       
   644  
       
   645      gtk_render_slider(style, cr,
       
   646 @@ -1248,8 +1445,6 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi
       
   647                       (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
       
   648                       GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
       
   649  
       
   650 -    gtk_style_context_restore(style);
       
   651 -
       
   652      return MOZ_GTK_SUCCESS;
       
   653  }
       
   654  
       
   655 @@ -1260,8 +1455,8 @@ moz_gtk_spin_paint(cairo_t *cr, GdkRecta
       
   656      GtkStyleContext* style;
       
   657  
       
   658      ensure_spin_widget();
       
   659 -    gtk_widget_set_direction(gSpinWidget, direction);
       
   660 -    style = gtk_widget_get_style_context(gSpinWidget);
       
   661 +    gtk_widget_set_direction(gSpin.widget, direction);
       
   662 +    style = gSpin.spin.style;
       
   663      gtk_style_context_save(style);
       
   664      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
       
   665      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   666 @@ -1280,11 +1475,10 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
       
   667      GtkStyleContext* style;
       
   668  
       
   669      ensure_spin_widget();
       
   670 -    style = gtk_widget_get_style_context(gSpinWidget);
       
   671 +    style = gSpin.spin.style;
       
   672      gtk_style_context_save(style);
       
   673 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
       
   674      gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
       
   675 -    gtk_widget_set_direction(gSpinWidget, direction);
       
   676 +    gtk_widget_set_direction(gSpin.widget, direction);
       
   677  
       
   678      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   679      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   680 @@ -1450,15 +1644,13 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec
       
   681  static gint
       
   682  moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
       
   683                      GtkWidgetState* state,
       
   684 -                    GtkWidget* widget, GtkTextDirection direction)
       
   685 +                    MozGtkWidget* w, GtkTextDirection direction)
       
   686  {
       
   687      gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
       
   688 -    GtkStyleContext* style;
       
   689      int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE
       
   690 +    GtkStyleContext* style = w->entry.style;
       
   691  
       
   692 -    gtk_widget_set_direction(widget, direction);
       
   693 -
       
   694 -    style = gtk_widget_get_style_context(widget);
       
   695 +    gtk_widget_set_direction(w->widget, direction);
       
   696  
       
   697      if (draw_focus_outline_only) {
       
   698          // Inflate the given 'rect' with the focus outline size.
       
   699 @@ -1478,10 +1670,9 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
       
   700       * textarea window uses gtk_paint_flat_box when exposed */
       
   701  
       
   702      /* This gets us a lovely greyish disabledish look */
       
   703 -    gtk_widget_set_sensitive(widget, !state->disabled);
       
   704 +    gtk_widget_set_sensitive(w->widget, !state->disabled);
       
   705  
       
   706      gtk_style_context_save(style);
       
   707 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_ENTRY);
       
   708    
       
   709      /* Now paint the shadow and focus border.
       
   710       * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad
       
   711 @@ -1531,7 +1722,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
       
   712      style = gtk_widget_get_style_context(gScrolledWindowWidget);
       
   713      gtk_style_context_save(style);
       
   714      gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);    
       
   715 -    gtk_style_context_get_border(style, state_flags, &border);
       
   716 +    moz_gtk_get_style_border(style, state_flags, &border);
       
   717      xthickness = border.left;
       
   718      ythickness = border.top;    
       
   719  
       
   720 @@ -1702,7 +1893,7 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk
       
   721          if (direction == GTK_TEXT_DIR_LTR) {
       
   722              GtkBorder padding;
       
   723              GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   724 -            gtk_style_context_get_padding(style, state_flags, &padding);
       
   725 +            moz_gtk_get_style_padding(style, state_flags, &padding);
       
   726              arrow_rect.x -= padding.left;
       
   727          }
       
   728          else
       
   729 @@ -1804,29 +1995,27 @@ moz_gtk_container_paint(cairo_t *cr, Gdk
       
   730                          gboolean isradio, GtkTextDirection direction)
       
   731  {
       
   732      GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
       
   733 -    GtkStyleContext* style;
       
   734 -    GtkWidget *widget;
       
   735 +    MozGtkWidget *widget;
       
   736  
       
   737      if (isradio) {
       
   738          ensure_radiobutton_widget();
       
   739 -        widget = gRadiobuttonWidget;
       
   740 +        widget = &gRadiobutton;
       
   741      } else {
       
   742          ensure_checkbox_widget();
       
   743 -        widget = gCheckboxWidget;
       
   744 +        widget = &gCheckbox;
       
   745      }
       
   746 -    gtk_widget_set_direction(widget, direction);
       
   747 +    gtk_widget_set_direction(widget->widget, direction);
       
   748  
       
   749 -    style = gtk_widget_get_style_context(widget);
       
   750 -    gtk_style_context_save(style);
       
   751 -    gtk_style_context_set_state(style, state_flags);
       
   752 +    gtk_style_context_save(widget->check.style);
       
   753 +    gtk_style_context_set_state(widget->check.style, state_flags);
       
   754    
       
   755      /* this is for drawing a prelight box */
       
   756      if (state_flags & GTK_STATE_FLAG_PRELIGHT) {
       
   757 -        gtk_render_background(style, cr,
       
   758 +        gtk_render_background(widget->check.style, cr,
       
   759                                rect->x, rect->y, rect->width, rect->height);
       
   760      }
       
   761    
       
   762 -    gtk_style_context_restore(style);
       
   763 +    gtk_style_context_restore(widget->check.style);
       
   764    
       
   765      return MOZ_GTK_SUCCESS;
       
   766  }
       
   767 @@ -1836,32 +2025,26 @@ moz_gtk_toggle_label_paint(cairo_t *cr,
       
   768                             GtkWidgetState* state, 
       
   769                             gboolean isradio, GtkTextDirection direction)
       
   770  {
       
   771 -    GtkStyleContext *style;
       
   772 -    GtkWidget *widget;
       
   773 +    MozGtkWidget *widget;
       
   774  
       
   775      if (!state->focused)
       
   776          return MOZ_GTK_SUCCESS;
       
   777  
       
   778      if (isradio) {
       
   779          ensure_radiobutton_widget();
       
   780 -        widget = gRadiobuttonWidget;
       
   781 +        widget = &gRadiobutton;
       
   782      } else {
       
   783          ensure_checkbox_widget();
       
   784 -        widget = gCheckboxWidget;
       
   785 +        widget = &gCheckbox;
       
   786      }
       
   787 -    style = gtk_widget_get_style_context(widget);
       
   788 -    gtk_style_context_save(style);
       
   789 -    if (isradio) {
       
   790 -      gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
       
   791 -    } else {
       
   792 -      gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
       
   793 -    }
       
   794 -    gtk_widget_set_direction(widget, direction);
       
   795 +    gtk_style_context_save(widget->check.styleLabel);
       
   796 +    gtk_widget_set_direction(widget->widget, direction);
       
   797  
       
   798 -    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
       
   799 -    gtk_render_focus(style, cr,
       
   800 +    gtk_style_context_set_state(widget->check.styleLabel, 
       
   801 +                                GetStateFlagsFromGtkWidgetState(state));
       
   802 +    gtk_render_focus(widget->check.styleLabel, cr,
       
   803                      rect->x, rect->y, rect->width, rect->height);
       
   804 -    gtk_style_context_restore(style);
       
   805 +    gtk_style_context_restore(widget->check.styleLabel);
       
   806  
       
   807      return MOZ_GTK_SUCCESS;
       
   808  }
       
   809 @@ -1922,7 +2105,7 @@ moz_gtk_toolbar_separator_paint(cairo_t
       
   810                            rect->height * (end_fraction - start_fraction));
       
   811      } else {
       
   812          GtkBorder padding;
       
   813 -        gtk_style_context_get_padding(style, 0, &padding);
       
   814 +        gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   815      
       
   816          paint_width = padding.left;
       
   817          if (paint_width > rect->width)
       
   818 @@ -2006,18 +2189,13 @@ static gint
       
   819  moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
       
   820                            GtkTextDirection direction)
       
   821  {
       
   822 -    GtkStyleContext* style;
       
   823 -
       
   824      ensure_progress_widget();
       
   825 -    gtk_widget_set_direction(gProgressWidget, direction);
       
   826 +    gtk_widget_set_direction(gProgressBar.widget, direction);
       
   827  
       
   828 -    style = gtk_widget_get_style_context(gProgressWidget);
       
   829 -    gtk_style_context_save(style);
       
   830 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
       
   831 -    
       
   832 -    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   833 -    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   834 -    gtk_style_context_restore(style);
       
   835 +    gtk_render_background(gProgressBar.progress.styleTrough, cr,
       
   836 +                          rect->x, rect->y, rect->width, rect->height);
       
   837 +    gtk_render_frame(gProgressBar.progress.styleTrough, cr,
       
   838 +                     rect->x, rect->y, rect->width, rect->height);
       
   839  
       
   840      return MOZ_GTK_SUCCESS;
       
   841  }
       
   842 @@ -2027,15 +2205,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
       
   843                               GtkTextDirection direction,
       
   844                               GtkThemeWidgetType widget)
       
   845  {
       
   846 -    GtkStyleContext* style;
       
   847 -
       
   848      ensure_progress_widget();
       
   849 -    gtk_widget_set_direction(gProgressWidget, direction);
       
   850 -
       
   851 -    style = gtk_widget_get_style_context(gProgressWidget);
       
   852 -    gtk_style_context_save(style);
       
   853 -    gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
       
   854 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
       
   855 +    gtk_widget_set_direction(gProgressBar.widget, direction);
       
   856  
       
   857      if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
       
   858          widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
       
   859 @@ -2074,12 +2245,14 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
       
   860      // gtk_render_activity was used to render progress chunks on GTK versions
       
   861      // before 3.13.7, see bug 1173907.
       
   862      if (!gtk_check_version(3, 13, 7)) {
       
   863 -      gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   864 -      gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   865 +      gtk_render_background(gProgressBar.progress.styleProgress, cr,
       
   866 +                            rect->x, rect->y, rect->width, rect->height);
       
   867 +      gtk_render_frame(gProgressBar.progress.styleProgress, cr,
       
   868 +                       rect->x, rect->y, rect->width, rect->height);
       
   869      } else {
       
   870 -      gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
       
   871 +      gtk_render_activity(gProgressBar.progress.styleProgress, cr,
       
   872 +                          rect->x, rect->y, rect->width, rect->height);
       
   873      }
       
   874 -    gtk_style_context_restore(style);
       
   875  
       
   876      return MOZ_GTK_SUCCESS;
       
   877  }
       
   878 @@ -2096,7 +2269,7 @@ moz_gtk_get_tab_thickness(void)
       
   879  
       
   880      style = gtk_widget_get_style_context(gTabWidget);
       
   881      gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK);
       
   882 -    gtk_style_context_get_border(style, 0, &border);
       
   883 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   884  
       
   885      if (border.top < 2)
       
   886          return 2; /* some themes don't set ythickness correctly */
       
   887 @@ -2292,7 +2465,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan
       
   888        gtk_style_context_save(style);
       
   889        moz_gtk_tab_prepare_style_context(style, flags);
       
   890  
       
   891 -      gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
       
   892 +      moz_gtk_get_style_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
       
   893  
       
   894        focusRect.x += padding.left;
       
   895        focusRect.width -= (padding.left + padding.right);
       
   896 @@ -2408,7 +2581,7 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t *
       
   897  }
       
   898  
       
   899  static gint
       
   900 -moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect,
       
   901 +moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state,
       
   902                         GtkTextDirection direction)
       
   903  {
       
   904      GtkStyleContext* style;
       
   905 @@ -2468,7 +2641,7 @@ moz_gtk_menu_separator_paint(cairo_t *cr
       
   906      border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
       
   907  
       
   908      style = gtk_widget_get_style_context(gMenuSeparatorWidget);
       
   909 -    gtk_style_context_get_padding(style, 0, &padding);
       
   910 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   911  
       
   912      x = rect->x + border_width;
       
   913      y = rect->y + border_width;
       
   914 @@ -2521,7 +2694,8 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
       
   915              item_widget = gMenuItemWidget;
       
   916          }
       
   917          style = gtk_widget_get_style_context(item_widget);
       
   918 -        gtk_style_context_save(style);
       
   919 +// TODO - FIX!
       
   920 +//        gtk_style_context_save(style);
       
   921  
       
   922          if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
       
   923              gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
       
   924 @@ -2540,7 +2714,7 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
       
   925  
       
   926          gtk_render_background(style, cr, x, y, w, h);
       
   927          gtk_render_frame(style, cr, x, y, w, h);
       
   928 -        gtk_style_context_restore(style);
       
   929 +//        gtk_style_context_restore(style);
       
   930      }
       
   931  
       
   932      return MOZ_GTK_SUCCESS;
       
   933 @@ -2556,7 +2730,10 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
       
   934  
       
   935      ensure_menu_item_widget();
       
   936      gtk_widget_set_direction(gMenuItemWidget, direction);
       
   937 -
       
   938 +/*
       
   939 +    state_flags |= (direction == GTK_TEXT_DIR_LTR) ? GTK_STATE_FLAG_DIR_LTR :
       
   940 +                                                     GTK_STATE_FLAG_DIR_RTL;
       
   941 +*/
       
   942      style = gtk_widget_get_style_context(gMenuItemWidget);
       
   943      gtk_style_context_save(style);
       
   944      gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
       
   945 @@ -2606,7 +2783,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
       
   946      }
       
   947      
       
   948      gtk_style_context_set_state(style, state_flags);
       
   949 -    gtk_style_context_get_padding(style, state_flags, &padding);
       
   950 +    moz_gtk_get_style_padding(style, state_flags, &padding);
       
   951  
       
   952      offset = gtk_container_get_border_width(GTK_CONTAINER(gCheckMenuItemWidget)) +
       
   953                                              padding.left + 2;
       
   954 @@ -2658,7 +2835,7 @@ moz_gtk_add_style_border(GtkStyleContext
       
   955  {
       
   956      GtkBorder border;
       
   957  
       
   958 -    gtk_style_context_get_border(style, 0, &border);
       
   959 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
   960  
       
   961      *left += border.left;
       
   962      *right += border.right;
       
   963 @@ -2667,12 +2844,22 @@ moz_gtk_add_style_border(GtkStyleContext
       
   964  }
       
   965  
       
   966  static void
       
   967 +moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags,
       
   968 +                         GtkBorder *border)
       
   969 +{
       
   970 +    gtk_style_context_save(style);
       
   971 +    gtk_style_context_set_state(style, state_flags);
       
   972 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), border);
       
   973 +    gtk_style_context_restore(style);
       
   974 +}
       
   975 +
       
   976 +static void
       
   977  moz_gtk_add_style_padding(GtkStyleContext* style,
       
   978                            gint* left, gint* top, gint* right, gint* bottom)
       
   979  {
       
   980      GtkBorder padding;
       
   981  
       
   982 -    gtk_style_context_get_padding(style, 0, &padding);
       
   983 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
   984  
       
   985      *left += padding.left;
       
   986      *right += padding.right;
       
   987 @@ -2680,6 +2867,16 @@ moz_gtk_add_style_padding(GtkStyleContex
       
   988      *bottom += padding.bottom;
       
   989  }
       
   990  
       
   991 +static void
       
   992 +moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags,
       
   993 +                          GtkBorder *padding)
       
   994 +{
       
   995 +    gtk_style_context_save(style);
       
   996 +    gtk_style_context_set_state(style, state_flags);
       
   997 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), padding);
       
   998 +    gtk_style_context_restore(style);
       
   999 +}
       
  1000 +
       
  1001  gint
       
  1002  moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
       
  1003                            gint* right, gint* bottom, GtkTextDirection direction,
       
  1004 @@ -2694,36 +2891,27 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1005      case MOZ_GTK_TOOLBAR_BUTTON:
       
  1006          {
       
  1007              ensure_button_widget();
       
  1008 -            style = gtk_widget_get_style_context(gButtonWidget);
       
  1009 -
       
  1010 -            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
       
  1011  
       
  1012 -            if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
       
  1013 -                gtk_style_context_save(style);
       
  1014 -                gtk_style_context_add_class(style, "image-button");
       
  1015 -            }
       
  1016 -              
       
  1017 -            moz_gtk_add_style_padding(style, left, top, right, bottom);
       
  1018 -                
       
  1019 -            if (widget == MOZ_GTK_TOOLBAR_BUTTON)
       
  1020 -                gtk_style_context_restore(style);
       
  1021 +            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButton.widget));
       
  1022 +            moz_gtk_add_style_padding(gButton.button.style, left, top, right, bottom);
       
  1023  
       
  1024              // XXX: Subtract 1 pixel from the border to account for the added
       
  1025              // -moz-focus-inner border (Bug 1228281).
       
  1026              *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
       
  1027 -            moz_gtk_add_style_border(style, left, top, right, bottom);
       
  1028 +            moz_gtk_add_style_border(gButton.button.style, left, top, right, bottom);
       
  1029 +
       
  1030              return MOZ_GTK_SUCCESS;
       
  1031          }
       
  1032      case MOZ_GTK_ENTRY:
       
  1033          {
       
  1034              ensure_entry_widget();
       
  1035 -            style = gtk_widget_get_style_context(gEntryWidget);
       
  1036  
       
  1037              // XXX: Subtract 1 pixel from the padding to account for the default
       
  1038              // padding in forms.css. See bug 1187385.
       
  1039              *left = *top = *right = *bottom = -1;
       
  1040 -            moz_gtk_add_style_padding(style, left, top, right, bottom);
       
  1041 -            moz_gtk_add_style_border(style, left, top, right, bottom);
       
  1042 +
       
  1043 +            moz_gtk_add_style_padding(gEntry.entry.style, left, top, right, bottom);
       
  1044 +            moz_gtk_add_style_border(gEntry.entry.style, left, top, right, bottom);
       
  1045  
       
  1046              return MOZ_GTK_SUCCESS;
       
  1047          }
       
  1048 @@ -2759,7 +2947,7 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1049          break;
       
  1050      case MOZ_GTK_DROPDOWN_ENTRY:
       
  1051          ensure_combo_box_entry_widgets();
       
  1052 -        w = gComboBoxEntryTextareaWidget;
       
  1053 +        w = gComboBoxEntryTextarea.widget;
       
  1054          break;
       
  1055      case MOZ_GTK_DROPDOWN_ARROW:
       
  1056          ensure_combo_box_entry_widgets();
       
  1057 @@ -2795,7 +2983,7 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1058  
       
  1059                  if (!wide_separators) {
       
  1060                      style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
       
  1061 -                    gtk_style_context_get_border(style, 0, &border);
       
  1062 +                    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
  1063                      separator_width = border.left;
       
  1064                  }
       
  1065              }
       
  1066 @@ -2814,14 +3002,17 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1067          w = gTabWidget;
       
  1068          break;
       
  1069      case MOZ_GTK_PROGRESSBAR:
       
  1070 -        ensure_progress_widget();
       
  1071 -        w = gProgressWidget;
       
  1072 -        break;
       
  1073 +        {
       
  1074 +            ensure_progress_widget();
       
  1075 +            moz_gtk_add_style_border(gProgressBar.progress.styleTrough,
       
  1076 +                                     left, top, right, bottom);
       
  1077 +            return MOZ_GTK_SUCCESS;
       
  1078 +        }
       
  1079      case MOZ_GTK_SPINBUTTON_ENTRY:
       
  1080      case MOZ_GTK_SPINBUTTON_UP:
       
  1081      case MOZ_GTK_SPINBUTTON_DOWN:
       
  1082          ensure_spin_widget();
       
  1083 -        w = gSpinWidget;
       
  1084 +        w = gSpin.widget;
       
  1085          break;
       
  1086      case MOZ_GTK_SCALE_HORIZONTAL:
       
  1087          ensure_scale_widget();
       
  1088 @@ -2840,12 +3031,13 @@ moz_gtk_get_widget_border(GtkThemeWidget
       
  1089          {
       
  1090              if (widget == MOZ_GTK_CHECKBUTTON_CONTAINER) {
       
  1091                  ensure_checkbox_widget();
       
  1092 -                w = gCheckboxWidget;
       
  1093 +                w = gCheckbox.widget;
       
  1094 +                style = gCheckbox.check.styleCheck;
       
  1095              } else {
       
  1096                  ensure_radiobutton_widget();
       
  1097 -                w = gRadiobuttonWidget;
       
  1098 +                w = gRadiobutton.widget;
       
  1099 +                style = gRadiobutton.check.styleCheck;
       
  1100              }
       
  1101 -            style = gtk_widget_get_style_context(w);
       
  1102  
       
  1103              *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w));
       
  1104              moz_gtk_add_style_border(style,
       
  1105 @@ -2978,6 +3170,32 @@ moz_gtk_get_combo_box_entry_button_size(
       
  1106  }
       
  1107  
       
  1108  gint
       
  1109 +moz_gtk_get_entry_height(gint* height)
       
  1110 +{
       
  1111 +    GtkRequisition requisition;
       
  1112 +    ensure_entry_widget();
       
  1113 +
       
  1114 +    gtk_widget_get_preferred_size(gEntry.widget, NULL, &requisition);
       
  1115 +    *height = requisition.height;
       
  1116 +
       
  1117 +    return MOZ_GTK_SUCCESS;
       
  1118 +}
       
  1119 +
       
  1120 +
       
  1121 +gint
       
  1122 +moz_gtk_get_button_height(gint* height)
       
  1123 +{
       
  1124 +    GtkRequisition requisition;
       
  1125 +    ensure_entry_widget();
       
  1126 +
       
  1127 +    gtk_widget_get_preferred_size(gButton.widget, NULL, &requisition);
       
  1128 +    *height = requisition.height;
       
  1129 +
       
  1130 +    return MOZ_GTK_SUCCESS;
       
  1131 +}
       
  1132 +
       
  1133 +
       
  1134 +gint
       
  1135  moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height)
       
  1136  {
       
  1137      gint arrow_size;
       
  1138 @@ -3030,7 +3248,7 @@ moz_gtk_get_toolbar_separator_width(gint
       
  1139                           "separator-width", &separator_width,
       
  1140                           NULL);
       
  1141      /* Just in case... */
       
  1142 -    gtk_style_context_get_border(style, 0, &border);
       
  1143 +    gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
       
  1144      *size = MAX(*size, (wide_separators ? separator_width : border.left));
       
  1145      return MOZ_GTK_SUCCESS;
       
  1146  }
       
  1147 @@ -3072,7 +3290,7 @@ moz_gtk_get_menu_separator_height(gint *
       
  1148      border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
       
  1149  
       
  1150      style = gtk_widget_get_style_context(gMenuSeparatorWidget);
       
  1151 -    gtk_style_context_get_padding(style, 0, &padding);
       
  1152 +    gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
       
  1153  
       
  1154      gtk_style_context_save(style);
       
  1155      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR);
       
  1156 @@ -3130,15 +3348,21 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro
       
  1157  {
       
  1158      ensure_scrollbar_widget();
       
  1159  
       
  1160 -    gtk_widget_style_get (gHorizScrollbarWidget,
       
  1161 +    gtk_widget_style_get (gHorizScrollbar.widget,
       
  1162                            "slider_width", &metrics->slider_width,
       
  1163                            "trough_border", &metrics->trough_border,
       
  1164                            "stepper_size", &metrics->stepper_size,
       
  1165                            "stepper_spacing", &metrics->stepper_spacing,
       
  1166                            NULL);
       
  1167  
       
  1168 -    metrics->min_slider_size = 
       
  1169 -        gtk_range_get_min_slider_size(GTK_RANGE(gHorizScrollbarWidget));
       
  1170 +    if (!gtk_check_version(3,19,7)) {
       
  1171 +        gtk_style_context_get(gVertScrollbar.scroll.styleSlider, 
       
  1172 +                              gtk_style_context_get_state(gVertScrollbar.scroll.styleSlider), 
       
  1173 +                              "min-height", &metrics->min_slider_size, NULL);
       
  1174 +    } else {
       
  1175 +        metrics->min_slider_size = 
       
  1176 +            gtk_range_get_min_slider_size(GTK_RANGE(gVertScrollbar.widget));
       
  1177 +    }
       
  1178  
       
  1179      return MOZ_GTK_SUCCESS;
       
  1180  }
       
  1181 @@ -3163,7 +3387,7 @@ moz_gtk_images_in_buttons()
       
  1182      GtkSettings* settings;
       
  1183  
       
  1184      ensure_button_widget();
       
  1185 -    settings = gtk_widget_get_settings(gButtonWidget);
       
  1186 +    settings = gtk_widget_get_settings(gButton.widget);
       
  1187  
       
  1188      g_object_get(settings, "gtk-button-images", &result, NULL);
       
  1189      return result;
       
  1190 @@ -3191,7 +3415,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
       
  1191          }
       
  1192          ensure_button_widget();
       
  1193          return moz_gtk_button_paint(cr, rect, state,
       
  1194 -                                    (GtkReliefStyle) flags, gButtonWidget,
       
  1195 +                                    (GtkReliefStyle) flags, gButton.widget,
       
  1196                                      direction);
       
  1197          break;
       
  1198      case MOZ_GTK_CHECKBUTTON:
       
  1199 @@ -3241,7 +3465,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
       
  1200      case MOZ_GTK_SPINBUTTON_ENTRY:
       
  1201          ensure_spin_widget();
       
  1202          return moz_gtk_entry_paint(cr, rect, state,
       
  1203 -                                   gSpinWidget, direction);
       
  1204 +                                   &gSpin, direction);
       
  1205          break;
       
  1206      case MOZ_GTK_GRIPPER:
       
  1207          return moz_gtk_gripper_paint(cr, rect, state,
       
  1208 @@ -3268,7 +3492,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
       
  1209      case MOZ_GTK_ENTRY:
       
  1210          ensure_entry_widget();
       
  1211          return moz_gtk_entry_paint(cr, rect, state,
       
  1212 -                                   gEntryWidget, direction);
       
  1213 +                                   &gEntry, direction);
       
  1214          break;
       
  1215      case MOZ_GTK_DROPDOWN:
       
  1216          return moz_gtk_combo_box_paint(cr, rect, state, direction);
       
  1217 @@ -3280,7 +3504,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
       
  1218      case MOZ_GTK_DROPDOWN_ENTRY:
       
  1219          ensure_combo_box_entry_widgets();
       
  1220          return moz_gtk_entry_paint(cr, rect, state,
       
  1221 -                                   gComboBoxEntryTextareaWidget, direction);
       
  1222 +                                   &gComboBoxEntryTextarea, direction);
       
  1223          break;
       
  1224      case MOZ_GTK_CHECKBUTTON_CONTAINER:
       
  1225      case MOZ_GTK_RADIOBUTTON_CONTAINER:
       
  1226 @@ -3332,7 +3556,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType
       
  1227                                                (GtkArrowType) flags, direction);
       
  1228          break;
       
  1229      case MOZ_GTK_MENUBAR:
       
  1230 -        return moz_gtk_menu_bar_paint(cr, rect, direction);
       
  1231 +        return moz_gtk_menu_bar_paint(cr, rect, state, direction);
       
  1232          break;
       
  1233      case MOZ_GTK_MENUPOPUP:
       
  1234          return moz_gtk_menu_popup_paint(cr, rect, direction);
       
  1235 @@ -3383,7 +3607,7 @@ GtkWidget* moz_gtk_get_scrollbar_widget(
       
  1236  {
       
  1237      MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()");
       
  1238      ensure_scrollbar_widget();
       
  1239 -    return gHorizScrollbarWidget;
       
  1240 +    return gVertScrollbar.widget;
       
  1241  }
       
  1242  
       
  1243  gboolean moz_gtk_has_scrollbar_buttons(void)
       
  1244 @@ -3391,7 +3615,7 @@ gboolean moz_gtk_has_scrollbar_buttons(v
       
  1245      gboolean backward, forward, secondary_backward, secondary_forward;
       
  1246      MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()");
       
  1247      ensure_scrollbar_widget();
       
  1248 -    gtk_widget_style_get (gHorizScrollbarWidget,
       
  1249 +    gtk_widget_style_get (gHorizScrollbar.widget,
       
  1250                            "has-backward-stepper", &backward,
       
  1251                            "has-forward-stepper", &forward,
       
  1252                            "has-secondary-backward-stepper", &secondary_backward,
       
  1253 @@ -3415,17 +3639,19 @@ moz_gtk_shutdown()
       
  1254  
       
  1255      gProtoWindow = NULL;
       
  1256      gProtoLayout = NULL;
       
  1257 -    gButtonWidget = NULL;
       
  1258 +
       
  1259 +    // MozWidgets
       
  1260 +    moz_gtk_widget_free(&gButton);
       
  1261      gToggleButtonWidget = NULL;
       
  1262      gButtonArrowWidget = NULL;
       
  1263 -    gCheckboxWidget = NULL;
       
  1264 -    gRadiobuttonWidget = NULL;
       
  1265 -    gHorizScrollbarWidget = NULL;
       
  1266 -    gVertScrollbarWidget = NULL;
       
  1267 -    gSpinWidget = NULL;
       
  1268 +    moz_gtk_widget_free(&gCheckbox);
       
  1269 +    moz_gtk_widget_free(&gRadiobutton);
       
  1270 +    moz_gtk_widget_free(&gHorizScrollbar);
       
  1271 +    moz_gtk_widget_free(&gVertScrollbar);
       
  1272 +    moz_gtk_widget_free(&gSpin);
       
  1273      gHScaleWidget = NULL;
       
  1274      gVScaleWidget = NULL;
       
  1275 -    gEntryWidget = NULL;
       
  1276 +    moz_gtk_widget_free(&gEntry);
       
  1277      gComboBoxWidget = NULL;
       
  1278      gComboBoxButtonWidget = NULL;
       
  1279      gComboBoxSeparatorWidget = NULL;
       
  1280 @@ -3433,12 +3659,12 @@ moz_gtk_shutdown()
       
  1281      gComboBoxEntryWidget = NULL;
       
  1282      gComboBoxEntryButtonWidget = NULL;
       
  1283      gComboBoxEntryArrowWidget = NULL;
       
  1284 -    gComboBoxEntryTextareaWidget = NULL;
       
  1285 +    moz_gtk_widget_free(&gComboBoxEntryTextarea);
       
  1286      gHandleBoxWidget = NULL;
       
  1287      gToolbarWidget = NULL;
       
  1288      gStatusbarWidget = NULL;
       
  1289      gFrameWidget = NULL;
       
  1290 -    gProgressWidget = NULL;
       
  1291 +    moz_gtk_widget_free(&gProgressBar);
       
  1292      gTabWidget = NULL;
       
  1293      gTooltipWidget = NULL;
       
  1294      gMenuBarWidget = NULL;
       
  1295 diff -up firefox-46.0/widget/gtk/gtkdrawing.h.gtk3-20 firefox-46.0/widget/gtk/gtkdrawing.h
       
  1296 --- firefox-46.0/widget/gtk/gtkdrawing.h.gtk3-20	2016-04-22 02:37:27.000000000 +0200
       
  1297 +++ firefox-46.0/widget/gtk/gtkdrawing.h	2016-04-25 14:42:42.000000000 +0200
       
  1298 @@ -67,6 +67,13 @@ typedef enum {
       
  1299    MOZ_GTK_TAB_SELECTED        = 1 << 10
       
  1300  } GtkTabFlags;
       
  1301  
       
  1302 +typedef struct {
       
  1303 +  GType type;
       
  1304 +  const gchar *name;
       
  1305 +  const gchar *class1;
       
  1306 +  const gchar *class2;
       
  1307 +} GtkCssNode;
       
  1308 +
       
  1309  /** flags for menuitems **/
       
  1310  typedef enum {
       
  1311    /* menuitem is part of the menubar */
       
  1312 @@ -396,6 +403,9 @@ void
       
  1313  moz_gtk_get_arrow_size(GtkThemeWidgetType widgetType,
       
  1314                         gint* width, gint* height);
       
  1315  
       
  1316 +gint moz_gtk_get_entry_height(gint* height);
       
  1317 +gint moz_gtk_get_button_height(gint* height);
       
  1318 +
       
  1319  /**
       
  1320   * Get the desired size of a toolbar separator
       
  1321   * size:    [OUT] the desired width
       
  1322 @@ -466,6 +476,12 @@ gboolean moz_gtk_images_in_buttons(void)
       
  1323   */
       
  1324  gboolean moz_gtk_has_scrollbar_buttons(void);
       
  1325  
       
  1326 +
       
  1327 +GtkStyleContext *
       
  1328 +moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent);
       
  1329 +
       
  1330 +
       
  1331 +
       
  1332  #ifdef __cplusplus
       
  1333  }
       
  1334  #endif /* __cplusplus */
       
  1335 diff -up firefox-46.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 firefox-46.0/widget/gtk/mozgtk/mozgtk.c
       
  1336 --- firefox-46.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20	2016-04-22 02:37:27.000000000 +0200
       
  1337 +++ firefox-46.0/widget/gtk/mozgtk/mozgtk.c	2016-04-25 14:46:15.299592716 +0200
       
  1338 @@ -504,6 +504,11 @@ STUB(gtk_window_set_type_hint)
       
  1339  STUB(gtk_window_set_wmclass)
       
  1340  STUB(gtk_window_unfullscreen)
       
  1341  STUB(gtk_window_unmaximize)
       
  1342 +STUB(gtk_widget_get_preferred_height_and_baseline_for_width)
       
  1343 +STUB(gtk_entry_get_text_area)
       
  1344 +STUB(gtk_check_menu_item_get_type)
       
  1345 +STUB(gtk_spin_button_get_type)
       
  1346 +STUB(gtk_button_get_type)
       
  1347  #endif
       
  1348  
       
  1349  #ifdef GTK3_SYMBOLS
       
  1350 @@ -581,6 +586,13 @@ STUB(gtk_color_chooser_get_type)
       
  1351  STUB(gtk_color_chooser_set_rgba)
       
  1352  STUB(gtk_color_chooser_get_rgba)
       
  1353  STUB(gtk_color_chooser_set_use_alpha)
       
  1354 +STUB(gtk_style_context_get_path)
       
  1355 +STUB(gtk_widget_path_copy)
       
  1356 +STUB(gtk_widget_path_iter_set_object_name)
       
  1357 +STUB(gtk_widget_path_iter_add_class)
       
  1358 +STUB(gtk_widget_path_iter_get_state)
       
  1359 +STUB(gtk_style_context_set_parent)
       
  1360 +STUB(gtk_widget_path_unref)
       
  1361  #endif
       
  1362  
       
  1363  #ifdef GTK2_SYMBOLS
       
  1364 diff -up firefox-46.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-46.0/widget/gtk/nsLookAndFeel.cpp
       
  1365 --- firefox-46.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20	2016-04-22 02:37:27.000000000 +0200
       
  1366 +++ firefox-46.0/widget/gtk/nsLookAndFeel.cpp	2016-04-25 14:18:25.000000000 +0200
       
  1367 @@ -353,14 +353,18 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       
  1368      case eColorID_activeborder:
       
  1369          // active window border
       
  1370          gtk_style_context_get_border_color(mBackgroundStyle, 
       
  1371 -                                           GTK_STATE_FLAG_NORMAL, &gdk_color);
       
  1372 +                                           gtk_style_context_get_state(mBackgroundStyle), 
       
  1373 +                                           &gdk_color);
       
  1374          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1375          break;
       
  1376      case eColorID_inactiveborder:
       
  1377          // inactive window border
       
  1378 +        gtk_style_context_save(mBackgroundStyle);
       
  1379 +        gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE);
       
  1380          gtk_style_context_get_border_color(mBackgroundStyle, 
       
  1381 -                                           GTK_STATE_FLAG_INSENSITIVE, 
       
  1382 +                                           gtk_style_context_get_state(mBackgroundStyle), 
       
  1383                                             &gdk_color);
       
  1384 +        gtk_style_context_restore(mBackgroundStyle);
       
  1385          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1386          break;
       
  1387      case eColorID_graytext: // disabled text in windows, menus, etc.
       
  1388 @@ -369,9 +373,12 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       
  1389          break;
       
  1390      case eColorID_inactivecaption:
       
  1391          // inactive window caption
       
  1392 +        gtk_style_context_save(mBackgroundStyle);
       
  1393 +        gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE);
       
  1394          gtk_style_context_get_background_color(mBackgroundStyle, 
       
  1395 -                                               GTK_STATE_FLAG_INSENSITIVE, 
       
  1396 +                                               gtk_style_context_get_state(mBackgroundStyle), 
       
  1397                                                 &gdk_color);
       
  1398 +        gtk_style_context_restore(mBackgroundStyle);
       
  1399          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1400          break;
       
  1401  #endif
       
  1402 @@ -497,13 +504,17 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       
  1403      case eColorID__moz_buttondefault:
       
  1404        // default button border color
       
  1405          gtk_style_context_get_border_color(mButtonStyle, 
       
  1406 -                                           GTK_STATE_FLAG_NORMAL, &gdk_color);
       
  1407 +                                           gtk_style_context_get_state(mButtonStyle),
       
  1408 +                                           &gdk_color);
       
  1409          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1410          break;
       
  1411      case eColorID__moz_buttonhoverface:
       
  1412 +        gtk_style_context_save(mButtonStyle);
       
  1413 +        gtk_style_context_set_state(mButtonStyle, GTK_STATE_FLAG_PRELIGHT);
       
  1414          gtk_style_context_get_background_color(mButtonStyle, 
       
  1415 -                                               GTK_STATE_FLAG_PRELIGHT, 
       
  1416 +                                               gtk_style_context_get_state(mButtonStyle), 
       
  1417                                                 &gdk_color);
       
  1418 +        gtk_style_context_restore(mButtonStyle);
       
  1419          aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
       
  1420          break;
       
  1421      case eColorID__moz_buttonhovertext:
       
  1422 @@ -1110,7 +1121,7 @@ nsLookAndFeel::Init()
       
  1423      style = create_context(path);
       
  1424      gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
       
  1425      gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
       
  1426 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1427 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1428      sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
       
  1429      g_object_unref(style);
       
  1430  
       
  1431 @@ -1118,18 +1129,18 @@ nsLookAndFeel::Init()
       
  1432      style = create_context(path);
       
  1433      gtk_style_context_save(style);
       
  1434      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       
  1435 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1436 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1437      sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1438 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1439 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1440      sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
       
  1441      gtk_style_context_restore(style);
       
  1442  
       
  1443      // tooltip foreground and background
       
  1444      gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
       
  1445      gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       
  1446 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1447 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1448      sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1449 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1450 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1451      sInfoText = GDK_RGBA_TO_NS_RGBA(color);
       
  1452      g_object_unref(style);
       
  1453  
       
  1454 @@ -1144,20 +1155,26 @@ nsLookAndFeel::Init()
       
  1455      gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
       
  1456  
       
  1457      style = gtk_widget_get_style_context(accel_label);
       
  1458 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1459 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1460      sMenuText = GDK_RGBA_TO_NS_RGBA(color);
       
  1461 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color);
       
  1462 +    gtk_style_context_save(style);
       
  1463 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_INSENSITIVE);
       
  1464 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1465      sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
       
  1466 +    gtk_style_context_restore(style);
       
  1467  
       
  1468      style = gtk_widget_get_style_context(menu);
       
  1469 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1470 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1471      sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1472  
       
  1473      style = gtk_widget_get_style_context(menuitem);
       
  1474 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
       
  1475 +    gtk_style_context_save(style);
       
  1476 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
       
  1477 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1478      sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
       
  1479 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
       
  1480 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1481      sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
       
  1482 +    gtk_style_context_restore(style);
       
  1483  
       
  1484      g_object_unref(menu);
       
  1485  #endif
       
  1486 @@ -1266,44 +1283,54 @@ nsLookAndFeel::Init()
       
  1487              GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]);
       
  1488      }
       
  1489  #else
       
  1490 +    GtkCssNode labelPath[] = {
       
  1491 +       { GTK_TYPE_LABEL, "label", "view", NULL },
       
  1492 +       { G_TYPE_NONE, "selection", NULL, NULL }
       
  1493 +    };
       
  1494 +
       
  1495 +    GtkStyleContext *styleLabel;
       
  1496 +    GtkStyleContext *styleSelection;
       
  1497 +    GtkBorder padding;
       
  1498 +
       
  1499      // Text colors
       
  1500 -    style = gtk_widget_get_style_context(textView);
       
  1501 -    gtk_style_context_save(style);
       
  1502 -    gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
       
  1503 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1504 +    styleLabel = moz_gtk_style_create(labelPath, NULL);
       
  1505 +    styleSelection = moz_gtk_style_create(labelPath+1, styleLabel);
       
  1506 +
       
  1507 +    gtk_style_context_get_background_color(styleLabel, gtk_style_context_get_state(styleLabel), &color);
       
  1508      sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1509 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1510 +    gtk_style_context_get_color(styleLabel, gtk_style_context_get_state(styleLabel), &color);
       
  1511      sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
       
  1512  
       
  1513      // Selected text and background
       
  1514 -    gtk_style_context_get_background_color(style,
       
  1515 -        static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
       
  1516 -        &color);
       
  1517 +    gtk_style_context_get_background_color(styleSelection, gtk_style_context_get_state(styleSelection), &color);
       
  1518      sTextSelectedBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1519 -    gtk_style_context_get_color(style,
       
  1520 -        static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
       
  1521 -        &color);
       
  1522 +    gtk_style_context_get_color(styleSelection, gtk_style_context_get_state(styleSelection), &color);
       
  1523      sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
       
  1524 -    gtk_style_context_restore(style);
       
  1525  
       
  1526      // Button text, background, border
       
  1527      style = gtk_widget_get_style_context(label);
       
  1528 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1529 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1530      sButtonText = GDK_RGBA_TO_NS_RGBA(color);
       
  1531 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
       
  1532 +    gtk_style_context_save(style);
       
  1533 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
       
  1534 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1535      sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
       
  1536 +    gtk_style_context_restore(style);
       
  1537  
       
  1538      // Combobox text color
       
  1539      style = gtk_widget_get_style_context(comboboxLabel);
       
  1540 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1541 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1542      sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
       
  1543  
       
  1544      // Menubar text and hover text colors    
       
  1545      style = gtk_widget_get_style_context(menuBar);
       
  1546 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1547 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1548      sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
       
  1549 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
       
  1550 +    gtk_style_context_save(style);
       
  1551 +    gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT);
       
  1552 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1553      sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
       
  1554 +    gtk_style_context_restore(style);
       
  1555  
       
  1556      // GTK's guide to fancy odd row background colors:
       
  1557      // 1) Check if a theme explicitly defines an odd row color
       
  1558 @@ -1316,7 +1343,7 @@ nsLookAndFeel::Init()
       
  1559      // Get odd row background color
       
  1560      gtk_style_context_save(style);
       
  1561      gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
       
  1562 -    gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1563 +    gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color);
       
  1564      sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
       
  1565      gtk_style_context_restore(style);
       
  1566  
       
  1567 @@ -1334,9 +1361,11 @@ nsLookAndFeel::Init()
       
  1568      gtk_container_add(GTK_CONTAINER(parent), infoBar);
       
  1569      gtk_container_add(GTK_CONTAINER(infoBarContent), infoBarLabel);
       
  1570      style = gtk_widget_get_style_context(infoBarLabel);
       
  1571 +    gtk_style_context_save(style);
       
  1572      gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
       
  1573 -    gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
       
  1574 +    gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color);
       
  1575      sInfoBarText = GDK_RGBA_TO_NS_RGBA(color);
       
  1576 +    gtk_style_context_restore(style);
       
  1577  #endif
       
  1578      // Some themes have a unified menu bar, and support window dragging on it
       
  1579      gboolean supports_menubar_drag = FALSE;
       
  1580 diff -up firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp
       
  1581 --- firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20	2016-04-25 14:46:15.300592722 +0200
       
  1582 +++ firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp	2016-04-25 14:40:42.000000000 +0200
       
  1583 @@ -1567,9 +1567,6 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
       
  1584    case NS_THEME_RADIO_CONTAINER:
       
  1585    case NS_THEME_CHECKBOX_LABEL:
       
  1586    case NS_THEME_RADIO_LABEL:
       
  1587 -  case NS_THEME_BUTTON:
       
  1588 -  case NS_THEME_DROPDOWN:
       
  1589 -  case NS_THEME_TOOLBAR_BUTTON:
       
  1590    case NS_THEME_TREEVIEW_HEADER_CELL:
       
  1591      {
       
  1592        if (aWidgetType == NS_THEME_DROPDOWN) {
       
  1593 @@ -1588,6 +1585,21 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
       
  1594        aResult->height += border.top + border.bottom;
       
  1595      }
       
  1596      break;
       
  1597 +  case NS_THEME_BUTTON:
       
  1598 +  case NS_THEME_DROPDOWN:
       
  1599 +  case NS_THEME_TOOLBAR_BUTTON:
       
  1600 +    {
       
  1601 +        moz_gtk_get_button_height(&aResult->height);
       
  1602 +    }
       
  1603 +    break;
       
  1604 +  case NS_THEME_FOCUS_OUTLINE:
       
  1605 +  case NS_THEME_NUMBER_INPUT:
       
  1606 +  case NS_THEME_TEXTFIELD:
       
  1607 +  case NS_THEME_TEXTFIELD_MULTILINE:
       
  1608 +    {
       
  1609 +        moz_gtk_get_entry_height(&aResult->height);
       
  1610 +    } 
       
  1611 +    break;
       
  1612    case NS_THEME_TOOLBAR_SEPARATOR:
       
  1613      {
       
  1614        gint separator_width;
       
  1615