Backed out changeset eb4be9ed211e (bug 1319650) for reftest and chrome bustage
authorPhil Ringnalda <philringnalda@gmail.com>
Thu, 24 Nov 2016 19:30:48 -0800
changeset 324228 b1ebe4a9aec027472a0ec09031795656677f7644
parent 324227 ed292fc1713cf931b50cd13518257990387aa281
child 324229 836a645d53513265a5bfc171047dfffddfb57406
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
bugs1319650
milestone53.0a1
backs outeb4be9ed211e684429f13296f587347b7972ba0d
Backed out changeset eb4be9ed211e (bug 1319650) for reftest and chrome bustage CLOSED TREE
widget/gtk/WidgetStyleCache.cpp
widget/gtk/mozgtk/mozgtk.c
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -15,16 +15,20 @@
 static_assert(GTK_STATE_FLAG_DIR_LTR == STATE_FLAG_DIR_LTR &&
               GTK_STATE_FLAG_DIR_RTL == STATE_FLAG_DIR_RTL,
               "incorrect direction state flags");
 #endif
 
 static GtkWidget* sWidgetStorage[MOZ_GTK_WIDGET_NODE_COUNT];
 static GtkStyleContext* sStyleStorage[MOZ_GTK_WIDGET_NODE_COUNT];
 
+static bool sStyleContextNeedsRestore;
+#ifdef DEBUG
+static GtkStyleContext* sCurrentStyleContext;
+#endif
 static GtkStyleContext*
 GetWidgetRootStyle(WidgetNodeType aNodeType);
 static GtkStyleContext*
 GetCssNodeStyleInternal(WidgetNodeType aNodeType);
 
 static GtkWidget*
 CreateWindowWidget()
 {
@@ -633,26 +637,16 @@ GetWidget(WidgetNodeType aWidgetType)
   GtkWidget* widget = sWidgetStorage[aWidgetType];
   if (!widget) {
     widget = CreateWidget(aWidgetType);
     sWidgetStorage[aWidgetType] = widget;
   }
   return widget;
 }
 
-static void
-AddStyleClassesFromStyle(GtkStyleContext* aDest, GtkStyleContext* aSrc)
-{
-  GList* classes = gtk_style_context_list_classes(aSrc);
-  for (GList* link = classes; link; link = link->next) {
-    gtk_style_context_add_class(aDest, static_cast<gchar*>(link->data));
-  }
-  g_list_free(classes);
-}
-
 GtkStyleContext*
 CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle)
 {
   static auto sGtkWidgetClassGetCSSName =
     reinterpret_cast<const char* (*)(GtkWidgetClass*)>
     (dlsym(RTLD_DEFAULT, "gtk_widget_class_get_css_name"));
 
   GtkWidgetClass *widgetClass = GTK_WIDGET_GET_CLASS(aWidget);
@@ -674,17 +668,21 @@ CreateStyleForWidget(GtkWidget* aWidget,
   // 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);
-  AddStyleClassesFromStyle(context, widgetStyle);
+  GList* classes = gtk_style_context_list_classes(widgetStyle);
+  for (GList* link = classes; link; link = link->next) {
+    gtk_style_context_add_class(context, static_cast<gchar*>(link->data));
+  }
+  g_list_free(classes);
 
   // Release any floating reference on aWidget.
   g_object_ref_sink(aWidget);
   g_object_unref(aWidget);
 
   return context;
 }
 
@@ -786,68 +784,23 @@ GetWidgetRootStyle(WidgetNodeType aNodeT
 }
 
 static GtkStyleContext*
 CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType)
 {
   return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
 }
 
-// Create a style context equivalent to a saved root style context of
-// |aWidgetType| with |aStyleClass| as an additional class.  This is used to
-// produce a context equivalent to what GTK versions < 3.20 use for many
-// internal parts of widgets.
 static GtkStyleContext*
-CreateSubStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
+GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
 {
-  static auto sGtkWidgetPathIterGetObjectName =
-    reinterpret_cast<const char* (*)(const GtkWidgetPath*, gint)>
-    (dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_get_object_name"));
-
-  GtkStyleContext* parentStyle = GetWidgetRootStyle(aWidgetType);
-
-  // Create a new context that behaves like |parentStyle| would after
-  // gtk_style_context_save(parentStyle).
-  //
-  // Avoiding gtk_style_context_save() avoids the need to manage the
-  // restore, and a new context permits caching style resolution.
-  //
-  // gtk_style_context_save(context) changes the node hierarchy of |context|
-  // to add a new GtkCssNodeDeclaration that is a copy of its original node.
-  // The new node is a child of the original node, and so the new heirarchy is
-  // one level deeper.  The new node receives the same classes as the
-  // original, but any changes to the classes on |context| will change only
-  // the new node.  The new node inherits properties from the original node
-  // (which retains the original heirarchy and classes) and matches CSS rules
-  // with the new heirarchy and any changes to the classes.
-  //
-  // The change in hierarchy can produce some surprises in matching theme CSS
-  // rules (e.g. https://bugzilla.gnome.org/show_bug.cgi?id=761870#c2), but it
-  // is important here to produce the same behavior so that rules match the
-  // same widget parts in Gecko as they do in GTK.
-  //
-  // When using public GTK API to construct style contexts, a widget path is
-  // required.  CSS rules are not matched against the style context heirarchy
-  // but according to the heirarchy in the widget path.  The path that matches
-  // the same CSS rules as a saved context is like the path of |parentStyle|
-  // but with an extra copy of the head (last) object appended.  Setting
-  // |parentStyle| as the parent context provides the same inheritance of
-  // properties from the widget root node.
-  const GtkWidgetPath* parentPath = gtk_style_context_get_path(parentStyle);
-  const gchar* name = sGtkWidgetPathIterGetObjectName ?
-    sGtkWidgetPathIterGetObjectName(parentPath, -1) : nullptr;
-  GType objectType = gtk_widget_path_get_object_type(parentPath);
-
-  GtkStyleContext* style = CreateCSSNode(name, parentStyle, objectType);
-
-  // Start with the same classes on the new node as were on |parentStyle|.
-  // GTK puts no regions or junction_sides on widget root nodes, and so there
-  // is no need to copy these.
-  AddStyleClassesFromStyle(style, parentStyle);
-
+  GtkStyleContext* style = GetWidgetRootStyle(aWidgetType);
+  gtk_style_context_save(style);
+  MOZ_ASSERT(!sStyleContextNeedsRestore);
+  sStyleContextNeedsRestore = true;
   gtk_style_context_add_class(style, aStyleClass);
   return style;
 }
 
 /* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
 static GtkStyleContext*
 GetCssNodeStyleInternal(WidgetNodeType aNodeType)
 {
@@ -906,52 +859,45 @@ GetCssNodeStyleInternal(WidgetNodeType a
                                  MOZ_GTK_PROGRESSBAR);
       break;
     case MOZ_GTK_PROGRESS_CHUNK:
       style = CreateChildCSSNode("progress",
                                  MOZ_GTK_PROGRESS_TROUGH);
       break;
     case MOZ_GTK_GRIPPER:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_GRIPPER,
-                                      GTK_STYLE_CLASS_GRIP);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
+                                     GTK_STYLE_CLASS_GRIP);
     case MOZ_GTK_INFO_BAR:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_INFO_BAR,
-                                      GTK_STYLE_CLASS_INFO);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
+                                     GTK_STYLE_CLASS_INFO);
     case MOZ_GTK_SPINBUTTON_ENTRY:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_SPINBUTTON,
-                                      GTK_STYLE_CLASS_ENTRY);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
+                                     GTK_STYLE_CLASS_ENTRY);
     case MOZ_GTK_SCROLLED_WINDOW:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
-                                      GTK_STYLE_CLASS_FRAME);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
+                                     GTK_STYLE_CLASS_FRAME);
     case MOZ_GTK_TEXT_VIEW:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_TEXT_VIEW,
-                                      GTK_STYLE_CLASS_VIEW);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
+                                     GTK_STYLE_CLASS_VIEW);
     case MOZ_GTK_FRAME_BORDER:
       style = CreateChildCSSNode("border", MOZ_GTK_FRAME);
       break;
     case MOZ_GTK_TREEVIEW_VIEW:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_TREEVIEW,
-                                      GTK_STYLE_CLASS_VIEW);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW,
+                                     GTK_STYLE_CLASS_VIEW);
     case MOZ_GTK_TREEVIEW_EXPANDER:
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_TREEVIEW,
-                                      GTK_STYLE_CLASS_EXPANDER);
-      break;
+      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;
@@ -977,26 +923,26 @@ GetCssNodeStyleInternal(WidgetNodeType a
       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 = CreateSubStyleWithClass(MOZ_GTK_NOTEBOOK,
+      style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK,
                                       GTK_STYLE_CLASS_TOP);
       gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB,
                                    static_cast<GtkRegionFlags>(0));
       return style;
     }
     case MOZ_GTK_TAB_BOTTOM:
     {
       // TODO - create from CSS node
-      style = CreateSubStyleWithClass(MOZ_GTK_NOTEBOOK,
+      style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK,
                                       GTK_STYLE_CLASS_BOTTOM);
       gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB,
                                    static_cast<GtkRegionFlags>(0));
       return style;
     }
     case MOZ_GTK_NOTEBOOK:
     case MOZ_GTK_NOTEBOOK_HEADER:
     case MOZ_GTK_TABPANELS:
@@ -1014,141 +960,122 @@ GetCssNodeStyleInternal(WidgetNodeType a
   sStyleStorage[aNodeType] = style;
   return style;
 }
 
 /* GetWidgetStyleInternal is used by Gtk < 3.20 */
 static GtkStyleContext*
 GetWidgetStyleInternal(WidgetNodeType aNodeType)
 {
-  GtkStyleContext* style = sStyleStorage[aNodeType];
-  if (style)
-    return style;
-
   switch (aNodeType) {
     case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
-                                      GTK_STYLE_CLASS_TROUGH);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
+                                     GTK_STYLE_CLASS_TROUGH);
     case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
-                                      GTK_STYLE_CLASS_SLIDER);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
+                                     GTK_STYLE_CLASS_SLIDER);
     case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
