Good Intentions/2

gtk+: I’ve been working again on the RecentManager and in trunk you’ll see some new stuff, namely:

  • use GIO to determine the MIME type of a URI, on every platform supported
  • use the file monitoring API to avoid polling the storage file
  • add a GtkSettings property for clamping the recently used resources list to a 30 days limit

more stuff I’d like to add is:

  • small parser changes to GBookmarkFile, to reflect changes in the spec
  • bulk addition, for applications storing multiple items when quitting
  • new API needed to follow the usability review in bug 349541
  • moving the RecentItem icon code to GIO, and add API to extract the thumbnail

twitter: I’ve been using Twitter a lot in the past two weeks; it’s nice, it makes it easier to copy and paste a quote or a thought, and the 160 characters limit is an interesting challenge. As it’s been ages since I last wrote an application1, I decided to start writing a Twitter reader/writer — using GTK+, Clutter and Tidy; without much thinking, I opened gvim and started writing code in C2 — so, the obvious thing that happened was that I ended up writing a library yet again in order to use Twitter’s web API. luckily for me, libsoup has now a really nice API to work with; all you need is GET and POST to their RESTful API, retrieve the result, parse it through JSON-GLib, hide everything inside a new GObject and you have a wrapper around a web service. the application, you say? oh, I was sure I forgot something. well, it’s coming along — it just needs some work still.

  1. lately all I’ve been doing was writing libraries []
  2. hey, that’s what I do for a living, it’s hard to switch off; plus, I could reuse some of the platform libraries []

Rhyme the rhyme well

Jason, it’s not just the canvas: writing a simple 2D canvas is trivial — that’s why a lot of applications end up writing their own homegrown one.

The hard bits are the animation framework, the event handling and down to the integration with the existing platform. A generic canvas is hard, and you probably don’t want it to be developed inside gtk+ (not even for 3.0) — just like Cairo is not developed inside gtk+ but supersedes part of gtk+’s API.

As for 3D acceleration — I’m obviously biased here, so everyone should take what I write with a graintruckload of salt — but I maintain my view that if GNOME (and Linux) started heavily pushing towards more support for OpenGL, then we could get more market share1, more visibility and thus more leverage to make the currently closed source drivers more open. Intel understood this; AMD is now getting it; I’m pretty sure nVidia will — or they will be simply pushed into irrelevance by the open drivers developed by the community2. Let’s face it: other platforms and toolkits are pushing heavily on hardware accelerated 3D effects.

Let’s start aggressively work to get the platform into the XXI century.

update@2008-10-11T12:21+0100 — just as a sidenote: if you have a good CPU, Mesa and software rendering, Clutter will work. It won’t be fast for some operations (like scaling and, possibly, rotating), but in that case you should probably start contributing to Mesa to make it fast (there’s a lot of room for improvement).

  1. think Compiz, and how many more users it brought home just with a spinning cube []
  2. unless you are a gamer, and need the very best card as soon as it’s out just to play Crisis []

Paint the Silence

Weee, long time, no blog.

Dear Lazyweb,

is it at all possible to coerce the devilspawn also known as libtool to actually be quiet when compiling and printing something like the kernel compilation outpout – that is, something like:

  GEN autogenerated.c
  CC file1.c
  CC file2.c
  LINK output
  INSTALL output

I know how to do that with a plain Makefile, and how to do it for autogenerated files like the enumeration types and the GLib marshallers, but I have no clue where to start to make libtool behave.

Thanks,
Emmanuele

Rome Wasn’t Built in a Day

People often arrive on the #clutter channel1 with troubles building Clutter from SVN: dependencies, installation in non-common prefixes, etc.

Luckily, GNOME has Jhbuild, which is easy to set up2 and also allows custom modulesets for handling dependencies inside a separate root – to avoid messing up your box.

