Tag Archives: Openismus

gtkmm 2.20 released

Yesterday I released the API/ABI-stable gtkmm 2.20.0.

Some GNOME friends recently suggested that we should hype gtkmm more, and the applications that use it. I think they want us to use meaningless phrases like more-productive, ground-breaking, state-of-the-art, etc. I won’t do that, but it’s nice to note that gtkmm has now tracked the GTK+ 2 API for 7.5 years, and has officially followed the GNOME release schedule for 6 years. It is the pure C++ GUI toolkit that you can depend on, if you like that kind of thing, while still easily using other standard tools and APIs. Its ongoing development is entirely open.

It will help you write code that works and that you understand better. It won’t help you “just” write code in 10 times less time, or with 10 times less bugs, but nothing can because software development is difficult and likely to remain difficult.

I will take the opportunity to link to gtkmm’s documentation and to mention that a company, Openismus, funds its development and offers paid support and training.

What our Trainees Learn

After our successful year of training at Openismus, I thought I’d publish the rough bullet-point list that we used. Whoever we choose for the following year will repeat much the same process, with in-depth critique and a dose of reality.

These were our overall aims:

  • Familiarity with the programming languages, toolkits, and tools, beyond the average.
  • Good quality habits – documentation, ChangeLogs/commit-messages, bug filing, simple code.
  • Good communication – politeness, precision, knowing who/where to contact, tracking progress and following up.

And this is the stuff that we checked off along the way:

Knowledge of C

  • Respect for memory. True understanding of pointers.
    • Understanding of the many ways to use * and & and [], declaring and dereferencing.
    • Understanding of state (Such as a widget’s data, or a user_data struct, or a C++ class’s member variables.)
    • Understanding function pointers, including their weird syntax, made easier by use of typedefs.
  • Basic understanding of object-orientation – Write functions that have a namespaced prefix and that take a first self/this parameter.
    • Write init and free functions where appropriate.
    • Don’t use a prefix that is used by an existing library.
  • Use of enums (or defines if necessary, or static constants if appropriate) instead of magic numbers/strings.
  • Breaking code up into small blocks, separated by empty lines, with pseudo-code comments above each block. In small functions, of course.
  • Initializing local variables, even if you don’t think it’s necessary.
  • The GTK+ coding style, which is common for C.

Knowledge of GTK+

Familiarity with GTK+, to the level of implementing new widgets.

  • Reference-counting: Conventions and special cases (gstreamer and tinymail use a different convention, for instance).
  • Child widgets don’t really use reference-counting. They are destroyed by parents regardless.
  • Glade and GtkBuilder
  • Implement a new widget, doing some custom drawing and/or containing some child widgets. Make sure that you understand what the various construct/init/finalize/destroy/etc vfuncs do.

Other C stuff and basic tools

  • Tools: gdb, valgrind, svn, git, diff, patch.
  • Writing ChangeLog entries or commit messages (mentioning files and functions, and what changed in them and why).
  • autotools
  • gtk-doc syntax, and knowing what developers need to see in the documentation. Mention the what, when, why, how, and “see also”.
  • Familiarity with Clutter, to the level of implementing new actors. See the Openismus Clutter tutorial.
  • Fix some GNOME bugs, submitting patches. Maybe work with the gnome-love group.

Communication

  • Join the relevant GTK+, GNOME, Maemo, and Qt mailing lists.
  • Add Openismus employees to your GNOME bugzilla Users To Watch list. Someone will watch yours too.
  • Be repeatedly told to file bugs and patches, and to follow up on them. File bugs about documentation too.

Familiarity with C++ – at least the parts used by gtkmm and Qt

