Isolated unit testing of D-Bus services

Hi all, long time no blog…

At Openismus these past months we’ve been making a series of improvements for the Evolution Data Server, again.

As it goes with patch reviews, better to take on one at a time, so this blog post will focus on isolated unit testing of your D-Bus services.

If you work on the implementation of D-Bus services you’ll be happy to know about the new GTestDBus object introduced in GIO since 2.34. Thanks to this nifty new object we can now perform unit tests on D-Bus services in a completely isolated fashion.

Using GTestDBus to implement a new test fixture for Evolution Data Server (EDS) now makes it possible to run ‘make check’ for EDS without running the actual EDS servers manually, and without even installing the EDS software into the target prefix before hand. With a little more work, we can even get regular distchecks passing for EDS again.

Here’s how:

  • First of all, you need to have an in-tree directory holding your D-Bus .service description files. Typically you already have the .service.in files stored somewhere in tree to be installed somewhere into the install prefix, but you need a separate one (I think it’s good practice to add a subdirectory to your ‘tests/’ directory, so it becomes ‘$(top_builddir)/tests/services’)
  • The contents of your separate .service.in files for testing should point to the in-tree location of your D-Bus service, typically it would look like this:
    [D-BUS Service]
    Name=org.gnome.MyProject.MyServiceName
    Exec=@abs_top_builddir@/src/my-server-name

    This will define a service which explicitly activates a server which you’ve built in your source tree.

  • Then, you just need to provide that in-tree service directory to g_test_dbus_add_service_dir(), typically you would put the following into your tests/Makefile.am:
    -DTEST_SERVICE_DIRECTORY=\""$(abs_top_builddir)/tests/services"\"
  • Finally you just need a basic test fixture, with this test fixture you can ensure that your temporary D-Bus session along with your test service is recreated for every test in the suite:
    typedef struct {
      GTestDBus *dbus;
      MyProxyType *proxy;
    } TestFixture;
    
    static void
    fixture_setup (TestFixture *fixture, gconstpointer unused)
    {
      /* Create a private dbus-daemon for this test */
      fixture->dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
    
      /* Add the private directory with our in-tree service files */
      g_test_dbus_add_service_dir (fixture->dbus, TEST_SERVICE_DIRECTORY);
    
      /* Start the private D-Bus daemon */
      g_test_dbus_up (fixture->dbus);
    
      /* Get a proxy which we will be using in test cases, typically
       * this is some API generated by gdbus-codegen
       */
      fixture->proxy = my_generated_code_new_for_bus_sync (...);
    }
    
    static void
    fixture_teardown (TestFixture *fixture, gconstpointer unused)
    {
      /* Destroy the proxy */
      g_object_unref (fixture->proxy);
    
      /* Stop the private D-Bus daemon */
      g_test_dbus_down (fixture->dbus);
      g_object_unref (fixture->dbus);
    }

With this basic type of fixture, you can produce a series of tests using g_test_add() in the normal way, all testing various behaviours of fixture->proxy.

Of course, perfect isolation of your service’s test cases may need more efforts than just the above, for instance in the EDS test cases we create and delete a data directory between each test and setup the XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_CACHE_HOME enviornment variables to point to that directory (avoiding any interaction with the user’s addressbook & calendar). We also compile a gsettings schema in the local data directory and setup GSETTINGS_SCHEMA_DIR to point to the in-tree directory (avoiding any need to have the EDS settings schemas already installed).

This morning before writing this post I also provided a simple patch to GIO adding an example of this testing paradigm.

 

Glade @ GUADEC

Hi everyone,

Long time no blog. I’ve been meaning to blog and build hype around this but as I’ve been busy with so many things it just hasnt come out.

Well the first thing so say is, please be interested to click this link and visit Juan Pablo’s blog. He is speaking first thing on the first day of GUADEC on the topic of embedding GtkBuilder script natively into GtkContainer derived widgets. Some may remember some of my ancient blog posts on the same topic, I never found time to complete the patches in the composite-containers branch but Juan Pablo has picked up the work with a fury and is going to explain in more details in his talk.

In a last minute decision, as the dates are right, I also decided to drop in too. With all the work Juan has already done, a little consensus and participation hopefully we can finally pull off this great feature.

See you there ;-)

 

A long overdue blog

I haven’t had the time to blog about the things I wanted to this summer, unfortunately I’m a couple days behind in the project I’m working on now so I’ll have to try to make this brief.

First ever GNOME summit

