When the Levee Breaks

Yesterday I decided to start working on the porting of the Gtk2::SourceView Perl module to the new upstream API. For my convenience, and because I know I’ll probably screw up, I decided to use a local git repository so I can experiment with all the branches I want before hitting CVS. Yes, you read that right: the Perl GTK+/GNOME bindings still use CVS on SourceForge.net1. Thus, I decided to import the whole gtk2-perl repository into a git one using git-cvsimport, and – lo and behold – after four hours of checkout, I got it on my machine, complete of full history.

The layout of the bindings modules is composed of a single CVS module and all the Perl modules are inside it; this is far from optimal with git2, so I proceeded to split up each Perl module into its own repository, with the help of git-filter-branch – a new command taken from the Cogito suite and added to the 1.5.3 release of git.

The filter-branch command is extremely powerful: it rewrites the history of a repository (which is a destructive operation) by passing a filter function on it. It has a set of predefined filters and contexts of operations, so what you need to do to split out a sub-directory into its own repository is call:

  $ git filter-branch --subdirectory-filter directory refspec

and after that you get all the files filtered out marked as new or modified, so you can use git reset --hard to get rid of them, and have your sub-directory contents as the only recognised content of the repository.

Unfortunately, you can’t really filter out a direct import of a CVS repository: git-cvsimport stores branches and tags, and filtering will most likely create dangling objects; so, what I did was cloning the original repository, to get rid of the local branches, and remove all the tags:

  $ git clone --no-hardlinks /tmp/gtk2-perl Gtk2-SourceView.git
  $ for TAG in `git tag`; do git tag -f -d ${TAG}; done

The --no-hardlinks switch is important for later – I have to thank Ricardo Signes for this tip; in short: it makes git use real copies instead of hardlinking files when cloning a local repository, and will make the garbage collection and pruning phases actually work and prune the unused objects from the git database.

At this point, I just filter-branched and reset:

  $ git filter-branch --subdirectory-filter Gtk2-SourceView HEAD
  $ git reset --hard

and then called:

  $ git gc --aggressive
  $ git prune

and finally obtained my local git repository of the Gtk2-SourceView module from the original CVS repository – with all the history on HEAD preserved. The good part is that the entire set of operations is very repetitive, so it’s suitable for scripting3. Yey for git! :-)

  1. there has been talk about moving them to GNOME CVS, then to SVN, but in the end the maintenance burden would be too high, and some of the members of the team would need at least SVN accounts anyway []
  2. or any other SCM software that is not CVS, for that matter []
  3. I did write a small script which extracted every Perl module sub-directory into its own git repository – but it’s mostly 50 lines sugarcoating the core 5 lines of actual work []

Going Mobile

At the end of this week I’ll be in Copenhagen for the Nordic Perl Workshop. I’ll give two talks about GNOME and Perl: the first one is about binding GObject-based libraries in Perl and using the Perl bindings in order to write GObject-based native Perl modules (and get all the GObject features); the second one is a GTK+ tutorial-slash-faq-slash-best practises for Perl developers. I’ll be around in the city from the 27th till the afternoon of the 29th (I have to get back early, unfortunately).

Mood to Burn Bridges

Whoa, really long time no blog.

I can’t say I’ve been really busy with GNOME-related stuff: work mostly blocked me from doing much. After GNOME 2.16 I’ve released gnome-utils 2.16.1 containing a couple of fixes to Screenshot, and one of them was written by Ross; I’ve also released not one, not two but three versions of the Gnome2::GConf perl module wrapping GConf, two of them today, thanks to the awesome work of Laurent Simonneil, who provided two patches for fixing the schema objects handling and for wrapping the recursive unsetting in the Gnome2::GConf::Client class. Those two patches are what Laurent needed for creating a FUSE-based file system (written in Perl using the FUSE and GConf bindings) for browsing the GConf database.

You can find the latest releases of Laurent’s GConf-FS, as well as the latest Gnome2::GConf module release, on CPAN.

now listening: Neko Case, Furnace Room Lullaby

Documentation

Davyd, the GTK+ Perl bindings come with documentation in the perldoc format (which works upon man); each object has its unique perldoc page, so if you need to know all the methods of the Gtk2::TreeView widget, all you have to do is open a terminal and type:


$ perldoc Gtk2::TreeView

And you’ll be greeted by a screenful like this:

