Wibbly Stuff

Building a binary for GTK3 theme

We discussed some aspects of making a GTK3 theme in my previous post, and may be we shall do more. In this post, I'll try to explain how to create a binary for your GTK3 theme.


Creating a binary bundle for your GTK3 theme can be useful. It will reduce the I/O error and file system checks as the the resources will already be in the memory. This means loading the resources will be more efficient. I really cannot say the impact on performance, but it is easy to do and makes no harm if you do.

Building the binary

So let's start. Now that your GTK3 theme is ready, we will create a binary for it. Backup the theme folder somewhere else before starting though, as we will delete and modify files.
  1. First, we shall rename the gtk.css file to gtk-main.css and gtk-dark.css file (if exists) to gtk-main-dark.css.
  2. Then create a XML file named gtk.gresource.xml inside the gtk-3.0 folder which will contain the list of all resources, i.e. all CSS files and images. An example would be,

    <?xml version="1.0" encoding="UTF-8"?>
    <gresources>
    <gresource prefix="/org/gnome/name">
    <file preprocess="to-pixdata">assets/slider.png</file>
    <file>apps/nautilus.css</file>
    <file>gtk-main.css</file>
    <file>gtk-main-dark.css</file>
    <file>gtk-widgets.css</file>
    </gresource>
    </gresources>
    

    I think you will be able to understand the syntax from the above file. The part prefix="/org/gnome/name" is important and you should use the name of your theme in place of name. It will be the path which we will use to access the resources after we made the binary. After you are done, proceed to next step.
  3. To build the binary, we will need some packages installed. The packages may vary depending on the contents of the file. But for our example, we would need following packages,

    libgtk-3-dev (>= 3.3.14), libglib2.0-dev, libgdk-pixbuf2.0-dev, libxml2-utils
    

    The names above refer to the packages in Ubuntu, but you should install corresponding packages for your distro.
  4. After installing the required packages, navigate to the gtk-3.0 folder and run the following command,

    glib-compile-resources gtk.gresource.xml
    

    If everything goes well, you will now have a shiny new file named gtk.gresource.
  5. Now make a file named gtk.css and also gtk-dark.css (only if you had a gtk-main-dark.css file). The contents of the file gtk.css should be,

    @import url("resource:///org/gnome/name/gtk-main.css");
    

    The name would be the one which used earlier in the gtk.gresource.xml file. Here we are using the @import rule to include gtk-main.css file, which will in turn import all other files listed inside it.

    For the file gtk-dark.css, the contents should be,

    @import url("resource:///org/gnome/name/gtk-dark-main.css");
    

  6. Now it is time to test the theme. Delete all other files except gtk.css, gtk-dark.css, gtk.gresource and settings.ini (you have a backup as I mentioned previously, don't you?). Then test the theme as you normally would. If everything was as expected, then you've successfully built the binary.

Writing a Makefile

You can package the theme for a specific distro and distribute via repositories. The advantage here would be that the user can get automatic updates and they won't face any problems installing the theme.

We will write a simple Makefile in case you want to build packages for distros. Note that the Makefile is not needed if you didn't compile the theme into binary.

Create a file Makefile outside your theme folder. We should have the following in our Makefile,

source_dir=Name/gtk-3.0

gtk.gresource:
    glib-compile-resources --sourcedir=$(source_dir) $(source_dir)/gtk.gresource.xml

clean:
    rm -f $(source_dir)/gtk.gresource

Notice that here the indention before the lines must be tabs, not spaces. Don't just copy/paste from here. It will not work.

The Name here should be the name of the directory inside which your theme is present. Now the Makefile is ready, you can package the theme easily. Note that we didn't add an install option in the Makefile because we will do that with whatever package we build, just to keep things simple.

I'm really a noob regarding Makefiles and if you have any suggestions or corrections, please comment.