This took place in Montreal several weeks ago, it’s definitely a late blog post for this but I really wanted express my gratitude.

I did not take any pictures, however I did force some time into my schedule to push out a release of Glade (you could easily say that the latest stable releases of Glade were brought to you in a large part by the GNOME summit).

All in all I just wanted to voice my appreciation for getting the opportunity to shake hands with some of the people I’ve admired over the years, after arguing countless topics with many of the same people on  gtk-devel-list and desktop-devel-list over the last decade, it’s really amazing to get to meet some of these people in real life.

I do wish I had blogged this earlier, and I sincerely apologize for not having been a better host (as Montreal is my home town), it was hard enough to push the summit (and Glade release) into my schedule at all (was more of a great pleasant surprise that the summit actually came to me).

A summer of evolution-data-server

This summer at Openismus we’ve been making some enhancements to the Evolution Data Server as a part of Intel’s effort on the Meego platform.

I haven’t been blogging about this work, generally because I did not feel like there was something to “show off” about, we haven’t invented anything new, however  since yesterday we’ve landed the final patch so I’ll just give a rundown of which patches I was tasked to work on.

Bug 652178: Store PHOTO data as plain files

This is probably the most complex of the patch set, Evolution Data Server’s addressbook api allows storing of image data either as binary encoded blobs or simply as a URI. This patch basically enforces a policy where the local backend of EDS converts any incoming binary data into URIs on disk managed by the addressbook backend.

Bug 652175 and Bug 652177:

These patches add a backend property to the calendar and addressbook, the value of the property is guaranteed to remain the same so long as no data has changed for that backend, whenever data changes in the backend then the overall revision is bumped (this allows tools like SyncEvolution to abort when no data has changed without iterating over the whole database).

Bug 652171 and Bug 652180:

These patches implement an api which already existed but had remained unimplemented. The api allows one to filter the reported results of a calendar or addressbook view to only report some of the desired information (this way if you only want contact names and UIDs for instance, you dont have to transfer full vCards from the EDS just to get them).

All of these patches have landed in Evolution Data Server and should be available in the next (3.4) release.

Here and Now

Only a few days ago I landed back in Seoul, South Korea where I expect to be spending the greater part of the coming year, right now I’m in a guest house and hacking in the basement, it’s a nice quaint little atmosphere that makes you feel like you’re doing some kind of crazy science experiments in grandma’s basement again.

For the next few months I’ll be devoting much of my time to a fun (commercial software) project which is to write the new up and coming Karaoke Application for TouchTunes.

While I can’t directly devote any of the company time to GNOME, I can always find a good excuse to enhance the code at the correct level in the stack instead of working around the problem in an application. It’s always good to prove that it pays off to give back to the community which provides your platform libraries.

 

Well, it’s been great and I hope there are not too many typos … now back to not having enough time to do all the things I must ;-)

Glade 3.10 and 3.8 out the door

Glade 3.10 and 3.8 actually happened.

Thanks to:

  • Juan Pablo the Magnificent our hero who is responsible for
    the sexy new workspace look and feel (and also there to help
    me fix and wrap up the builds in the last minute).
  • Marco Diego Aurélio Mesquita for his work on the new preview feature
  • Florent Thévenet for creating icons for every widget class
  • Openismus GmbH for sponsoring my work on Glade.
  • Dozens of contributors who helped polish Glade, reported and fixed bugs.

There has been so much to do in these last moments wrapping up Glade that I have forgotten to include translator credits… so after this blog post I will follow up on my release mails with that.

I’m very proud that we actually came this far, while I think we’re moments late for the GNOME 3.0 release and also a few freeze breaks seem to have occurred, Juan Pablo and I stayed up very late last night making sure we had something worth while so… there better not be any bugs (i.e. you better love it !)  ;-)

Enjoy !

 

Animated Drag’n’Drop thoughts

So I’ve been tasked to try an animated approach at Drag’n’Drop to rearrange child widgets inside a specific container widget in libegg (EggSpreadTable), and I’m throwing this out in public just in case someone might have some better ideas than I do currently.

The EggSpreadTable is something like a GtkTable or GtkGrid that takes a list of widgets and displays them in a fixed number of columns, the spread table “spreads” out widgets evenly across the columns in order to consume the least height as possible (important thing to keep in mind is that widgets can shift across columns to make better use of space).