TREEVIEW(1)         User Contributed Perl Documentation        TREEVIEW(1)

NAME
       Gtk2::TreeView

HIERARCHY
         Glib::Object
         +----Glib::InitiallyUnowned
              +----Gtk2::Object
                   +----Gtk2::Widget
                        +----Gtk2::Container
                             +----Gtk2::TreeView

INTERFACES
         Glib::Object::_Unregistered::AtkImplementorIface

METHODS
       widget = Gtk2::TreeView->new ($model=undef)

           * $model (Gtk2::TreeModel)
...

Support of man pages, by the way, is sorely missed inside GTK+ itself: instead, you’ll have to use devhelp or point your browser to a long URI; I love devhelp, but I’m usually coding (with) development releases of many libraries, all installed inside a jhbuild sandbox so in order to make it find the autogenerated API documentation you’ll have to build devhelp inside the sandbox too – which is unnecessary pain I’d like to avoid inflicting upon myself.

Anyway, perldoc to the rescue: at the end of the object page you’ll find the SIGNALS section – if the object’s class exports signals, that is – which looks like this:

SIGNALS
       set-scroll-adjustments (Gtk2::TreeView, Gtk2::Adjustment, Gtk2::Adjustment)
       row-activated (Gtk2::TreeView, Gtk2::TreePath, Gtk2::TreeViewColumn)
       boolean = test-expand-row (Gtk2::TreeView, Gtk2::TreeIter, Gtk2::TreePath)
       boolean = test-collapse-row (Gtk2::TreeView, Gtk2::TreeIter, Gtk2::TreePath)
       row-expanded (Gtk2::TreeView, Gtk2::TreeIter, Gtk2::TreePath)
       row-collapsed (Gtk2::TreeView, Gtk2::TreeIter, Gtk2::TreePath)
...

As you can see, you have the signal name, the arguments of the callback and the eventual return value. The “gotcha” is that there are no named arguments, so you’ll have to know the C counterpart of the signal; this might be a worthy addition to the API documentation generation module.

Another dirty trick is to use the Data::Dumper module inside a callback you don’t know which arguments passes:


sub my_unknown_callback {
    use Data::Dumper;

    print STDERR Dumper(@_);
}

Which will print whatever the callback gives you – even descending into hashes and arrays if it knows how to print their contents.

If you don’t want to use a terminal and the perldoc command, there’s the Gtk2::Ex::PodViewer widget on CPAN, which comes with a podviewer application which you can use to browse the entire Perl documentation available on the system,or you can download PodBrowser which does a bazillion things more.

Tides that I tried to swim against

gtk-recent: For those who missed the mail on gtk-devel-list, language-bindings and desktop-devel:

Unfortunately, when importing the GtkRecent API in GTK+ I made a mistake and these two functions have been erroneously left inside the GtkRecentChooser interface API:


  gtk_recent_chooser_set_show_numbers()
  gtk_recent_chooser_get_show_numbers()

These two functions try to set the “show-numbers” property, which is installed only by GtkRecentChooserMenu and it’s not one of the properties defined by the GtkRecentChooser interface. Using these functions on a GtkRecentChooserMenu (or any other custom GtkRecentChooser implementation which defines a boolean “show-numbers” property) will yield the expected results, while using them on a GtkRecentChooser implementation that does not support the “show-numbers” property will result in a warning.

Since we are in a stable release we can’t mark those functions as deprecated, and we cannot remove them without breaking the API. You are advised not to use these functions: use the GtkRecentChooserMenu functions instead:


  gtk_recent_chooser_menu_set_show_numbers()
  gtk_recent_chooser_menu_get_show_numbers()

Language binding authors should not bind those functions, but bind the GtkRecentChooserMenu functions instead.

These functions will be marked as deprecated as soon as GTK+ will branch off for the 2.11/2.12 cycle, so you’ll have to bear with this inconsistency for a short period of time.

language-bindings/1: By the way, gtk2-perl now supports the GtkRecent code in HEAD, thanks to the hard work of Torsten kaffee Schoenfeld who fixed most of my first iteration binding code and wrote the tests for it.

language-bindings/2: I also finished the Perl bindings for Clutter, as well as the Python ones. As I changed Clutter to behave like GTK, with the ClutterActor objects being created with a “floating” reference count, you’ll have to update Clutter to HEAD if you want to test the bindings. Beware that Clutter’s API is still a bit fuzzy at the moment. Of course, if you find bugs in the library or in the bindings, be sure to report them.

