Quick guide to port an app for Gtk+ 3.20

Recently, there was a lot of action happening in Gtk+ git repository. It was the so called CSS Nodes, which supposely came to improve Gtk’s CSS features and other good things. If you want to know more about that, you can check these two great posts by Matthias Clasen: “A GTK+ update” and “CSS boxed in GTK+”. They, however, come with a downside: it needs some fixups from theme authors and developers too.

Since I just ported GNOME To Do and GNOME Calendar to this new model, and I had quite a hard time tracking down some issues, I decided to write this quick, small and incomplete guide for developers to port their applications to Gtk+ 3.19+.

Note: this is totally based on my personal experience porting the applications, so please, please, if you find any errors, report it and I’ll immediately fix.

The 3-step solution

In order to port your application codebase to Gtk+ 3.19+, there are 3 basic steps to follow:

  1. Replace gtk_widget_get_state_flags by gtk_style_context_get_state_flags
  2. Double check gtk_style_context_get* family of functions
  3. Add a CSS name (optional)

Lets check each step closely. I’m using Calendar’s port to use a CSS name as a case study here.

1. Replace gtk_widget_{get/set}_state_flags

Pretty self-explanatory title. An example (relevant section in bold letters):

GtkStyleContext *context;
GtkStateFlags state_flags;

context = gtk_widget_get_style_context (widget);
state_flags = gtk_widget_get_state_flags (widget);

turns into

GtkStyleContext *context;
GtkStateFlags state_flags;

context = gtk_widget_get_style_context (widget);
state_flags = gtk_style_context_get_state (context);

Since we’re now using GtkStyleContext API, the same is valid for gtk_widget_set_state_flags. You should use gtk_style_context_set_state instead.

2. Double check gtk_style_context_get*

Now the part the took most of my time to figure out how to fix. Obviously, if I had read Matthias’ blog post correctly, I would’ve done it way faster. While tracking down Calendar warning messages, they were coming from this function (among others):

gtk_style_context_get (context,
                       GTK_STATE_FLAG_SELECTED,
                       "font", &font_desc,
                       NULL);

What’s wrong here? The issue is that we’re passing a state that can be different from the GtkStyleContext’s one.

To fix that, we simply have to set the GtkStyleContext’s state before calling the function, as demonstrated below:

gtk_style_context_save (context);
gtk_style_context_set_state (context, GTK_STATE_FLAG_SELECTED);
gtk_style_context_get (context,
                       gtk_style_context_get_state (context),
                       "font", &font_desc,
                       NULL);
gtk_style_context_restore (context);

Again, the relevant sections are bolded. Now, the last piece of this cake.

3. Add a CSS name (optional)

This one is quite easy. Instead of using the class type to match it, the widget sets a CSS name in the class_init function. Let’s check:

static void
gcal_event_widget_class_init (GcalEventWidgetClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  [...]

  gtk_widget_class_set_css_name (widget_class, "event-widget");
}

Now we have to update the theme file. In GNOME Calendar, the theme is stored in gtk-style.css:

GcalEventWidget {
  /* CSS properties */
}
turns into
event-widget {
  /* CSS properties */
}

Tada! It’s done. You now ported your widget to use a CSS name.

Conclusion

I reiterate that this is only my personal experience adjusting the widgets, and is prone to error. This is an ongoing work, so there may be changes after this guide is published (but I’ll try to keep this document updated).

Feel free to share your comments, ideas and rants 🙂

 

Advertisements

4 thoughts on “Quick guide to port an app for Gtk+ 3.20

  1. Is GTK-Doc not cool anymore to write porting guides? For a random GTK+ app developer, finding your blog post will be difficult. This should be documented in the ‘Migrating from Previous Versions of GTK+’ section of the GTK+ reference manual.

    But thanks for writing this up, it can indeed be useful. It looks just at the wrong place to me.

    Like

  2. I second the idea of writing this up in the GTK+ documentation, otherwise it will be lost forever once it drops off planet.gnome.org.

    In fact, I would recommend writing about this kind of thing in the GTK+ documentation //first// in future, //then// blogging about it. 🙂

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s