Tag Archives: gtkmm

gtkmm now uses C++11

Switching to C++11

All the *mm projects now require C++11. Current versions of g++ require you to use the –std=c++11 option for this, but the next version will probably use C++11 by default. We might have done this sooner if it  had been clearer that g++ (and libstdc++) really really supported C++11 fully.

I had expected that switching to C++11 would require an ABI break, but that has not happened, so already-built applications will not be affected. But our API now requires C++11 so this is a minor API change that you will notice when rebuilding your application.

Some distros, such as Fedora, are breaking the libstdc++ ABI slightly and requiring a rebuild of all applications, but that would have happened even without the *mm projects moving to C++11. It looks like Ubuntu might be doing this too, so I am still considering taking advantage of a forced (not gtkmm’s fault) widespread ABI break to make some ABI-breaking changes in gtkmm.

C++11 with autotools

You can use C++11 in your autotools-based project by calling AX_CXX_COMPILE_STDCXX_11() in your configure.ac after copying that m4 macro into your source tree. For instance, I used AX_CXX_COMPILE_STDCXX_11() in glom. The *mm projects use the MM_AX_CXX_COMPILE_STDCXX_11() macro that we added to mm-common, to avoid copying the .m4 file into every project. You may use that in your application instead. For instance, we used MM_AX_CXX_COMPILE_STDCXX_11() in the gtkmm-documentation module.

C++11 features

So far, the use of C++11 in gtkmm doesn’t provide much benefit to application developers and you can already use C++11 in applications that use older versions of gtkmm. But it makes life nicer for the gtkmm developers themselves. I’m enjoying learning about the new C++11 features (particularly move constructors) and enjoying our discussions about how best to use them.

I’m reading and re-reading Scott Meyer’s Effective Modern C++ book.  C++11’s rvalue references alone require great care and understanding.

For now, we’ve just made these changes to the **mm projects:

  • Using auto to simplify the code.
    For instance,
    auto builder = Gtk::Builder::create();
  • Using range-based for-loops.
    For instance,
    for(const auto& row : model->children()) { … }
  • Using nullptr instead of 0 or (void*)0.
    For instance,
    Gtk::Widget* widget = nullptr;
  • Using the override keyword when we override a virtual method.
    For instance,
    bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;
  • Using noexcept instead of throw().
    For instance,
    virtual ~Exception() noexcept;
  • Using “= delete” instead of private unimplemented copy constructors and operator=().
  • Using C++11 lambdas, instead of sigc::slots, for small callback methods.
    See below.

libsigc++ with C+11

libsigc++ has also moved to C++11 and we are gradually trying to replace as much as possible of its internals with C++11. Although C++11 has std::function, there’s still no C++11 equivalent for libsigc++ signals and object tracking

You can use C++11 lambda functions with libsigc++. For instance, with glibmm/gtkmm signals:

button.signal_clicked().connect(
  [] () {
    std::cout << "clicked" << std::endl;
  }
);

And now you don’t need the awkard SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE macro if the signal/slot returns a value. For instance:

m_tree_model_filter->set_visible_func(
  [this] (const Gtk::TreeModel::const_iterator& iter) -> bool
  {
    auto row = *iter;
    return row[m_columns.m_col_show];
  }
);

With C++14 that should be even nicer:

m_tree_model_filter->set_visible_func(
  [this] (auto iter) -> decltype(auto)
  {
    auto row = *iter;
    return row[m_columns.m_col_show];
  }
);

These -> return type declarations are necessary in these examples just because of the unusual intermediate type returned by row[].

PrefixSuffix revived

In 2002 I released a little GNOME app to rename files by changing the start or end of the filename, using gtkmm and gnome-vfs(mm). It worked well enough and was even packaged for distros for a while before the dependencies became too awkward.

I’ve never heard of a single person using it, but I still need the app now and then so I just updated it and put it in github, changing it from gtkmm 2.4 to gtkmm 3, removing the bakery dependency, and changing from gnome-vfs to GIO. I also removed most signs of my 2002 code style.

It seems to work, but it really needs a set of test cases.

I’m sure that the performance could be vastly improved but I’m not greatly interested in that so far. Patches are welcome. In particular, I haven’t found an equivalent for the gnome_vfs_xfer_uri_list() function for renaming several files at once and I guess that repeated sequential calls to g_file_set_display_name_async() are probably not ideal.

screenshot_prefixsuffix

cluttermm 1.18

cluttermm provides gtkmm-like C++ bindings for the Clutter API. It hasn’t had much attention over the last few years, while the Clutter API has moved on considerably.

I don’t have a great interest in Clutter, though I’d like cluttermm to be ready to inspire gtkmm if any future GTK+ 4 absorbs Clutter. However, Ian Martin has recently put lots of work into updating cluttermm and I’ve been helping him to get his changes upstream and I released some cluttermm-1.17.x tarballs. It’s in the cluttermm-1-18 branch.