So, if you want to play with Clutter, here’s two Jhbuild modulesets:

  • clutter-0.4.modules – for the stable branch of Clutter, if you are developing applications
  • clutter-0.6.modules – for the development branch of Clutter, if you want to contribute to Clutter itself, or you want to write bindings for it

Just download the moduleset file of the branch you want to use, copy it into the modulesets directory of the Jhbuild checkout and then:

  jhbuild -m clutter-0.4 build pyclutter

or, if you have a fresh checkout of Jhbuild, simply do:

  jhbuild -m http://folks.o-hand.com/~ebassi/clutter-0.4.modules build pyclutter

thanks to Frederic Peters for fixing remote modulesets and pointing this out

The command lines above will build the stable Python bindings for the stable branch of Clutter, fetching all the needed dependencies. If you’re stuck on some external dependency, though, feel free to drop into #clutter and ask for help3.

Update@2007-10-12T17:51+0100: I’ve added the following meta-packages:

  • meta-clutter-core, depending on Clutter
  • meta-clutter-suite, depending on meta-clutter-core, Clutter-GStreamer, Clutter-GTK+ and Clutter-Cairo
  • meta-clutter-python, depending on meta-clutter-suite and PyClutter

You can use the meta-packages to pull in everything you need. As soon as I figure out a way to reliably depend on the other languages runtime environments, I’ll probably add their own meta-packages and a meta-clutter-bindings as well.

Have fun!

  1. IRC: irc.gnome.org – join today! []
  2. the wiki page linked has it running in less than ten easy steps []
  3. be sure to specify which distribution you have []

Porcelain

Today I committed to Clutter trunk ClutterScript, the initial support for defining the scenegraph using external files. You can think of it as the GtkBuilder equivalent for Clutter.

During the 0.3 development cycle we considered using XML and JSON, and opted for the latter because while XML is quite easy for applications to write, JSON is more geared towards human to read1. Also, JSON syntax is really parser-friendly, with only three barewords and six symbols.

Another nice thing about JSON is that many high-level languages already have some JSON module, so manipulating data streams would be quite easy for, let’s say, Perl or Python before feeding those streams to Clutter.

Defining a simple scene with JSON and ClutterScript is quite easy:

{
  "id" : "main-stage",
  "type" : "ClutterStage",
  "fullscreen" : true,
  "children" : [
    {
      "id" : "red-button",
      "type" : "ClutterRectangle",
      "x" : 100,
      "y" : 100,
      "width" : 100,
      "height" : 100
      "color" : "#ff0000ff"
    },
    {
      "id" : "green-button",
      "type" : "ClutterRectangle",
      "x" : 300,
      "y" : 100,
      "width" : 100,
      "height" : 100
      "color" : "#00ff00ff"
    },
    {
      "id" : "blue-button",
      "type" : "ClutterRectangle",
      "x" : 600,
      "y" : 100,
      "width" : 100,
      "height" : 100
      "color" : "#0000ffff"
    }
  ]
}

This will draw a red, a green and a blue square, 100×100 pixels of size, inside a full screen stage.
You can then retrieve the "main-stage" object (as well as any other object using its id) and connect signals and manipulate them with the usual Clutter API.

At the moment ClutterScript is not 100% complete – I still need to add support for defining behaviours (mostly a matter of defining an object syntax); complex properties parsing; merging (and, possibly, unmerging) of “snippets” of objects. Plus, obviously, more sanity checks in the scene building code.

To parse JSON there are a few C libraries, but I opted for writing a GObject-based one – which, in one of my usual moments of lack of originality, I called JSON-GLib. Clutter uses an in-tree copy because I might need API changes to make Clutter parsing code easier, but the library is already auto-tooled, tested and 100% documented (it is missing GObject deserialization, but that will have to wait). JSON-GLib is released under the terms of the LGPL and it’s available in my personal git repository, which you can clone with the usual:

  git clone http://folks.o-hand.com/~ebassi/git/json-glib.git

