Bug 1355143 - Implement CreateStyleContextWithStates to style with fully stated css path, r?jhorak
MozReview-Commit-ID: ENWBekzq4Oq
--- 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)