This has involved deprecating a huge amount of API and adding (hopefully all of) the API that replaces it. I’ve already removed all this API in the parallel-installable cluttermm git master branch but I have some linker errors that stop that from building, and I’m not going to spend time on it until there are some releases from clutter’s git master (clutter-2.0).

This also means that the cluttermm-tutorial is even more wildly out of date. I’m not likely to spend my free time updating it.

I don’t want to be cluttermm maintainer again, but I didn’t want Ian’s work to be wasted and I hope he wants to keep at it.

 

glibmm 2.40 and gtkmm 3.12

Only a little late, we released stable glibmm 2.40.0 and gtkmm 3.12.0 versions.

This was only possible thanks to lots of work from Kjell Ahlstedt and  Juan Rafael García Blanco. For instance, Juan added the Gtk:::ActionBar, Gtk::FlowBox and Gtk::Popover classes,after having added Gtk::HeaderBar, Gtk::PlacesSidebar, Gtk::Revealer and Gtk::SearchBar in gtkmm 3.10. They also added example code in gtkmm-documentation.

glibmm 2.38 and gtkmm 3.10

I just released glibmm 2.38.0 and gtkmm 3.10.0 – stable releases of API that we’ve been working on for a while.

This adds several new widgets that were added in GTK+: HeaderBar, ListBox, PlacesSidebar, SearchBar, and Stack. Thanks to Juan Rafael García Blanco, Andrew Potter, and Kjell Ahlstedt for that hard work.

It deprecates StockID, Table, IconFactory, IconSet, IconSource, and Gdk::Color along with several methods.

This glibmm release also has a fairly useable API for Gio::Menu and Gio::Action so you can really create gtkmm Menus with them and Gtk::Builder (here is an example). But unlike GTK+, we decided not to deprecate Gtk::UIManager, Gtk::Action and friends yet.

Most importantly, and most difficult to notice, we have deprecated deriving from Glib::Object before deriving from interface classes (such as Gtk::TreeModel). So you need to make changes such as this. The previous use of interface classes as the last base classes, after Glib::Object (which used to be the only way to use them) will cause runtime warnings in glib for now, and will probably break your application’s functionality in future glib versions. It’s not what we want.

gtkmm 3.8

I didn’t get around to blogging about gtkmm 3.8 when I released it last month, partly because we had to fix a crasher bug and do a gtkmm .1 release before people noticed.

Anyway, just a little while after GNOME 3.8 was released, we managed to release gtkmm 3.8 and glibmm 2.36. There is quite a bit of work in these, almost all by José Alburquerque and Kjell Ahlstedt, as well as the usual few days of last-minute work by me to wrap remaining new API.

I spend very little time on glibmm and gtkmm these days, and don’t have much motivation to change that.

There’s also a change that we expect in glib 2.38 that will break many installed applications that use gtkmm. We successfully begged the glib developers to add a special case for us in glib 2.36, but we have not found any way to avoid this for 2.38. So far our best option seems to be to do a new parallel-installed gtkmm (and glibmm) ABI, leaving the old (broken with glib 2.38) one behind, at least allowing applications to be changed slightly and then rebuilt.

Personally, I have no great incentive to go through that pain.

gtkmm maintainership

I have not had enough time recently for my maintainership of gtkmm, glibmm, libxml++ and libsigc++. And I’m unlikely to find time soon. Family and (income earning) work have taken priority. That’s why glibmm and gtkmm didn’t have .0 releases until a couple of weeks after the GNOME .0 release, and why there was no real attempt to follow the GNOME release schedule this time. I’ve hardly touched cairomm for years.

It’s not a lot of work but I’ve had to find a few days every few months to keep glibmm and gtkmm up to date with API additions in glib and GTK+, to keep roughly in sync with them. There has been rather a lot of new API recently. See the list of new API in gtkmm 3.6, glibmm 2.34 , gtkmm 3.4, and glibmm 2.32. Krzesimir’s ongoing attempt to use the introspection information (rather than .defs files) would help with this but not hugely because we’d still need to take care that the API is right for C++. Some initial .hg/ccg creator script would probably be most helpful.

I have no time for the more difficult bugs that turn up occasionally. Luckily Kjell Ahlstedt, José Alburquerque and others arrive regularly in bugzilla with great fixes for hard problems. I trust Kjell and José to commit directly, but they deserve some decent patch review. Unfortunately I often keep them waiting far too long.

I need to make some change. As a start, I might stop receiving bug email for glibmm and gtkmm, and stop worrying about adding new API. I guess it will take at least one missed GNOME release cycle for some other people to take over my responsibilities.