7

I'm trying to use CSS to style a GtkLabel. I would like to change the color and font size of the label. Here is my C code:

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *label = gtk_label_new("Label");

    GtkCssProvider *cssProvider = gtk_css_provider_new();
    gtk_css_provider_load_from_path(cssProvider, "theme.css", NULL);
    gtk_style_context_add_provider(gtk_widget_get_style_context(window),
                                   GTK_STYLE_PROVIDER(cssProvider),
                                   GTK_STYLE_PROVIDER_PRIORITY_USER);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_container_add(GTK_CONTAINER(window), label);
    gtk_widget_show_all(window);

    gtk_main();
}

Here is my CSS in theme.css, currently this should only change the font color:

GtkLabel {
    color: green;
}

I compile with:

gcc `pkg-config gtk+-3.0 --cflags` test.c -o test `pkg-config --libs gtk+-3.0`

However, when I run the code I get black text. If I change theme.css to use a widget name or CSS class instead of GtkLabel, it still doesn't work. However, if I use * instead of GtkLabel, it works (although I don't want this to apply to everything). This means that the C code should be correct and something is wrong with the CSS.

gsgx
  • 12,020
  • 25
  • 98
  • 149
  • 1
    You are ignoring errors from `gtk_css_provider_load_from_path()`. Use the final argument; if the function returns `FALSE`, check it to see what's wrong. I have a feeling the selector isn't `GtkLabel` and you're missing a `;`... – andlabs Jun 11 '15 at 22:06
  • @andlabs I added the `;` (my code had it, just not the question), and I checked the return value. It's true. – gsgx Jun 11 '15 at 22:13
  • Hm... Try adding the style provider to the *label's* style context instead of the *window's*. – andlabs Jun 11 '15 at 22:20
  • @andlabs That works! But it would be nice if I could have one CSS file for the window and all it's child elements, not one CSS file per widget. – gsgx Jun 11 '15 at 22:26
  • You can; you just need to add a higher specificity for your CSS selector. Try using a CSS class instead of using the widget name, and use the same class with `gtk_style_context_add_class()`. – ebassi Jun 12 '15 at 16:54
  • @ebassi If I understand correctly, the `.label` class should already be defined, so a call to `gtk_style_context_add_class` shouldn't be necessary if I use this class. Using this instead of `GtkLabel` doesn't work either. – gsgx Jun 12 '15 at 22:32

1 Answers1

11

Currently, CSS providers are not inherited to the children style contexts. So you need to add the CSS provider to the screen using gtk_style_context_add_provider_for_screen()

Try changing

gtk_style_context_add_provider(gtk_widget_get_style_context(window),
                               GTK_STYLE_PROVIDER(cssProvider),
                               GTK_STYLE_PROVIDER_PRIORITY_USER);

to

gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
                                          GTK_STYLE_PROVIDER(cssProvider),
                                          GTK_STYLE_PROVIDER_PRIORITY_USER);

I don't think gtk supports multiple screens these days, but gtk_widget_get_screen() could be used to replace gdk_screen_get_default().

marcolz
  • 2,880
  • 2
  • 23
  • 28