This takes more time than anything else, but its doable with motivation and mentoring from our experts.

  • Read a full book, such as Accelerated C++, cover to cover.
  • Understanding of classes, constructors, inheritance, polymorphism.
  • Understanding of references.
  • Understanding of const and mutable.
  • Templates. And template specializations.
  • Use of std containers.
  • Familiarity with gtkmm (easy because they know GTK+ already.)
  • The gtkmm coding style, which is common for C++.
  • The doxygen/javadoc syntax.
  • Wrap some new GTK+ API for gtkmm.
  • Fix a Glom bug. For instance, there are some simple Glom gnome-love bugs.
  • Familiarity with Qt. Understand what moc does. Do something real-world with it’s (quasi) model/view widgets. Understand QString historical oddities.
  • Maybe find a bug to fix in KDE.

Optimization work

  • Understanding processing, memory, and IO costs.
  • Avoiding premature optimization while avoiding obvious performance errors.
  • Using Oprofile, SysProf, system tap, etc.

Debian/Ubuntu packaging

  • Package a new version of an existing package, such as Glom, in the Openismus PPA.
  • Package something new for Ubuntu.

Embedded Linux

  • Use of Scratchbox with Maemo.
    • Port something to Maemo.
    • Package it for maemo-extras.
  • Using a BeagleBoard:
    • Set up the BeagleBoard and get something running.
    • Try to install Mer.
    • Putting a self-built distro on generic hardware (BeagleBoard), using Poky or OpenEmbedded.
  • Be aware of differences/pros/cons between Poky and OpenEmbedded.
  • Document how a customer might prepare and maintain a custom debian (or Ubuntu) distro for their embedded hardware project. For instance, how to install and use an autobuilder for packages.

Openismus Wants More Trainees

A little over a year ago, we hired our first batch of Openismus trainees. After an intensive year gaining knowledge and experience, I’m proud to say that David King and Michael Hasselmann have now graduated to regular work on customer projects. They’ve become solid developers in whom we have confidence, thanks to mentoring from all our other employees. Personally, creating these new development careers is one of the most worthwhile things I’ve done in my career.

So we need some more people to repeat our success. Here’s the text from the first time:

If you are smart and enthusiastic but you lack experience then we can provide the opportunity. You would work mostly on existing open source projects instead of customer projects, just to get experience with C, C++, GTK+ and Qt. Our developers would provide technical guidance and encourage you to work and communicate in a structured way, creating software that’s actually usable and useful.

This is also a great opportunity to move to Berlin – a wonderful city for young people. Munich may also be a possibility if necessary.

I’d also like to point out that we are very much an equal-opportunities employer. We get almost no applications from women or minority groups and that’s not good enough. We are a small company so every new person can make the place more like themselves.

Please send us an email telling us about yourself. Show enthusiasm and show us anything you’ve done in the open source world already. As before, I will filter out the least suitable candidates by expecting you to find the appropriate email address yourself. Unfortunately, as before, it’s unlikely that we’ll want to deal with visa paperwork if you are not already working in the EU.

Update: We think we have chosen our new trainees already. Stay tuned. Do bug me if I have not replied to you.

Glom 1.13/14 using boost::python

Finally Figured Out boost::python

After lots of experimentation and two previous failed attempts, Glom now uses boost::python, with very little use of the nasty Python C API remaining. This should make it easier to add Python API to easily access and set field/record/table/database details from the Python that’s used in calculated fields or button scripts.

Useful Things I Now Know about boost::python

boost::python is no fun to get started with, but it’s now far easier for me to use than the Python C API.

I’ve mentioned the awful boost::python documentation before. Here are some essential things that I figured out, which are not really documented. This is thanks to helpful people on the boost::python mailing list. Corrections welcome – there’s so much here that some of it must be wrong.

None of this is very obvious or pleasant. If anyone had their first real C++ experience with boost::python then I’d forgive them for being put off C++ for good. I love C++ so that would be unfortunate.

“Converting” between C and C++ object types

C++ to C: To get the underlying PyObject* from a boost::python::object (awful docs), when you need to use a C function:

PyObject* cobject = theobject.ptr();

To test for a boost::python::object with a null underlying PyObject*, do:

if(cppobject.ptr())

Do not do if(cppobject). That tests if the python object is actually a boolean that is PyTrue.

