Proposal: gtk_widget_add_css_classes()

I know this is just syntax sugar, but I was wondering, wouldn’t something like this be a nice-to-have?

G_GNUC_NULL_TERMINATED GtkWidget * gtk_widget_add_css_classes (
	GtkWidget * const widget,
	const gchar * const css_class_1,
	...
) {
    va_list args;
	const gchar * iter = css_class_1;
	va_start(args, css_class_1);
	do {
		gtk_widget_add_css_class(widget, iter);
	} while ((iter = va_arg(args, const gchar *)));
	va_end(args);
	return widget;
}

The concept is a bit jQuery-style, but it can spare a lot of code when widgets are placed by hand one by one.

E.g. (probably not the best example):

adw_preferences_group_add(
	ADW_PREFERENCES_GROUP(preferences_group),
	gtk_widget_add_css_classes(
		g_object_new(
			ADW_TYPE_BUTTON_ROW,
			"title", "Bla bla bla",
			NULL
		),
		"suggested-action",
		"my-class",
		"bla-bla-bla",
		NULL
	)
);

–madmurphy

EDIT: I just saw that something similar already exists, but does not bring the sugar advantage.

Hi,

You can already do:

		g_object_new(
			ADW_TYPE_BUTTON_ROW,
			"title", "Bla bla bla",
			"css-classes", (const char * const[]) {
				"suggested-action", "my-class", "bla-bla-bla", NULL
			},
			NULL
		),

Thank you. I suspect that the problem of “setting” CSS classes instead of “adding” them would be that with your solution possible CSS classes added by the _init() function of GtkButton would be overwritten. Isn’t that correct?

Yes, that will indeed overwrite the classes set by init(), if any.

Back to the original question: usually maintainers are reluctant to add these kind of small APIs that apps can easily implement on their side.

Yes, possibly. But I hope the GTK developers will consider adding a gtk_widget_add_css_classes() and also a gtk_widget_remove_css_classes() function (also variadic). If, as it seems, GTK mimics the HTML DOM and JavaScript, there we have

element.classList.add("foo", "bar", "baz");

and

element.classList.remove("foo", "bar", "baz");

–madmurphy

It’d probably be easier to add something like this:

void
gtk_widget_add_css_classes (GtkWidget   *widget,
                            const char **css_classes);

With css_classes being NULL-terminated:

gtk_widget_add_css_classes (some_widget,
                            (const char *[]) {
                              "foo",
                              "bar", 
                              "baz",
                              NULL,
                            });

And similarly, for a remove_css_classes(). In general, though:

  • we don’t add this kind of C convenience API unless there are multiple applications clamouring for it
  • it’s easy to open-code this functionality
  • it’s rare for application code to add more than one class at a time; that’s usually happens at instance initialisation, which is better handled through a UI template

An array of strings would also work! I don’t know if C convenience APIs are in general necessary, but if they are, CSS classes are something so ubiquitous and deeply rooted in modern GTK programming that this is definitely one place where to have them. For the same reason, personally, I would consider adding both types of functions (variadic and single array argument) – but this is just my opinion.

–madmurphy