-                                      GTK_STYLE_CLASS_TROUGH);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
+                                     GTK_STYLE_CLASS_TROUGH);
     case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
-                                      GTK_STYLE_CLASS_SLIDER);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
+                                     GTK_STYLE_CLASS_SLIDER);
     case MOZ_GTK_RADIOBUTTON:
-      style = CreateSubStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER,
-                                      GTK_STYLE_CLASS_RADIO);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER,
+                                     GTK_STYLE_CLASS_RADIO);
     case MOZ_GTK_CHECKBUTTON:
-      style = CreateSubStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
-                                      GTK_STYLE_CLASS_CHECK);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
+                                     GTK_STYLE_CLASS_CHECK);
     case MOZ_GTK_RADIOMENUITEM_INDICATOR:
-      style = CreateSubStyleWithClass(MOZ_GTK_RADIOMENUITEM,
-                                      GTK_STYLE_CLASS_RADIO);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM,
+                                     GTK_STYLE_CLASS_RADIO);
     case MOZ_GTK_CHECKMENUITEM_INDICATOR:
-      style = CreateSubStyleWithClass(MOZ_GTK_CHECKMENUITEM,
-                                      GTK_STYLE_CLASS_CHECK);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM,
+                                     GTK_STYLE_CLASS_CHECK);
     case MOZ_GTK_PROGRESS_TROUGH:
-      style = CreateSubStyleWithClass(MOZ_GTK_PROGRESSBAR,
-                                      GTK_STYLE_CLASS_TROUGH);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
+                                     GTK_STYLE_CLASS_TROUGH);
     case MOZ_GTK_GRIPPER:
-      style = CreateSubStyleWithClass(MOZ_GTK_GRIPPER,
-                                      GTK_STYLE_CLASS_GRIP);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
+                                     GTK_STYLE_CLASS_GRIP);
     case MOZ_GTK_INFO_BAR:
-      style = CreateSubStyleWithClass(MOZ_GTK_INFO_BAR,
-                                      GTK_STYLE_CLASS_INFO);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
+                                     GTK_STYLE_CLASS_INFO);
     case MOZ_GTK_SPINBUTTON_ENTRY:
-      style = CreateSubStyleWithClass(MOZ_GTK_SPINBUTTON,
-                                      GTK_STYLE_CLASS_ENTRY);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
+                                     GTK_STYLE_CLASS_ENTRY);
     case MOZ_GTK_SCROLLED_WINDOW:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
-                                      GTK_STYLE_CLASS_FRAME);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
+                                     GTK_STYLE_CLASS_FRAME);
     case MOZ_GTK_TEXT_VIEW:
-      style = CreateSubStyleWithClass(MOZ_GTK_TEXT_VIEW,
-                                      GTK_STYLE_CLASS_VIEW);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
+                                     GTK_STYLE_CLASS_VIEW);
     case MOZ_GTK_FRAME_BORDER:
       return GetWidgetRootStyle(MOZ_GTK_FRAME);
     case MOZ_GTK_TREEVIEW_VIEW:
-      style = CreateSubStyleWithClass(MOZ_GTK_TREEVIEW,
-                                      GTK_STYLE_CLASS_VIEW);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW,
+                                     GTK_STYLE_CLASS_VIEW);
     case MOZ_GTK_TREEVIEW_EXPANDER:
-      style = CreateSubStyleWithClass(MOZ_GTK_TREEVIEW,
-                                      GTK_STYLE_CLASS_EXPANDER);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_TREEVIEW,
+                                     GTK_STYLE_CLASS_EXPANDER);
     case MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SPLITTER_HORIZONTAL,
-                                      GTK_STYLE_CLASS_PANE_SEPARATOR);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SPLITTER_HORIZONTAL,
+                                     GTK_STYLE_CLASS_PANE_SEPARATOR);
     case MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SPLITTER_VERTICAL,
-                                      GTK_STYLE_CLASS_PANE_SEPARATOR);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SPLITTER_VERTICAL,
+                                     GTK_STYLE_CLASS_PANE_SEPARATOR);
     case MOZ_GTK_SCALE_TROUGH_HORIZONTAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL,
-                                      GTK_STYLE_CLASS_TROUGH);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL,
+                                     GTK_STYLE_CLASS_TROUGH);
     case MOZ_GTK_SCALE_TROUGH_VERTICAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCALE_VERTICAL,
-                                      GTK_STYLE_CLASS_TROUGH);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCALE_VERTICAL,
+                                     GTK_STYLE_CLASS_TROUGH);
     case MOZ_GTK_SCALE_THUMB_HORIZONTAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL,
-                                      GTK_STYLE_CLASS_SLIDER);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCALE_HORIZONTAL,
+                                     GTK_STYLE_CLASS_SLIDER);
     case MOZ_GTK_SCALE_THUMB_VERTICAL:
-      style = CreateSubStyleWithClass(MOZ_GTK_SCALE_VERTICAL,
-                                      GTK_STYLE_CLASS_SLIDER);
-      break;
+      return GetWidgetStyleWithClass(MOZ_GTK_SCALE_VERTICAL,
+                                     GTK_STYLE_CLASS_SLIDER);
     case MOZ_GTK_TAB_TOP:
-      style = CreateSubStyleWithClass(MOZ_GTK_NOTEBOOK, GTK_STYLE_CLASS_TOP);
+    {
+      GtkStyleContext* style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK,
+                                                       GTK_STYLE_CLASS_TOP);
       gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB,
                                    static_cast<GtkRegionFlags>(0));
-      break;
+      return style;
+    }
     case MOZ_GTK_TAB_BOTTOM:
-      style = CreateSubStyleWithClass(MOZ_GTK_NOTEBOOK, GTK_STYLE_CLASS_BOTTOM);
+    {
+      GtkStyleContext* style = GetWidgetStyleWithClass(MOZ_GTK_NOTEBOOK,
+                                                       GTK_STYLE_CLASS_BOTTOM);
       gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB,
                                    static_cast<GtkRegionFlags>(0));