C to C++: To get a boost::python::object for a PyObject*, when you received one from a C function, but you then need to use the result in a C++ function, or just want the improved memory management:

  • If the C function gave you a reference that you should later unreference:
    boost::python::object cppobject( (boost::python::handle<>(cobject)) );

    (You need those extra brackets, for “interesting” compiler reasons.)

  • Or, if you need to take a reference.
    boost::python::object cppobject(boost::python::borrowed(cobject));

    (Yes. that’s horrible too. I see no reason to expose boost::python::handle in the API.)

  • However, you’ll need to use allow_null too to avoid exceptions if the PyObject* might be null. Well, any pointer could be null, so say hello to:
    boost::python::object cppobject(  (boost::python::handle<>(boost::python::allow_null(cobject))) );

    or

    boost::python::object(boost::python::borrowed(boost::python::allow_null(cobject)));

    (Shoot me now. No, reducing it to b::p::whatever is not a significant improvement.)
    I understand that a null PyObject* may sometimes be an exceptional unexpected event, but forcing the use of a try/catch by default just for a null pointer check is annoying. Explicit functions such as wrap() and wrap_not_null() would be so much easier.
    See the equivalent for gtkmm (plus calling reference() when necessary with non-widgets).

Using boost::python with your own wrapped C++ classes.

  • To get a boost::python::object for an instance of your C++ class that you’ve wrapped for Python with boost::python::class, just do:
    boost::python::object obj(new YourWrappedClass);
  • To get a C++ instance of your wrapped class from a boost::python::object, use boost::python::extract (as also mentioned generically below):
    boost::python::extract<MyClass*> extractor(cppobject);
    if(extractor.check()) myobject = extractor;

Others

  • To get a C++ value out of a boost::python::object do, for instance:
    boost::python::extract<std::string> extractor(cppobject);
    if(extractor.check()) mystring = extractor;

    You can do

    mystring = boost::python::extract<std::string>(cppobject)

    without the check() but that will throw an exception if the underlying type is not really what you expect.

  • boost::python likes to throw exceptions. I think it only ever throws boost::python::error_already_set, though the (Python) error is often not already set when it’s thrown. When the error is set, you’ll need to use Python C API to discover what it is.
  • To provide [] syntax in python for your wrapped class, you’ll need to know how the C API works. Add this voodoo to your boot::python::class declaration:
    .def("__getitem__", &MyClass::getitem)
    .def("__len__", &MyClass::len)

    Those methods can then have signatures like this:

    boost::python::object getitem(const boost::python::object& cppitem);
    long len() const;
  • To use Python date or time values, you will need to use C Python functions. For instance:
    PyObject* cobject = cppobject.ptr();
    int day = PyDateTime_GET_DAY(cobject);
    int month = PyDateTime_GET_MONTH(cobject);
    int year = PyDateTime_GET_YEAR(cobject) );

Boost has no .pc files

boost is a complete pain as a dependency. I understand that they don’t want to freeze API or ABI, because it’s a place for gradually improving API, though I think they should just have regular stable/devel phases with parallel installs. But I can’t forgive how difficult it is to get the header and linker options to use boost libraries. There are some m4 macros out there but they are hacky and fragile, and don’t actually work for boost::python. It shouldn’t be hard to provide pkg-config .pc files, so you wouldn’t need to do any compilation or linker checks in configure at all. I hacked some m4 code together based on some existing stuff, but I couldn’t recommend it.

So distro packagers won’t enjoy this new dependency. Sorry.

Openismus Website Now More Shiny

Daniel Borgmann has prettied up our Openismus website a little. The small touches make it easier on the eye. It’s no longer so adaptable to every screen size or font size, but it’s still relatively simple. It wasn’t us who broke the web, though we tried not to break it more.

Daniel would have liked to do much more impressive things, but I held him back because I like gradual iterative changes and very maintainable files. He did this without changing the content at all. We’ll see what happens next.

In Helsinki at the weekend, Monday and Tuesday

Liam says “broombroom soon Stinky Mama Papa mit”.