Update@2007-10-09T15:07+0100: Just landed in trunk: defining behaviours (not every type, complex types like the path-based ones are still to be implemented), merging tests and more sanity checks. Defining a rotate behaviour boils down to:

{
  "id"          : "rotate-behaviour",
  "type"        : "ClutterBehaviourRotate",
  "angle-begin" : 0.0,
  "angle-end"   : 360.0,
  "axis"        : "z-axis",
  "direction"   : "cw",
  "alpha"       : {
    "timeline" : { "loop" : true, "num-frames" : 300, "fps" : 60 },
    "function" : "sine"
  }
}

Really soon now: all behaviours, complex properties and more.

  1. obviously nothing prevents adding an XML parser, and use both []

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

Flying Teapot

Clutter 0.4.0 was, finally, released two days ago. Not only the core and add-on libraries but also the language bindings are available for this new stable release cycle.

We already started working on trunk for the 0.5/0.6 development cycle, which should hopefully lead up to another stable release in six months; there already is a nice list of features we are working on, but I’d like to see more requests, more patches ( ;-) ) and people working on even more language bindings.

Of Angels And Angles

GtkApplication class: I’ve updated the application class page on the wiki. Now, it has an updated layout of the API (which is what I’m currently working on) and the design requirements it should fulfil. While writing it I had some sort of epiphany about the whole library consolidation effort and its perception among the platform developers. Project Ridley as it stands is a double-edged sword: on one hand we’d like to have more functionalities moved from external libraries to GLib and GTK+; on the other hand, the size of the platform libraries maintainer teams is not growing at the same rate. If we are to move widgets, features and whatnot to GTK+ we must be sure not only that someone is actively working on them after inclusion, but also that someone is willing to work on the rest of the codebase, in order to review the patches leading to the inclusion of new functionalities. So, waiting for Project Ridley to come to the rescue is not going to cut it anymore: if you are proposing to move some functionality from a library to GLib or GTK+ be prepared to work on the whole code and not only on your pet feature.

GtkUnique: since a “single instance application class” doesn’t really make any sense without an “application class” to make it inherit from, I’m punting the GtkUnique inclusion in GTK+ until the application class lands in first – and that makes it part of the post-2.12 masterplan; hence, I’m going to remove the gtk namespace from gtkunique and releasing it as a standalone library for the time being. I’ll commit the namespace switch before this weekend: it’ll switch from GtkUnique to Unique; everything else will stay the same. Remember to check it out from GNOME SVN server:

  svn co http://svn.gnome.org/svn/gtkunique/trunk

GConfig: as I mentioned in the last blog post, I’m working on the next iteration of GConf. Aside from ongoing design and API churning, I’ve also submitted a talk proposal for the next GUADEC about how to tackle the whole ‘GConf issue’. GConf is part of the core GNOME platform, and it has been so since 2000; it’s almost seven years old, and now it begins to show its age. Since 2001, Havoc has been asking the community to implement the same set of (five) features; no one has answered his call yet. Maybe the community is to be blamed for this; maybe we need to rethink part of the GConf design to allow someone other than ‘the usual suspects’ to fix GConf shortcomings and add new features. For instance: the backend API is a really nasty piece of code and it’s not easy to drop a new backend into an existing GConf installation; probably, that’s also why, after all these years, we still have only the XML and had to wait a long time for the evo-ldap backends. I’m going to put a page on the wiki with what kind of API I’m thinking about.

talks: aside from the GConf talk, I’ve also proposed a talk/tutorial about the Perl bindings for GTK+. I’ll also do two talks about Perl, GObject and GTK+ at this year’s Nordic Perl Workshop which will be held at the end of April in Copenhagen.

Live Wire

Back from FOSDEM 2007, after a little detour in Helsinki.

