Bug 1355143 - Implement CreateStyleContextWithStates to style with fully stated css path, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Wed, 18 Apr 2018 11:03:39 +0200
changeset 784986 f6b3d279049b97d184f8a379f8b5afbb17b0a4ab
parent 784732 a0c804993efc599a95e97bea39fa1528fd0195d8
child 784987 478e40f73cee64d4e39971b09240b1881697a07d
push id107085
push userstransky@redhat.com
push dateThu, 19 Apr 2018 11:45:09 +0000
reviewersjhorak
bugs1355143
milestone61.0a1
Bug 1355143 - Implement CreateStyleContextWithStates to style with fully stated css path, r?jhorak MozReview-Commit-ID: ENWBekzq4Oq
widget/gtk/WidgetStyleCache.cpp
widget/gtk/WidgetStyleCache.h
widget/gtk/mozgtk/mozgtk.c
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -1509,8 +1509,38 @@ GetStyleContext(WidgetNodeType aNodeType
   // 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]) {
     gtk_style_context_invalidate(style);
   }
   return style;
 }
+
+GtkStyleContext*
+CreateStyleContextWithStates(WidgetNodeType aNodeType, GtkTextDirection aDirection,
+                             GtkStateFlags aStateFlags)
+{
+  GtkStyleContext* style = GetStyleContext(aNodeType, aDirection, aStateFlags);
+  GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(style));
+
+  if (gtk_check_version(3, 14, 0) == nullptr) {
+
+    static auto sGtkWidgetPathIterGetState =
+      (GtkStateFlags (*)(const GtkWidgetPath*, gint))
+      dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_get_state");
+    static auto sGtkWidgetPathIterSetState =
+      (void (*)(GtkWidgetPath*, gint, GtkStateFlags))
+      dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_state");
+
+    int pathLength = gtk_widget_path_length(path);
+    for(int i = 0; i < pathLength; i++) {
+      unsigned state = aStateFlags | sGtkWidgetPathIterGetState(path, i);
+      sGtkWidgetPathIterSetState(path, i, GtkStateFlags(state));
+    }
+  }
+
+  style = gtk_style_context_new();
+  gtk_style_context_set_path(style, path);
+  gtk_widget_path_unref(path);
+
+  return style;
+}
--- a/widget/gtk/WidgetStyleCache.h
+++ b/widget/gtk/WidgetStyleCache.h
@@ -33,20 +33,37 @@ CreateStyleForWidget(GtkWidget* aWidget,
 
 GtkStyleContext*
 CreateCSSNode(const char*      aName,
               GtkStyleContext* aParentStyle,
               GType            aType = G_TYPE_NONE);
 
 /*
  * Returns a pointer to a style context for the specified node and state.
- * The context is owned by WidgetStyleCache.  Do not unref.
+ * aStateFlags is applied only to last widget in css style path,
+ * for instance GetStyleContext(MOZ_GTK_BUTTON, .., GTK_STATE_FLAG_HOVER)
+ * you get "window button:hover" css selector.
+ * If you want aStateFlags applied to all path elements use
+ * CreateStyleContextWithStates().
+ *
+ * The context is owned by WidgetStyleCache. Do not unref.
  */
 GtkStyleContext*
 GetStyleContext(WidgetNodeType aNodeType,
                 GtkTextDirection aDirection = GTK_TEXT_DIR_NONE,
                 GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
                 StyleFlags aFlags = NO_STYLE_FLAGS);
 
+/*
+ * Returns a pointer to a style context for the specified node
+ * and state applied to all elements at widget style path.
+ *
+ * The context is owned by caller and must be released by g_object_unref().
+ */
+GtkStyleContext*
+CreateStyleContextWithStates(WidgetNodeType aNodeType,
+                             GtkTextDirection aDirection = GTK_TEXT_DIR_NONE,
+                             GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL);
+
 void
 ResetWidgetCache(void);
 
 #endif // WidgetStyleCache_h
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -599,16 +599,17 @@ STUB(gtk_widget_get_preferred_width)
 STUB(gtk_widget_get_preferred_height)
 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_length)
 STUB(gtk_widget_path_new)
 STUB(gtk_widget_path_unref)
 STUB(gtk_widget_set_valign)
 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)