The desired effect is the one produced when running libegg/toolbareditor/test-toolbar-editor… which uses gtk_toolbar_set_drop_highlight_item(), an obscure and highly complex piece of code which is responsible for highlighting potential drop targets in the toolbar by animating other items out of the way.

My plan so far is a little abstract but I’m going to have to write code now and see if it works:

  • When a drag’n’drop (DnD) operation is in effect, and “drag-motion” is being emitted, I think I’ll have to “lock” the spread table so that widgets don’t jump from column to column, this will avoid hovering a drag source at the end of one column and having the animation show the widget at the beginning of the following column, which I think would be unintuitive.
  • When performing DnD animations, not only will we have to animate widgets up and down inside the potential “drop column”, but we’ll have to call gtk_widget_queue_resize() repeatedly whilst the spread table will have to grow in order to fit the new drag source into the column somewhere.
  • To look more intuitive, when a drag begins the drag source widget will have to “slide out” of it’s parent spread table, which will require the same animation technique whenever a drag begins. Likewise, when a drag fails the widget should be animated back into place.
  • Once a widget is successfully dropped in a said spread table (widgets can be dragged and dropped from one spread table to another), then the arrangement of widgets will still be invalid… the target spread table will have to unlock… at this point it’s also probably best to animate the rearranging of widgets (otherwise you get a nice animated DnD experience and when you drop you get this “snap” where widgets are rearranged in the target container).
  • Another complication is that EggSpreadTable is a height-for-width container, the size and space that the target placeholder will use will depend on requesting the size of the the actual widget being dragged (it’s even possible the spread table will have to grow in width & height to fit the animation).
  • And last but not least, of course it has to use GTK+’s horrid Drag’n’Drop apis.

The business logic will surely be horrid in all of this, many states will have to be managed and juggled while performing these various animations… not to mention the whole operation will require resizing of the spread tables in play (causing the whole interface to shift around, kind of like having a GtkInfoBar in play).

The toolbar code is evidently much more obvious, it only lines up a list of fixed size widgets in a row from left to right, when the widgets (tool items) don’t fit the toolbar anymore, an arrow is displayed and the rest of the items are placed in a drop down menu.

So all of this to say… anyone have any better ideas ?

Translucent TextViews

Now that we’ve finally rolled 3.0 out of the door… it’s time to hang up our hats and stop adding features to GTK+.

Err, nah forget about that – instead lets add cool stuff for an awesome 3.2 now !

As discussed in bug 636695, using GdkRGBA colors in GtkTextView is just about the last thing blocking us from completely deprecating GdkColor and moving GTK+ to an RGBA only api for colors.

But wait ! Implementing the RGBA color values on GtkTextTag is not a mere api cleanup, it also lets us…

Do stuff with GtkTextView that was not possible before

the new 'testtextview' demo found in gtk+/tests

As you can see, now the foreground, background and paragraph background colors of text in the text view can be painted with translucency to the background of the GtkTextView, this particular demo connects to the “GtkWidget::draw” signal and simply fills in the background with checkers.

Of course most of the time you use a text view with a default solid white background for readable text, however this new feature does open up some…

New Possibilities

TextView rendering translucent text over a downscaled image of Iguazu falls.

As usual, this installment of “GTK+ feature of the week” was brought to you by Openismus GmbH.

Currently the code is available for your compiling pleasure in the rgba-texttags branch.

What follows here is just my own personal brain storm…

Ideas for GTK+ hackers

While going over the GtkTextView code, which we all know is a fearsome animal not to be taken lightly or hunted in plain sight I came up with a bit of an idea of how we could start taming this beast. Text View code is not horrible really, it just hasn’t received much love over the years and needs a little tidying up.

Currently we have these components:

  • GtkTextBuffer and friends (GtkTextIter, GtkTextMark, GtkTextChildAnchor, GtkTextTag, GtkTextTagTable): This is all a part of the TextView’s data model, it’s very modular and it all makes sense. Sure, it’s much code but all of that code is well segmented and justified as far as I can see.
  • GtkTextBTree, GtkTextLine, GtkTextLineSegment: Some caching on the view side of things, all of this is private and caches things about how to render segments of text from the buffer model into the view, still quite modular code and probably very well thought out and well written.
  • GtkTextLayout: The heart of the beast where all the cached data is traversed and prepared for rendering, this is probably where most hackers are scared off… while most if not all of the code in there is well justified and needed, this code could probably be better organized and have more rich comments to guide the hacker who’s looking at this code for the first time.