-      break;
+      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);
   }
-
-  MOZ_ASSERT(style);
-  sStyleStorage[aNodeType] = style;
-  return style;
 }
 
 void
 ResetWidgetCache(void)
 {
+  MOZ_ASSERT(!sStyleContextNeedsRestore);
+#ifdef DEBUG
+  MOZ_ASSERT(!sCurrentStyleContext);
+#endif
+
   for (int i = 0; i < MOZ_GTK_WIDGET_NODE_COUNT; i++) {
     if (sStyleStorage[i])
       g_object_unref(sStyleStorage[i]);
   }
   mozilla::PodArrayZero(sStyleStorage);
 
   /* This will destroy all of our widgets */
   if (sWidgetStorage[MOZ_GTK_WINDOW])
@@ -1157,22 +1084,27 @@ ResetWidgetCache(void)
   /* Clear already freed arrays */
   mozilla::PodArrayZero(sWidgetStorage);
 }
 
 GtkStyleContext*
 ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
                   GtkStateFlags aStateFlags, StyleFlags aFlags)
 {
+  MOZ_ASSERT(!sStyleContextNeedsRestore);
   GtkStyleContext* style;
   if (gtk_check_version(3, 20, 0) != nullptr) {
     style = GetWidgetStyleInternal(aNodeType);
   } else {
     style = GetCssNodeStyleInternal(aNodeType);
   }
+#ifdef DEBUG
+  MOZ_ASSERT(!sCurrentStyleContext);
+  sCurrentStyleContext = style;
+#endif
   bool stateChanged = false;
   bool stateHasDirection = gtk_get_minor_version() >= 8;
   GtkStateFlags oldState = gtk_style_context_get_state(style);
   MOZ_ASSERT(!(aStateFlags & (STATE_FLAG_DIR_LTR|STATE_FLAG_DIR_RTL)));
   unsigned newState = aStateFlags;
   if (stateHasDirection) {
     switch (aDirection) {
       case GTK_TEXT_DIR_LTR:
@@ -1202,21 +1134,28 @@ ClaimStyleContext(WidgetNodeType aNodeTy
     stateChanged = true;
   }
   // This invalidate is necessary for unsaved style contexts from GtkWidgets
   // in pre-3.18 GTK, because automatic invalidation of such contexts
   // was delayed until a resize event runs.
   //
   // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7
   //
-  // Avoid calling invalidate on contexts that are not owned and constructed
-  // by widgets to avoid performing build_properties() (in 3.16 stylecontext.c)
-  // unnecessarily early.
-  if (stateChanged && sWidgetStorage[aNodeType]) {
+  // Avoid calling invalidate on saved contexts to avoid performing
+  // build_properties() (in 3.16 stylecontext.c) unnecessarily early.
+  if (stateChanged && !sStyleContextNeedsRestore) {
     gtk_style_context_invalidate(style);
   }
   return style;
 }
 
 void
 ReleaseStyleContext(GtkStyleContext* aStyleContext)
 {
+  if (sStyleContextNeedsRestore) {
+    gtk_style_context_restore(aStyleContext);
+  }
+  sStyleContextNeedsRestore = false;
+#ifdef DEBUG
+  MOZ_ASSERT(sCurrentStyleContext == aStyleContext);
+  sCurrentStyleContext = nullptr;
+#endif
 }
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -576,17 +576,16 @@ STUB(gtk_style_properties_lookup_propert
 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)
 STUB(gtk_widget_path_append_type)
 STUB(gtk_widget_path_copy)
 STUB(gtk_widget_path_free)
 STUB(gtk_widget_path_iter_add_class)
-STUB(gtk_widget_path_get_object_type)
 STUB(gtk_widget_path_new)
 STUB(gtk_widget_path_unref)
 STUB(gtk_widget_set_visual)
 STUB(gtk_app_chooser_dialog_new_for_content_type)
 STUB(gtk_app_chooser_get_type)
 STUB(gtk_app_chooser_get_app_info)
 STUB(gtk_app_chooser_dialog_get_type)
 STUB(gtk_app_chooser_dialog_set_heading)