Now Listening: Last-exit, Neighbour radio

Tap Dancing on a Mine

I’ve just released version 1.031 of the Gnome2::GConf Perl module binding libgconf. In this release, thanks to Laurent Simonneau, I dropped the Gtk2 dependency, making Gnome2::GConf depend only on the Glib Perl module (and the libgconf C library, obviously).

Gnome2::GConf is mostly in maintenance mode these days so, even if this is supposed to be a development release there are no known issues preventing it from working in a stable environment. I don’t plan any more releases in this development cycle (remember that Gnome2::GConf is part of the GNOME Platform Perl bindings and as such it follows the GNOME release schedule) unless upstream API changes.

You can get Gnome2::GConf either from Sourceforge.net or from CPAN (as soon as both update their state).

On a releated note: as the next release of Gtk2 will support GTK+ 2.10, and it’ll have printing support, I plan to discontinue the Gnome2::Print module binding libgnomeprint and libgnomeprintui; obviously, I’ll still maintain this module, but I don’t plan making any new releases unless for (serious) bug fixing.

How Good It Can Be

Corey, why on earth should we switch from an entire set of system configuration tools written in Perl to another one written in Python? Just for the sake of Python? Just because there are more Python zealots^Whackers on GNOME than there are Perl ones?

I understand that Ubuntu loves Python, but please: rewriting every tool in Python just for the sake of it is totally useless. What Python gives us over Perl, for system configuration backends? (No, it’s not a rethorical question: I’m serious).

Feeling yourself disintegrate

life: In the past 24 hours I’ve had:

  • a bad cold
  • a sore throat
  • some lines of fever
  • water spilled on my laptop’s keyboard
  • thus, a broken Ctrl key that would not disengage itself
  • and, finally, a broken Ctrl key that would not work anymore

The last problem was solved by switching Caps Lock and Ctrl (thanks to the Gnome keyboard capplet; but I’d prefer to be able to use the windows key as a replacement, as it’s nearer to the original key), as my finger memory could not adapt to using the right Ctrl key for stuff like workspace navigation.

doap: like all the cool kids, I’m too working on a way for handling DOAP streams, except that I’m doing it in Perl and not in fancy Python (I’m using the Redland library, though). Unfortunately, there’s no such Perl module for basic handling FOAF and DOAP data – so I’ll need to create them first, then work on a nice authoring interface.

perl: also, I’ve been working on Perl bindings for the Maemo libraries, as one of the goals for the 2.0 version of the platform is having language bindings working. From inside the scratchbox (version 0.9.8.5 comes with perl 5.8.4), I downloaded the GLib and Gtk2 modules from CPAN, and even with some failures, they basically worked out of the box; then I began binding stuff (hildon-lgpl, hildon-libs and hildon-fm for starters, libosso will be next, as it needs the DBus perl bindings), and in less than twenty minutes I had my own nice little hello world application written (sorry, no screenshot at the moment).

Now Listening: Led Zeppelin, Stairway to heaven

Glib::Builder

I’ve began working on a new build environment for Glib, Glib::Builder.

Glib should use it, and provide it for Gtk2, Gnome2 and the other Perl bindings; well, hopefully, and when it’s finished, that is. It should also supercede not only ExtUtils::Depend but also Glib::MakeHelper and a bunch of the code we are currently using inside our Makefile.PL files. Also, it should be easier for us to port a single module to Module::Build, if we ever decide to ditch ExtUtils::MakeMaker.

How does it work?

Simply by using the right tool for the job – that is Perl and pkg-config. Each Glib-based extension will provide a pkg-config file, and inside it will export some variables useful to retrieve all the stuff that currently is exported by ExtUtils::Depend; using pkg-config we can make all these data available to every project out there that can’t rely on ExtUtils::Depend – like the programs exporting an embedded Perl interpreter (gedit, gaim, xchat, etc).

How should it look like?