Now the fun part:

  • GtkTextAttributes/GtkTextAppearance: This is something of a customized PangoAttribute the text appearance is a structure holding all the needed attributes for rendering a ‘segment of text’, a segment being a continuous string of glyphs that all share the same attributes… actually the GtkTextAttributes structure holds a GtkTextAppearance member, they could probably be merged into the same structure and the apis which handle this could be better defined (currently we have GtkTextTag modifying the attributes manually with exposed struct members and the like).
  • GtkTextRenderer (found in gtktextdisplay.c): This is the really fun part, this jem is actually a derived PangoRenderer class and takes over the actual rendering of the glyphs (the fact this jem already existed is why it was relatively easy enough to add RGBA rendering of the pango glyphs into the mix)… The GtkTextRenderer object inspects the custom GtkTextAttributes and uses these extended PangoAttributes to render the glyphs.

Now without digging into the ultra-complex innards of GtkTextLayout, I thought it would be a sweet idea to give GtkTextRenderer and GtkTextAttributes a bit more air time… these are for the most part internals of GTK+ and would not become part of the public api but… we could use the GtkTextRenderer to render text in GtkLabel and GtkEntry (and possibly elsewhere).

By working a little bit towards fine tuning the GtkTextRenderer and attributes to have a sane internal API and reusing it, we would already be able to render text from GtkLabel and GtkEntry using RGBA text attributes… at a relatively low cost. Also, a move in this direction would help demystify the text view code somewhat (at least hackers would be more familiar with GtkTextAttributes and GtkTextRenderer and would not have to consider those entities while looking at the rest of the huge code that is GtkTextView).

Anyway, just some food for thought for anyone who might be interested.

Glade learns some new tricks

It’s been a few weeks and Glade has learned a few new tricks worthy of showing off.

Today’s release of Glade 3.9.2 was brought to you in a large part by our hero Juan Pablo Ugarte the Magnificent (and the crowd goes wild !)

Project widgets go off screen

Having the project widgets go off screen allows us to draw over the whole project widget hierarchy as a single canvas, resulting in added sexiness for Glade:

Magnificent selection drawing brought to you by our hero Juan Pablo.

It also allowed us to simplify the code base to some extent where it comes to handling events on widgets, not to mention event handling on project widgets is more solid and fail safe now (GtkComboBox can finally be selected in the workspace; something that has been escaping us for years now).

Glade workspace gets a new look

Something I’ve wanted for a long time but never took the time to implement is to have a more coherent workspace and view of the project, recently I went and added notebook tabs to navigate through open projects and now our hero added the final touch by allowing the user to scroll through all the project widgets in the Glade workspace:

Glade's coherent and magnificent new look, also brought to you by our hero Juan Pablo.

With this new touch to Glade’s UI, selecting widgets in the inspector treeview on the right cause the workspace to automatically scroll to the selected widget and ensure it’s visibility. In the future one of our plans is to add some drag’n’drop support to the workspace so that project widgets can be easily moved from one toplevel to another (however the new interface already makes it easier and more obvious for the user to cut/copy widgets and paste them in other toplevels).

GtkComboBoxText

In other, practical news, Glade receives some support for new widgets and objects, one of them being the GtkComboBoxText widget and sports a custom editor to make it easy for the user to create a simple dropdown list using GtkComboBoxText:

An editor to allow editing of GtkComboBoxText items

This little treeview here lets you easily type in the text for each item, delete items intuitively with the Delete key and reorder the items using the built-in Drag’n’Drop functionality of the treeview. Just type into the < Type Here > row to add new items. Click on the icon on the right to edit the i18n attributes (translator comments and context etc.).

GtkFileFilter and GtkRecentFilter

These filtering auxiliary objects have finally become more useful in Glade as well, now it’s possible to add a list of filename patterns or mime types for the filters (these objects can be set for GtkFileChooser and GtkRecentChooser widgets respectively).

Add patterns and mime types to your filters.

For these editors I was able to just reuse the editor I wrote for editing GtkComboBoxText by simply disabling the translation features, I borrowed the < Type Here > editing paradigm from the signal editor since I thought it was a great way to offer lots of functionality while saving on screen real estate (no need for clumsy “Add” buttons in the UI)… it also makes for good consistency in Glade’s UI.

Glade is now a GtkApplication

This was just a weekend code spike which was surprisingly easy to implement. Using GtkApplication automatically makes Glade a single instance application practically for free. It also opens the door to opening files properly from whichever uris are supported by GIO. Currently Glade still only opens files that are on a local harddisk, but the only thing stopping us from opening remote files handed to us via the GFile is a hand full of logistics in the core (handling read-only mode, displaying a proper project name even if there is no local path to save it to; that kind of internal business logic).

