Tag Archives: C++

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[].

Looking for Work

I’ve really enjoyed the past year or so of “sabbatical”, learning new skills, doing some hobby projects, and spending more time with my kids, but it’s time to look for a proper job again. I suspect I’ll do some freelancing for a while until I find something suitable.

I’m hoping to find something still in the Linux and open source world, maybe moving into Android, and maybe with some management. I enjoyed running Openismus so I hope I can continue doing something similar: managing multiple small teams of highly skilled software developers who work with open source code and collaborative open source methods, while still doing some software development myself. I’d like to continue working with people with such high standards.

I don’t expect this to be easy because:

  • I want to stay in Munich.
  • I’d really like part time or flexible (start early, leave early) hours so I can spend some of the afternoon with my kids.
  • Running Openismus gave me project management experience, but I’m not sure it’s given me enough to call myself a manager rather than a programmer, and I don’t want to stop being a programmer.
  • GTK+ (and gtkmm) experience is apparently no longer such a popular niche. Qt still is but I’m less enthusiastic about it.
  • C++ is still broadly popular, but I’d like to stay away from MS Windows development.
  • I’ve really enjoyed doing Java Android development recently, but I hesitate to call myself an expert Java developer, compared to my C++ skills. Then again, if most Java developers are as bad as most C++ developers, then I must be better than most.
  • Although I’m learning some Algorithm analysis theory at the moment for fun, it doesn’t greatly interest me and I’ve never needed it over the last 20 years. But it seems to have become a popular interview filter.
  • I’m still not a Kernel developer and I still don’t really want to be. I like creating libraries, tools, and user experiences.

Here’s my CV if you think I can be useful.

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

GTK+: Aligning / Justification in text widgets

There are 3 GTK+ text widgets: GtkEntry, GtkTextView, and GtkLabel. I noticed recently that they are a little inconsistent in how they offer alignment of their text, and the API confuses the terms justification and alignment slightly. This is highly unlikely to change, because that would be disruptive to existing code, but maybe this is helpful to people trying to use the API as it is now.

I’ve put some test_gtk_text_widgets_align.c example code in github. It shows two GtkLabels (single-line and multi-line) two GtkTextViews (single line and multi-line) and a GtkEntry (single-line only). I tried this with GTK+ 3.15.9. I’ve mostly ignored deprecated API, such as GtkMisc and GtkAlignment, to simplify things.

I’ve referred to the API via the *_set_*() functions, but this API is available as properties too. There are also vertical equivalents though I only talk about horizontal alignment here.

Default

This is how it looks by default. It looks fine, though the GtkLabel, and only the GtkLabel, defaults to center alignment – not a very useful default.

Justification

Now, if you want to justify the text to the right, you might call gtk_label_set_justify() on the GtkLabels and call gtk_text_view_set_justification() on the GtkTextViews, though you’ll need to call gtk_text_view_set_wrap_mode() for that to take effect. Then you’d see something like the screenshot below.

You’d notice

  • The justification had no effect on the single-line GtkLabel (as per the gtk_label_set_justify() documentation) but it did have an effect on the single-line GtkTextView.
  • The text in the GtkLabel remains aligned in the center (the GtkLabel default) even though it’s justified within that central part.
  • We didn’t call any justification method on the GtkEntry, because it has none. However, see below about gtk_entry_set_alignment().

Justification and Alignment

To fix that center-alignment of the right-justified text in the GtkLabel, you could call gtk_widget_set_halign(). Then you’d see this:

But, strangely:

  • The center-aligned right-justified text in the multi-line GtkLabel is unchanged. It remains center-aligned – it is not flush with the right side of the widget. But see below about gtk_label_set_xalign().
  • The single-line GtkLabel now appears to be justified/aligned to the right, which is nice. But see below.
  • The GtkTextViews have changed their word wrapping for some reason. I have no idea why.
  • The GtkTextViews and GtkEntry now use only just enough space at the right for their entire widgets, not just the text that they contain. In fact, the GtkEntry is now too small to show all of its text and, strangely, that happens even if I use gtk_widget_set_hexpand() on the GtkEntry.

This shows us that gtk_widget_set_halign() affects the whole widget (as per the halign documentation), not just the text. That is more obvious if we set a background color. Then we see that that’s why the single-line GtkLabel now looks justified – it’s really just the whole widget that has been aligned to the right:

Obviously, I don’t want this effect with the GtkTextViews, and it would only be useful on a single-line GtkLabel. Luckily we don’t need to use gtk_widget_set_halign() at all to justify text:

gtk_label_set_xalign

The GTK+ developers noticed this problem with GtkWidget’s halign so in the very latest GTK+ (3.15/3.16), they added gtk_label_set_xalign(). This aligns the text in the GtkLabel, rather than the GtkLabel itself. Like so:

I just pushed an improvement to the gtk_misc_set_alignment() deprecation documentation to make that clearer.

gtk_misc_set_alignment (deprecated)

If you can’t use the last GTK+ API, you can use the deprecated gtk_misc_set_alignment() method to get the same effect as gtk_label_set_xalign(). (Ignore the GtkTextViews here – they don’t derive from GtkMisc).

screenshot_test_gtk_text_widgets_set_alignment

Entry alignment

Likewise, GtkEntry has gtk_entry_set_alignment(), which has been in GTK+ since 2.4. Like gtk_labeL_set_xalign(), it affects the text in the widget, not widget itself.

screenshot_test_gtk_text_widgets_entry_alignment

Conclusion

So, if I wanted to justify my widget’s text, without changing the size of the widget itself, I’d decide what to do like this:

  • For a GtkLabel: Use both gtk_label_set_xalign() and gtk_label_set_justify(). Use gtk_misc_set_alignment() instead of gtk_label_set_xalign() if you can’t use GTK+ 3.16.
  • For a GtkTextView: Use gtk_text_view_set_justification() with gtk_text_view_set_wrap_mode().
  • For a GtkEntry: Use gtk_entry_set_alignment().

I could be wrong, so do please tell me how.

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.

 

jhbuild and clang’s scan-build

I love C and C++ compiler warnings, particularly when I can fix the problems they show. I love getting new warnings for code I thought was clean. There are always a few warnings that show serious mistakes.

I recently noticed that, since 2011, jhbuild can do some extra static code analysis, using clang’s scan-build tool. This is thanks to Jeremy Huddleston and friends.

It’s pretty simple, though I don’t think it’s in the jhbuild manual yet. It should work if you just install scan-build (from your distro package, such as the clang-analyzer package on Fedora), and add this line to your .config/jhbuildrc file in your home directory:

static_analyzer = True

My scan-build here on Fedora 19 didn’t seem to find its own clang executable, so I had to add this line too:

static_analyzer_template = 'scan-build --use-analyzer=/usr/bin/clang -v -o %(outputdir)s/%(module)s'

I wonder if any systems are running this regularly. I’d like to just view it online every now and then. My local /tmp/jhbuild_static_analyzer/ directory is full of lovely scan-build reports for various GNOME modules but I’m sure others would enjoy that bounty.

 

Going gnome-vfs

I rewrote regexxer and PrefixSuffix a bit to use our new C++ gnome-vfs bindings rather than just local file systems. Regexxer was much easier than I expected because danielk‘s code is so well structured. I haven’t done a comparison, but I suspect that regexxer is slower now. If Daniel ever shows up again he’s going to slap me around that. I am not worthy of hacking on Daniel’s code.

It’s nice to know that gnome-vfsmm really works. We will freeze the API for 2.0 soon, so we can branch for the parallel-installable gtkmm 2.4/GNOME 2.6 stuff.