This is how the Makefile.PL for a Perl module named Foo::Bar, and binding libfoo-bar would look like using Glib::Builder:

  use Glib::Builder;

  # optional code generation using Glib::CodeGen goes here

  my $build = Glib::Builder->new(
      MODULE_NAME => 'Foo::Bar',
      VERSION_FROM => Bar.pm,
      PKG_REQUIRES => {
        'bar-2.0' => '2.0.0',       # C library we depend on
        'glib-perl-2.0' => '1.100', # Perl bindings for Glib
        'gtk-perl-2.0' => '1.100',  # Perl bindings for GTK
        'foo-perl-1.0' => '0.800',  # Perl bindings for Foo
      },
      XS_FILES => @xs_files,
      PM_FILES => %pm_files,
      TYPEMAPS => qw(foo-bar.typemap),
      PKG_CONFIG_FILES => qw(foo-bar-perl-2.0.pc.in),
      DOCTYPES => 'foo-bar.doctypes',
      COPYRIGHT_FROM => 'foo-bar-copyright.pod',
      ENABLE_API_DOC => 1,
    );

  $build->create_build_files if $build;

As you can see, every dependency check is done using pkg-config, which resolves for us all the stuff needed for creating the dependency chain. Glib::Build checks if the pkg-config file exports a specific variable, named perlincludedir, which should be exported by Perl wrappers for Glib-based libraries; the location inside this variable should hold all the typemaps, doctypes and header files needed for inheritance. Another variable, named perllibdir will include the location of the shared objects needed for compiling. The Foo::Bar module would also allow other modules to access its exported data by providing a pkg-config template file, which will create a pkg-config file with all the locations automagically resolved.

This will allow the creation of modules embedded into other Glib-based projects, just by using pkg-config and some auto-foo magic; Glib::Builder could even supply some m4 macros for it, or some Perl script to be used inside Makefile.am or configure.ac files.

All neat and stuff, but where’s the code?

Still living in my source tree. I plan to hack on it this month, but I’ve also got this semester’s finals, and some other stuff going, so I can’t really promise a release date. I really want this to be done, though. Also, since Glib, Gtk2 and the other gtk2-perl modules require special code, I’ll have to add functions for it, in order to keep their Makefile.PL as similar as possible to the template Makefile.PL: those are not (so) special cases of Perl wrappers, so I don’t want them to be treated as such.

There And Back Again

Again at home, after a week in Berlin.

The city is wonderful – now I understand why Marta loves it that much: the place is gorgeous, the people is warm and they really make you feel at home. Me and Marta were both a bit sad to leave – but we plan to return there as soon as possible, maybe even in summer, even though with the GUADEC 2006 moved at the end of June we’d already have our summer holidays covered. Time will tell.

We’ve done a ton of photos – but the last day’s worth of them (mostly about and from the dome on top of the Reichstag/Bundestag) were eaten by F-Spot; it was an older version of it, and I did the stupidest thing by deleting them from my card too, but F-Spot shouldn’t lie about having done the import and then really having finished just the thumbnailing.

While in Berlin we’ve met for a couple of hours Torsten Schoenfeld, another gtk2-perl hacker – well, he is the gtk2-perl Release Master and the Test Suite God, other than being more than Just Another Perl Hacker; he is a real pleasure to talk with and a great guy. If you ever come to Italy, you’re up for a beer, or more than one. ;-)

Now that the winter holidays are really over, let’s get back to work.

The gnome-utils release went fine (even though there’s a typo in the NEWS file I’ve submitted – dang!), and a bunch of bugs have been filed in Bugzilla. Keep them flowing, so I can know what doesn’t work. I’m off to add the window-size-saved-across-session feature that was added to the search tool, and to make the icon in the applet become a toggle button, instead of a plain icon.

Another project I’m working on is the build environment for the Glib Perl module and Glib-based Perl extensions; I began looking at Module::Build while in Berlin, but in the end, I came up with another solution – which will be easier to port to Module::Build later on, when that module enters the standard Perl base distribution. Anyway, I’ll talk about this issue later in a (lengthy) post, so stay tuned.

There are a bunch of fixes due for the libegg/recentchooser code, the main one being the sorting functions duplicated from the RecentManager object into the RecentChooser object; in the end, I’d like to remove all the sorting/filtering stuff from the RecentManager, and let all the UI built upon the RecentChooser interface provide their own sorting/filtering stuff. This would make the RecentManager object a thin layer upon the BookmarkFile object, and would really make things easier to be included into the GTK library. In the end, all the sorting a filtering is something that has to do with the display of the data that the RecentManager holds, so they do not belong into the manager itself. Other than this fix, I’ll begin working on a patch for the BookmarkFile object in order for it to land inside Glib, and a patch for the FileSystem object to use it for its bookmarks.