0

Could someone tell me whats wrong with the below program? I am referring the http://wikistack.com/use-css-gtk/ site for the example. But when i run the program i get the error style.css:1:0Expected a valid selector

#include <gtk/gtk.h>
#include <string.h>  /* for css */
#include <iostream>

int main (int argc, char *argv[])
{
    GtkWidget *window;

    /*---- CSS ------------------*/
    GtkCssProvider *provider;
    GdkDisplay *display;
    GdkScreen *screen;
    /*---------------------------*/

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_widget_set_size_request(window, 400, 300);
    gtk_window_set_title(GTK_WINDOW(window), "wikistack");
    g_signal_connect(G_OBJECT (window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    /* ----------------- CSS -------------------------------------------------*/
    provider = gtk_css_provider_new ();
    display = gdk_display_get_default ();
    screen = gdk_display_get_default_screen (display);
    gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

    const gchar* home = "D:\\style.css";

    GError *error = 0;

    gtk_css_provider_load_from_file(provider, g_file_new_for_path(home), &error);
    std::cout << error->message;
    g_object_unref (provider);
    /* -----------------------------------------------------------------------*/

    gtk_widget_show_all(window);
    gtk_main ();
    return 0;
}

and the style.css file contains below styling info.

/* Theme labels that are descendants of a window */
GtkWindow GtkLabel {
    background-color: #898989;
}
Swapnil
  • 389
  • 5
  • 22
  • I don't know if it makes a difference, but you don't have a semicolon at the end of `background-color: #898989`. Single lines should not require it, but you never know. – theGtknerd Apr 26 '17 at 11:36
  • sorry its typo mistake, but it does not work with semicolon as well – Swapnil Apr 26 '17 at 12:08
  • I tried compiling your program and it works fine. I changed `"D:\\style.css"` to `"style.css"` and I have the style.css file in the same directory as the .c file. This is using Linux Mint. – theGtknerd Apr 26 '17 at 12:49
  • Whoops, I made a mistake in the style.css. Change `GtkWindow GtkLabel` to `GtkWindow, GtkLabel` and see if that works. – theGtknerd Apr 26 '17 at 12:54
  • If you are using GTK 3.20 or later, then the names of the selectors have changed. See the GTK documentation for GtkWindow and GtkLabel to get the correct CSS node names. – ptomato Apr 29 '17 at 21:09

1 Answers1

3

'\xef\xbb\xbf' is the UTF8 encoded version of the unicode ZERO WIDTH NO-BREAK SPACE U+FEFF. It is often used as a Byte Order Mark at the beginning of unicode text

  • when you have 3 bytes: '\xef\xbb\xbf', then the file is utf8 encoded
  • when you have 2 bytes: '\xff\xfe', then the file is in utf16 little endian
  • when you have 2 bytes: '\xfe\xff', then the file is in utf16 big endian

Example:

# when you read from a  byte string
b'window {\n    opacity: 1;\n  ... 

# when you read from a .css file
b'\xef\xbb\xbfwindow {\n  ... 

Therefore, the gtk_css_provider_load_from_file function throws an error.

The 'utf-8-sig' encoding explicitely asks for writing this BOM at the beginning of the file To process it automatically at read time of file in Python 2, you can use the codecs module:

Example:

css_provider = Gtk.CssProvider()
with open("main.css", "rb") as css_file:
    css_file = EncodedFile(css_file, 'utf-8', 'utf-8-sig')
    css_provider.load_from_data(css_file.read())

EncodedFile will wrap the original file object by decoding it in utf8-sig, actually skipping the BOM and re-encoding it in utf8 with no BOM.

The answer is taken and modified from this anwser.

  • I was trying to apply CSS in Gtk#. I created the css file using Monodevelop "New File". That was causing the problem. When I created the css file using text editor and included that in project, no problems! – Mohit Atray Jul 21 '20 at 20:22