I’ve opened a bug for the places support in GtkFileChooser: #413076. Attached to it you’ll find a patch; it should be taken with a grain of salt: it’s still a work in progress, but implements the main features and shows how the new API should work. In short, if your application need to use some predefined, user visible folder and you want to provide a link inside the file chooser, you need to create your bookmark file, drop it somewhere and call:

gtk_file_chooser_add_shortcuts_from_file (file_chooser
                                          "/path/to/bookmarks.xbel",
                                          NULL);

We’d need an intltool able to recognise the title (and eventually description) markup elements of the bookmark files and merge them into the translation pool, so that you can have the places already localised (the machinery is already in place in the patch). I’ll keep working on it, and finish up the implementation of the automagic places that applications can install in a common place and have it appear in every file chooser, based on the group or application name used in the bookmark.

I’m also working again on the Application class (the wiki page is really out of date with the current iteration I have been workin on – I’ll update it as soon as possible); now that the session management code has landed in libegg I will add hooks into the application class to have it do The Right Thing®. Other than an application class, GTK+ really needs a desktop abstraction – a simple API to know whether we are connected to a network, or to control the screensaver, or to launch the default browser/mailer/editor/whatever. For that to work properly we should really have a working configuration system like GConf moved below GTK+. I did some prototype API for a configuration engine, mostly stealing^Wtaking inspiration from alexl work on GVFS (which already has a nice and clean API); will probably have something usable soon.

Like Eating Glass

Desktop-devel-list (d-d-l) is an interesting place. You follow discussions that usually tend to fork off, moving through tangential arguments; but, in the end, some stuff keeps turning up. Lately, for instance, every thread seems to end up on discussing about Tracker.

Let’s take the discussion about having a GNOME “media center version”; you could think that such a discussion will end up laying out some ideas about a media center. Wrong: we ended up discussing about special folders – an argument that has already been discussed to the death. Obviously, if you read d-d-l all day you can’t really expect having time to actually work on the features (or the crack) proposed on the list. So, for a change, I decided to do stuff after saying what could be done. I decided to take an idea that has been floating around for ages and implement it.

This is a simple FileChooserDialog, but the places list have been generated using a bookmark file (read using GBookmarkFile) in $HOME/.local/share/places/gtk-bookmarks.xbel instead of $HOME/.gtk-bookmarks:

FileChooser using bookmark file
It’s completely identical to the FileChooser in trunk, really, but the places on the left are parsed using this.

The code, obviously, merges the places saved using the old format.

This, instead, is a trivial Perl application that can read all the places; it can also edit them, add new places and remove old ones:

GTK+ shortcuts editor

The fun part about switching the file chooser to the bookmark files is that it’s public API, so everyone can read, change and write these locations. We can add new locations to an application like we add Glade files, and let the file chooser populate itself by loading a file; so, instead of using:

  gtk_file_chooser_add_shortcut_folder (file_chooser, some_location);

we could use:

  gtk_file_chooser_add_shortcuts (file_chooser, PKGDATADIR "/shortcuts.xbel");

But wait, the keen reader familiar with the issue will interrupt, the whole point of this mess is localising the name the user sees in the interface. Indeed, that’s why the bookmarks have a title and a description; through intltool we can extract those two and put them into the po file for the translators to work on – exactly like we do for the Glade files. Before displaying the bookmark will pass the string through gettext, which will return the localised alias using the application’s domain – or we could add domain argument to the gtk_file_chooser_add_shortcuts() function above.

The file chooser can also load shortcuts automatically, using the application name to filter out what’s interesting.

Is this the most correct solution for this problem? I don’t really know, even though using bookmarks and applications make more sense than using dot-desktop files and MIME types (come on? MIME types? Like I should bind a directory to specific types of content and not to the applications that are most likely to use them – and what are “MIME types” anyway?). At least, however, this is a start and there’s some code to comment on.

The patches are roughly done, but the real treat would be to split the places section of the file chooser widget into its own widget and let other applications, like nautilus, use it directly without having to cut and past tons of code out of GTK+.