That means that we will be flying in an airplane on Friday to Helsinki. I’ll be around for work stuff on Monday and Tuesday too. Most afternoons are planned out already, and evenings are generally difficult with a child, but I hope to see random Nokia/Maemo people, maybe at lunch. I shall be pinging you.

We are looking forward to seeing old friends who we don’t get a chance to see often enough.

Kat, David, Mathias, and Daniel will be around too.

GtkToolPalette in GTK+ 2.20

We (Openismus) recently got our GtkToolPalette widget into GTK+’s git master, to be seen in recent GTK+ 2.19 (unstable) tarballs. We haven’t had much extra time for this kind of thing, so I’m glad it’s finally done after being worked on now and then by Mathias Hasselmann, Jan Arne Petersen and Johannes Schmid. Thanks to Matthias Clasen for valuable reviewing and cleanup.

We hope that this can replace the hand-coded tool palette widgets in Glade and Gimp, as well as making this easier for new applications. It replaces EggToolPalette in libegg, where we started the work. Please take a look and report any problems. I’m already using it in a Glom branch.

Here’s the GTK+ API reference for GtkToolPalette. There’s a GtkToolPalette example in gtk-demo.

And here’s a little introductory Gtk::ToolPalette chapter I wrote for the gtkmm (C++) book. Note that gtkmm’s API reference for this is mostly empty, but fixed already in git.

Peter Penz Joining Openismus

I’m pleased to say that Peter Penz will become an Openismus employee at the start of February. I’ve known and liked Peter since I worked with him six years ago in Linz, Austria on a proprietary C++ mobile phone platform. Back then I was impressed with his skill and temperament so I’ve watched with interest as he has become a core KDE maintainer via the Dolphin file manager.

Obviously Peter will help Openismus as we gain experience with Qt for Maemo 6 (Harmattan) in addition to our continued use of GTK+ and gtkmm.

Peter will work from home in Linz, occasionally visiting the office in Berlin. I like the idea of another office in Linz though.

Trying to use gnuplot in massif_grapher

I’ve been trying to use gnuplot instead of Gd::Chart in my massif_grapher script, mostly just so it can generate zoomable postscript or SVG output.

I first tried using the Chart::Gnuplot perl API, but after a very helpful email conversation with its maintainer Ka-Wai Mak, we found that it cannot yet be used to create gnuplot’s “rowstacked” histograms. So now my gnuplot branch of massif_brancher uses gnuplot directly. However, there are still some problems that I can’t solve easily:

  • The x axis has a label for each item, which makes it cluttered, with overlapping text. I think this cannot be changed while using xtics(1) in the “using” statement, but that’s voodoo to me and I can’t find some version of the using statement that doesn’t use xtics.
  • When using massif_grapher’s –detailed option, for instance with the example .out file, there are 60 stacked columns of data. The legend (key) is then so big that it pushes the graph off the page. I’ve asked about this on the gnuplot mailing list, but I am inpatient.

Actually, I wish I could do these stacked (or “cumulative” in Gd::Chart terms) graphs for regular line graphs, instead of just as items on a histogram, in case the snapshot times are not at regular intervals.

LDTP in jhbuild: A Cry For Help

Glom has lots of code, lots of functionality and lots of UI. It’s easy to break things when making changes to the code. So Armin set up some initial Glom LDTP python scripts to check for regressions. These scripts try to actually use the UI and then check that the application worked as expected.

I’m sure I had that working once, but it doesn’t work for me now. I wish it did because it would be incredibly useful to me. Note that I build Glom in jhbuild, so I need LDTP to work there. To simplify things, I build LDTP in jhbuild too. I’m trying this on Ubuntu Jaunty and Ubuntu Karmic. Armin has a similar environment and it does work for him.

The problem is that the waittillguiexist() [1] function calls just timeout instead of recognizing that the first window has appeared. I definitely have accessibility support enabled, and Accerciser does show the window properly. I’ve asked the LDTP developers but they haven’t been able to help me.

[1] Yes, I hate that function name. I wish that the API and documentation had received proper feedback from native English speakers. It’s rather embarrassing to look at so far.