So, Glade 3.9.2 is now available for download at http://download.gnome.org/sources/glade/3.9/, I only just published this tarball so the disks should still be warm: i.e. get them while they’re hot !

The Glade DL

This is a general post on the Glade downlow, what’s been going on, and what is to be.

Lets start by discussing what’s the game plan for Glade and GTK+ 3.0, I’ve already detailed this in recent release mails and some bug reports it should also be discussed here.

Glade 3.8

This release of Glade will depend on GTK+ 2.24 and include libglade support, support for legacy catalogs such as libgnomeui and libbonoboui widgets and will still have the project conversion feature to convert your old libglade projects to use the GtkBuilder.

The theory behind releasing 2 Glades simultaneously is that Glade 3.8 will serve as a decent migration path to ease transition of projects transitioning from GTK+ 2 -> GTK+ 3, or from libglade -> GTK+ 2 -> GTK+ 3.

If an older project can be run with Glade 3.8, targeting GTK+ 2.24 and use no deprecated widgets, the glade file should then be ready to load up into Glade 3.10 and already usable with GtkBuilder in GTK+ 3.0.

Glade 3.10

This release will depend on GTK+ 3.0 and will not support libglade, will not support any of the old and deprecated widgets from the GTK+ 2.x line and will evidently, not have any conversion routine. Furthermore the libgladeui-2 core library will guarantee API and ABI stability so that IDE’s like Anjuta will never be broken by an upgrade to the underlying Glade core (not to mention, the code cleanup required to achieve an ABI stable core made the Glade sources considerably more readable, so it will be much easier from now on for you to contribute to Glade… which is what we’re counting on ;-)).

Both of these releases will be made simultaneously, we’re going to try our best to coordinate the release to be at the same date that GTK+ 3.0 is released.

Glade 3.8 and Glade 3.10 will be parallel installable.

Map of Glade 3.8 related files:

  • $prefix/bin/glade-3 (Glade’s frontend executable).
  • $prefix/lib/libgladeui-1.so (Glade’s core library)
  • $prefix/lib/glade3/modules/*.so (Glade’s plugin modules)
  • $prefix/share/glade3/catalogs/ (Catalogs for Glade)
  • $prefix/share/glade3/pixmaps/… (Glade’s graphical resources including widget icons)
  • http://download.gnome.org/sources/glade3/3.8/ (Will be the download location for 3.8 tarballs)

Map of Glade 3.10 related files:

  • $prefix/bin/glade (Glade’s frontend executable).
  • $prefix/lib/libgladeui-2.so (Glade’s core library)
  • $prefix/lib/glade/modules/*.so (Glade’s plugin modules)
  • $prefix/share/glade/catalogs/ (Catalogs for Glade)
  • $prefix/share/glade/pixmaps/… (Glade’s graphical resources including widget icons)
  • http://download.gnome.org/sources/glade/3.10/ (Will be the download location for 3.10 tarballs)

Glade things renamed

In light of the coming renames of ‘glade-3’ exec to be ‘glade’ and the install directory changes, we’ve recently renamed the actual product and repository information to simply be ‘glade’ instead of ‘glade3’.

  • http://git.gnome.org/browse/glade/ (Glade’s new git repository name)
  • https://bugzilla.gnome.org/browse.cgi?product=glade (Glade’s new bugzilla product)

Other Glade news

Over the last month or two I’ve been working hard on Glade, the current buglist right now has only 195 bugs on it, where only a month or so ago the list was somewhere between 300 and 400 bugs long. Lots of crashers have been fixed and lots of refactoring done as specially for Glade 3.10.

But besides all that under-the-hood goodness there are a couple things I can show off with screen shots (unfortunately though; I dont have a sexy theme installed for my GTK+ 3.0 sandbox… maybe someone can eventually fix that for me).

Glade loading progress bars

Alot of Glade files only contain a few widgets, or a few hundred widgets… but alot of the time Glade files can contain > 1000 widgets. Loading speed for these files can be slightly optimized but there is a limit to that optimization.

So to avoid freezing the UI completely we’ve added a progress bar so that you can continue your work and have some reliable feedback about when your project will finish loading up:

Loading a project with a progress bar

As you can see, a notebook tab is by far the best place to put a progress bar (I don’t think I’ve seen this done before but I think it looks just perfect).

Ok moving on to something a little more useful…

Glade allows you to edit GtkActionGroup

Using Juan Pablo Ugarte’s original menu editor, which has been reused to edit GtkTreeView and add GtkCellRenderers and has not failed me yet, I simply applied the code towards editing action groups and allowing the user to add actions to groups:

The GtkActionGroup editor

Users who are already familiar with this editor which we use more and more in Glade will find it very easy to setup an action group with this, I suspect.

Glade allows you to add tags to a GtkTextTagTable

This has been a long standing feature request, GtkTextTagTable is not directly useful in a Glade project however for programs that might use a GtkTextView; setting up a text tag table and symbolic text tags can be useful to apply text attributes to a region of a GtkTextView/GtkTextBuffer (i.e., lets say I want to call this paragraph “Important” and next month I want important text to be green and italic instead of purple and bold, I just go and edit the “Important” tag in the Glade file and I’m done).

The GtkTextTagTable editor

Glade now supports editing the GtkToolPalette widget

Editing a GtkToolPalette

To edit a GtkToolPalette we use the same editor as above, in the same way that we use it to edit GtkToolBar or GtkMenuBar, only in this case we support adding GtkToolItemGroups to a GtkToolPalette and then support adding GtkToolItems to GtkToolItemGroup.

Note here that the GtkToolItemGroup supports use of a custom ‘label-widget’, the above screenshot shows us adding a GtkFrame as the group’s label widget and then adding a label to it, of course it’s not a realistic example of how that might be used, perhaps someone would add a horizontal box with an image and label though.

New GladeSignalEditor

Johannes Schmid has written new code for Glade’s signal editor. Currently the UI looks just about the same as the old signal editor with some minor improvements. However the underlying code has drastically changed so that GladeWidget uses a delegate object to report the signals via a GtkTreeModel interface implementation. This was supposedly the missing link that will allow Anjuta to support Drag’n’Drop of signals from Glade’s signal editor into other active portions of Anjuta’s UI (I suspect probably to automatically create function prototypes in a given language for the signal callback dragged into the GtkSourceView or fancy things like that will happen).

Glade is starting on a Preview feature

Preview Feature

The new preview feature by Diego Aurélio Mesquita is in it’s preliminary stages but currently works to the specs that I originally wanted, mainly it runs out of process and uses a ‘glade-previewer’ program that responds to some very basic IPC commands sent to it via stdio to update itself at some appropriate times and to exit when requested. The main reason that I wanted this to be out of process is because there is always the possibility that GtkBuilder can crash while loading the xml, yes it’s highly unlikely but possible.

Some things we want to add to the preview feature:

  • Override desktop settings, it will be nice to allow the user to configure various desktop settings to see how the app will look and feel on different desktop configurations.
  • Override theme, this would allow the user to see how their app will look with a specific theme, it should be particularly interesting for example, if the application developed in Glade is targeting a specific handheld device and the user wants to know how the app looks with the hand-held’s theme before compiling it and installing it onto the said device (this can even be interesting for theme authors to see how their theme pans out with various glade files and widget configurations loaded).
  • Report errors reliably, if for any reason GtkBuilder has some problems with the loaded xml, the previewer program can report back the stdout and it can be displayed to the user in a warning window.

Icons

Dolean Samuel has started working on some new icons for the palette, this work was initiated by a google code-in task and we’re tracking that work in this bug. Hopefully Glade for GTK+ 3.0 will come with all the much needed icons as a result.

Well, I think this covers most of the recent developments on Glade.

As usual, Openismus deserves our thanks for tasking me full time on Glade.

Lets make GTK+3 rock !

Bonus Icon View refactor

This is one of the final installments on the GtkCellArea TreeView refactoring saga, we’re having a GTK+ team on Tuesday where we’ll discuss this and other various things and finally, land the beast that is GtkCellArea.

Actually as a passing note, the GTK+ team meeting this week is potentially the last one we’re going to have before freezing GTK+ 3.0 apis. If there are glitches, problems, polishing work for GTK+ that you know is important and requires breaking API/ABI, it would be a good idea to present your issues at this meeting.

This is a bit of a surprise post I was not planning on writing but I was surprised by the success of the icon view refactoring work so I thought it would be a good idea to share this here.

Bonus GtkIconView Refactor

I’m pleased to say that the refactored GtkIconView actually works much better than the old icon view, all in ~1700 less lines of code.

A small example of this (without showing off configurable cell alignments and the potential of adding some custom GtkCellArea to your icon view to lay cells out in more custom ways) is already viewable in the tests/testiconview test.

It seems that the former icon view did not handle horizontal layout of cells very well:

This shot shows the GtkIconView with a horizontal "item orientation" before refactoring.

As you can see the cells in this icon view are not aligned, the effect is “yuck”. However this was not noticeable when using a typical GtkIconView with only a constant size pixbuf on the left and variable length text on the right, the “yuck” starts to show through when using variably sized cell renderers on the left followed by more, unaligned renderers.

The new Icon View test in the same configuration:

This shot shows the same icon view test configured horizontally using the new refactored code using GtkCellArea.

Now all cells are correctly aligned horizontally no matter the size of leading cells.

You’ll have to just trust and forgive me for “Icon 5” and “Icon 6”, it actually does not appear that way. Only when using the screenshot tool and releasing the selected area it causes a rerender of the GtkIconView… it seems the screen capture is performed before the widget has time to finish re-rendering itself.

And that’s not all

The GtkIconView still doesn’t handle progressive calculation of rows like GtkTreeView does (it calculates the sizes of all icons in one go, sorry this refactor did not change that, we still have to take care of that).

However I was curious about the performance difference so I inserted a GTimer into the GtkIconView layouting procedure, which was pretty easy to analyze (since it does everything in one pass, it was pretty easy to compare).

Before refactoring (that is, requesting the size of each GtkCellRenderer individually and doing some complex calculations about where each renderer is placed inside the “icon” or “item”) I got these results:

  • After adding 10,000 items to the same test (that’s what the “Add Many” button does), the former icon view took 6.225222 seconds to initially layout the newly added items.
  • With the new icon view (after refactoring), adding the same 10,000 rows took 3.492693 seconds.

Once the sizes are initially requested for newly added rows processing is a bit cheaper, however the whole icon view needs to be relayed out every time it gets a new allocation.

With the old code, in my console after resizing the window pane (with > 10,000 items) I got:

relayout took 3.142941 seconds
relayout took 3.150152 seconds
relayout took 3.149025 seconds

With the new code for the same items I got:

relayout took 1.252735 seconds
relayout took 1.339084 seconds
relayout took 1.313939 seconds
relayout took 1.287726 seconds

So in conclusion, not only does the new icon view render cells with better alignments, not only does it do so in 1700 less lines of code… it also calculates the cell positions and lays out the icons in literally half the time it took with the old icon view code.

The icon view refactor work is now ready after ~2 days of work and available on the icon-view-refactor branch.

Enjoy !

GtkCellArea continued…

This is another installment on the GtkTreeView refactoring saga. We’ve come a really long way with this and have the first phase of GtkTreeView rework almost 100% complete.

I’ve been working around the clock with our treeview master Kristian Rietveld, who worked out the initial integration of GtkCellArea into GtkTreeViewColumn and has been reviewing my patches against the treeview code every chance he gets… I know it’s been hard to keep up between meetings and other obligations but really, thanks a lot for your help on this Kris !

Some of the good news is:

  • GtkCellArea as an abstract class opens up the road for eventually more implementations, for instance tabular cell areas or areas that embed widgets can be developed and then used directly by GtkIconView, GtkTreeView, GtkComboBox classes without any need to change code in those classes.
  • GtkCellLayout widgets only need to interface with a single GtkCellArea instead of manage a list of cells, GtkCellLayout only requires that a layouting widget implement the GtkCellLayoutIface->get_area() virtual method and then does everything under the hood on the layouting widget’s behalf (this helps to remove lots of code from lots of classes).
  • GtkCellArea provides “cell properties” to define the relationship of GtkCellRenderers inside their area. Using this generic interface (just like GtkContainer “child properties”) GtkCellLayout’s GtkBuildable implementation implements a <cell-packing> custom tag and allows cell properties to be defined from the GtkBuilder UI format. (something we’ve been missing for a long time is a way to specify which cells “expand” in a GtkTreeViewColumn from GtkBuilder format).
  • Since GtkCellArea provides a generic way for handling events, and since recent developments of GtkWidget (i.e. widgets can be “drawn” and can be rendered ofscreen and such), its possible to implement a GtkCellArea subclass that contains and renders widgets (which can even handle events).
  • Also, GtkCellArea handles the driving of focus from renderer to renderer inside an area (as well as the painting of focus on the renderers), further reducing the workload of cell layouting widgets.
  • Finally, GtkTreeViewColumn has been reworked to replace it’s management of GtkCellRenderers with a single abstract GtkCellArea (not to mention, GtkTreeViewColumn struct members are now safely in a private data structure and GtkTreeView and Column code have a much cleaner “split”).

Some of the bad news is:

  • GtkCellArea replicates lots of api. For instance “cell properties” would really be GContainer child properties if we were to have a GContainer interface, “focus navigation” could really be implemented as a GtkFocusable interface that might not be a GtkWidget and finally even event handling could be implemented as a GtkEventable interface of sorts. However, after doing all of this and actually getting it to work, I dont think this api replication is such a bad deal. A GContainer interface providing child packing properties and object hierarchy outside of the GtkWidget hierarchy is something I’ve wanted for a long time however it’s just not exactly what I’ve been working on these days.
  • Another disappointment is that GtkTreeView has not been fully reworked to harness the power of the new height-for-width apis yet. We preferred a safer and more conservative development procedure for GtkTreeView: dump all the cell renderer man-handling in favor of an abstract GtkCellArea first and then leverage the height-for-width apis afterwards once we know everything is working.

Ideally I wanted GtkTreeView to actually calculate and allocate rows “height-for-width” with wrapping text and the works, all in one go but I also think it’s wise to do this stuff in comprehensible iterations… at least the framework is here and we don’t need to break any more api/abi at this point.

However, that being said, here’s a peek at some of the new things that are already possible with the new and improved GtkTreeView code without adding any fancy GtkCellArea subclasses or actually doing the height for width geometry.

Configurable Cell Alignments:

To show off cell alignments (and test some inner workings) I’ve updated a test that we already have in gtk+, here’s a look at the good old ./tests/testtreeedit in tact and as we are used to seeing it:

testtreeedit updated with some alignment controls, still appearing in the way we are used to seeing it.

Ok nothing new here, moving along, for completeness sake (and just to express what exactly is “configurable” in terms of cell alignments), let’s look at an ugly configuration that no-one is likely to use:

The "ugly" configuration here shows the same test case with the 3rd cell "unaligned", everything looks jumbled up and it's probably desirable to align the 3rd cell in this case.

Well, that’s an ugly configuration sure, but sometimes unaligned cells can be useful.

Here’s an example of how an unaligned cell can be more useful:

This shot shows the configuration with the fourth (icon) cell "unaligned".

Ahh this is much better, I’ve always been annoyed at the alignment space between a variable length text renderer and an icon that logically belongs with the text. In this case we can have an icon that is “related” to the variable length text placed nicely to the right of it without any undesired space.

Vertically Oriented GtkCellAreaBox:

Here we see a GtkTreeViewColumn on the left using the normal horizontal orientation along side a GtkTreeViewColumn on the right using a vertically oriented GtkCellAreaBox to render the cells.

That’s right, vertically stacked cells inside a GtkTreeViewColumn was not possible before this. If you’ve used the popular bit torrent client “transmission”, you will find that they’ve achieved a similar look to the above image by way of implementing a custom cell renderer for their needs. With GtkCellAreaBox we should be able to cover most any desirable layout of cells inside an area without any custom code needed (with a GtkCellAreaTable, we can probably cover any conceivable layout that the user might desire without the need for any custom code).

Documentation:

Now that I’m tidying up and trying to close all of this work I’ve been doing over the past 2 months I’m doing the polish work and writing loads of documentation. The bulk of the documentation is not pertinent to users as it tries to discuss how GtkCellLayout widgets actually work (unless GTK+ users are into writing custom treeviews and the like, of course). Nevertheless having the documentation is probably a good step to help us keep track of how things are done inside GTK+.

  • Documentation for the GtkCellArea itself (the bulk of the documentation).
  • Documentation for GtkCellAreaContext (a context to store geometrical details for a collection of rows).
  • Documentation for GtkCellAreaBox (the first cell area implementation, an orientable box area).
  • Documentation for the GtkTreeMenu (GtkComboBox now delegates it’s menu related work to this new class, which I showed off already in previous posts).

Since the deadline for landing these new apis is getting dangerously close, I hope to land them very soon and then move on to giving GtkTreeView (and GtkIconView) real height-for-width capabilities afterwards, as this part wont need to entail any API breakage.

Coming up up next: Episode “lets land this code” and then the season finale, Episode “Height for width icon views and treeviews”.

Stay tuned ;-)