Stinging Velvet

Clutter – If release 0.4 rocked hard, release 0.6 of Clutter will blow your mind away. Just to list some features landed in the past couple of weeks after ClutterScript got in:

  • new event handling, borrowing from the W3C DOM event – that is, two event phases: capture, which traverses the scene from the stage to the actor that received the event, and bubble which traverses the scene from the actor to the stage. You can block the event chain in any point of both phases by simply returning TRUE in the signal handlers (like GTK+); kudos to mallum and Pippin
  • improved text scaling, at least for downscaling at ~50%; kudos to Pippin
  • build and test on win32 using the SDL backend, complete with VS2005 build files; kudos to tf
  • time-based timelines, so you can define a ClutterTimeline by giving its length in milliseconds; and without even breaking the API.

Still, there’s plenty more coming – so keep looking at trunk.

JSON-GLib – The code base has been consolidated a lot while working on ClutterScript, so I feel confident about making a release of the out-of-tree repository. The release is bagged, tagged and signed as json-glib-0.2.1 in the git repository ((As usual, at http://folks.o-hand.com/~ebassi/git/json-glib.git)). You can grab the tarball here. Work on seamless GObject-JSON (de)serialization will continue in the master branch towards a 0.4.0 release. Update@2007-10-16T23:30+0100: obviously, as soon as I got back home and checked the repository I found two bugs in the generator code; hence, brown paper bag release 0.2.1. Tarball, documentation and tag updated.

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 read ((obviously nothing prevents adding an XML parser, and use both)). 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.

My Wandering Days Are Over

This weekend I’ve finally tried Vala, something I wanted to do for a while now. Vala is, for those of you that never tried it, like GOB, but on PCP and steroids and with a syntax that doesn’t make using it feel like you’re being skull-raped through your eye sockets. It’s, actually, quite a pleasant experience – if you ignore the utter brain damage of connecting signals by overloading the plus operator ((which is more a fault of C# than anything, and one of the reasons operator overloading should be banished using necromancy. Come on: signal = signal + handler? Really?)).

Surely, there are a couple of issues with the underlying C translation layer:

  • connecting signals passes the class instance pointer, but if your class does not have any property then an empty struct will be generated, which doesn’t create valid C code;
  • if you then add a dummy int, the passed pointer is still called “self” but it’s never allocated, because the Vala compiler still expects for the class to inherit from GLib.Object in this case, while it really shouldn’t;
  • so, if you want to connect to signals, you have to make your class inherit from Object, create an instance and connect to the signals in the constructor or inside a method;

The last point is a perfectly legitimate choice to be made by language designers: but, then, this snippet:

using GLib;
using Gdict;

class TestSource {
  void on_definition_found (Gdict.Context context, Gdict.Definition definition) {
    stdout.printf ("*definition for `%s' found:\n%s\n",
                   definition.get_word(),
                   definition.get_text());
  }
  static void main (string[] args) {
    var loop = new GLib.MainLoop (null, false);
    var context = new Gdict.ClientContext ("dict.org", 2628);

    context.definition_found += on_definition_found;
    try {
      context.define_word ("*", "dictionary");
   } catch (Glib.Error e) { warning (e.message); }

    loop.run ();
  }
}

should fail to compile in Vala, and not in produce invalid C code ((I think this stems from the fact that Vala, like C#, allows a mixed OO-procedural approach, like Perl and Python; but those languages usually get it right)).

Anyway, Vala is an interesting project. If it had a better integration with the rest of the toolchain (gdb, valgrind, autotools, profilers, etc.) it should definitely become one of the first class citizens of GNOME ((for instance, Apple has native Objective-C support, and that is a layer above C like Vala)).

By the way, just to try out Vala I wrote the bindings for the Gdict API. They are mostly working, so if you want to check them out, you can clone the repository here:

  git clone http://www.gnome.org/~ebassi/git/gdict-vala.git

Those are the bindings for the unstable version of Gdict, which will be released for GNOME 2.20.

GUADEC/recap

This year’s GUADEC has been really great – it seemed hard to top last year’s but paul, thos, robster and the rest of the GUADEC team really rocked hard to make everything work at its best. Kudos to all of them.

Unfortunately, my GUADEC was cut short on Wednesday for a small medical emergency, as my wife had some health problems on Tuesday night that got worse on Wednesday. Now it seems everything’s back to normal, but as we’re still expecting some of the lab analysis to come through, we had to postpone our holidays and the trip back to Italy.

I could only stay in Birmingham for the GTK+ “state of the union” (awesome) talk by Kris and the 3.x4.x workshop and see the wonderful presentation Fer and Xan did – really funny but also straight to the point. The following discussion was a bit hijacked towards the ABI/API break issue, which I believe is neither interesting nor really important. I also missed the Clutter talk on Thursday, but I was told Matthew rocked. It’s fun to see people picking up Clutter and finding it API-friendly: it’s hard, being very near to it, to judge whether some of the choices you make are the right ones.

I had to cancel my tutorial on Perl and GTK+, as well as the GConf workshop. I’m very sorry if this has caused you some trouble; I heard that Ryan did an interesting talk on his dconf project, though.

I missed Havoc’s keynote on the online desktop, but went to Alex’s keynote; it was intriguing, even though I disagree on some of his points – especially the bit about Firefox being an interesting platform to develop towards or with, after the utter disregard that the Mozilla developers have had in the past for Linux and GTK+ (two issues spring to mind: borked clipboard usage and UTF-8 drag and drop); oh, and I don’t think I’ve ever seen the words “good engineering practises” and “small extensible core” anywhere near “mozilla”, unless “the Fox” that Alex mentioned was a new web browser I’ve yet to see. What I completely agree is that we need to tap into the resources of the non-C, non-hardcore programmers: we need tools to make possible for Flash developers, for Javascript developers, for designers to use our platform, and provide new ideas; in short, make the platform interesting and usable for developers, like the desktop should be interesting and usable for the users.

Let’s take Plasma, the new environment KDE provides for writing their version of desktlets-dash-widgets-dash-applets-dash-somethingets. Obviously, right now, it’s just an exciting new way to write not really useful stuff, like the uptenth variant of a clock, or a weather applet, or a note taking applet; but you get an HTML canvas widget, and you can write ${FOO}ets in Javascript. This way, KDE will get a truckload of useless stuff lying on a desktop which will be covered in windows anyway – but they will also get the attention of web developers writing small apps integrating with web services in a transparent way, using their own strengths and knowledge, without forcing them to learn the intricacies of a complete platform; and in time they’ll get those developers to know this platform and gain new workforce to work with it, and on it. Compare to GNOME: if I want to write something as simple as a desklet, right now, I’d need to know GTK+, Cairo, GConf and possibly gnome-vfs, libsoup, or third party modules for talking to web services through their API. The curve for contributing to the platform is still too steep; and you don’t even get to use your own knowledges: you have to learn everything from scratch. KDE core developers understood this before we did, and their move might keep KDE from falling into the irrelevancy of geek-only usage. It’s up to us find a way for making the GNOME platform interesting again for developers, as well as users.

Take it or leave it

After the comments on my latest blog post, I got back at Unique and did some rearrangements in the code base. Now the backends are all compiled in (obviously, depending on whether you have the dependencies to compile them) and the backend to be used can be defined at runtime. The default backend is chosen at compile time and can be overridden by setting the UNIQUE_BACKEND environment variable. Obviously, if you launch an instance with UNIQUE_BACKEND=dbus and another one with UNIQUE_BACKEND=bacon you will have two instances running – but that’s only to be expected.

I’ve also updated the API to something I can probably call “semi-frozen” (small API additions notwithstanding); the constructor changed to always accept a startup notification id (it will try to be clever and find it for you if you pass NULL, though) and allows you to define custom commands with a single call.

As usual, you can clone the Git repository from here:

  git clone http://www.gnome.org/~ebassi/git/unique.git

or grab the tarball for 0.9.20.9.3 from here.

I’ll keep working on making a 1.0.0 release at GUADEC (probably it’ll happen right at GUADEC), API/ABI stable and with the Xlibs backend. Then I’ll resume working on the GtkApplication class, which will have the Unique features but will (hopefully) be integrated in GTK+.

Update@2007-07-12T12:54+0100: New release, with full API reference documentation, a couple of stupid bugs squashed and workspace support.

Strange news from another star

I’ve been promising a release of GtkUnique for a while now, but work and other stuff got in the way of the namespace change-slash-rewrite. Yesterday I finally got around finishing the porting of the Unix domain sockets backend (or “bacon”) so I cooked up a preliminary release with the D-Bus and Bacon backends working. You can find the tarball here or, if you’re feeling in hacking mood, you can check out the git repository from here:

  git clone http://www.gnome.org/~ebassi/git/unique.git

the unique-0.9.1 is the tag for this release. I’ll work on finishing the port of the Xlibs backend and target a stable 1.0.0 release for GUADEC.

The API of Unique changed a bit since the last GtkUnique release, and I think it’ll change a bit more in order to be usable with the smallest impact possible. Now you can register custom commands and there’s convenience API for sending strings and URI lists; the command registration and construction API might change to something similar to the GtkDialog API – and I might switch to a more signal based approach (construct the message payload inside a signal handler) before 1.0. I also might add a –replace command line switch that gets slurped and does The Right Thing for you.

The biggest change is happening under the hood, though; with this release, the UniqueApp instance will request the specified name as soon as it is created, so you’ll be guaranteed to either be the first running instance or be able to send messages to the currently running instance at the same moment that the UniqueApp constructor returns. Hence, no more race conditions between the constructor and the “is running” request. Finally, the “window watching” functions have been removed – even though I might add a “watch window” function to handle the startup notification sequence for you (now that we have the API to do that in GTK+ 2.11).

This release also means that the code in SVN under the gtkunique module is to be considered deprecated. I’m going to ask the svnmaster to move it into the attic, as the delta is too big for a simple check-in. As soon as 1.0.0 is out I’ll also ask the release-team for “blessing” Unique as a dependency, so if you want your module to depend on it you’ll be able to safely do it. Again, sorry for taking this long to finish up this work.

Update@2007-07-09T15:16+0100: I’ve just rolled a 0.9.1 to fix some build issues and add licensing terms. Thanks to Christian Persch for the heads up.

Time is Running Out

Today I committed a couple of fixes to GtkRecentManager and I thought it was worth mentioning them on pgo.

Up until now, GtkRecentManager instances were available either via the gtk_recent_manager_new() constructor – which left the memory management duties to the developer – or via the gtk_recent_manager_get_default() which tried to do the right thing, by returning a singleton instance to be shared inside an application. The master plan was having the singleton attached to the GdkScreen to take advantage of the lifetime management of the screen done by GTK+ and cleanly dispose the recent manager when the screen was closed. This approach would have worked well, except for two tiny details:

  1. if you change screen, gtk_recent_manager_get_default() will return a different instance
  2. GdkScreen are never closed unless you do that explicitly.

So much for the master plan.

Thanks to Morten Welinder, who did some very appreciated detective work on it, it was decided to switch to a more common approach, with a static variable and a private synchronisation function that gets called when the main loop level reaches zero. What does this mean, for the application developer? First of all, two deprecations: both gtk_recent_manager_get_for_screen() and gtk_recent_manager_set_screen() are deprecated as of GTK+ 2.12 and should never be used again (the first evaluates to gtk_recent_manager_get_default() and the second to a NOP, if you ever decide to compile with GTK_DISABLE_DEPRECATED turned off); second of all, no more juggling around with the screen changes: multiple calls of gtk_recent_manager_get_default() will always return the same instance of the GtkRecentManager object – which you should never unref. Obviously, if you were creating your own recent manager instance with the gtk_recent_manager_new() constructor, none of this matters and you’ll have to handle the manager lifetime by yourself.

Another change I committed was the switch to the g_timeout_add_seconds() for the polling of the recent files storage file. Since the timeout was set to every N seconds I decided that the lifespan of my laptop’s battery was more important than having a millisecond precision on a stat() call. In other news, laptop owners around the world rejoice as one. Since every signal under GTK+ is emitted under the assumption that the emitter is inside the GDK master lock, the newly added gdk_threads_add_*() functions weren’t fit for my cunning plan of using the approximate timeout source; for this reason, I added a g_timeout_add_seconds_full() inside GLib and the equivalent code directly inside GtkRecentManager.

Company Calls Epilogue

Today I gave the final touches to a patch based upon the patch for search capabilities in the GtkFileChooser embeddable widget, adding the “Recently Used” shortcut:

File Chooser Support for Recently Used Files

there are still a few missing bits (the icon for the shortcut is one of them) but it’s already working remarkably well. I’ll work toward implementing what’s left in the next few days, while I also fix some of the warts of the search support.

Company Calls

Search support for the GtkFileChooser (#344785) landed in GTK+ trunk. It’s a patch written by Federico and updated by Matthias Clasen (I merely kept it in sync with trunk). The patch adds a private search engine abstraction object and three implementations, using libbeagle, libtracker and a simple file-tree-walking search. There’s no hard dependency on Beagle or Tracker: the libraries are opened using g_module_open() if they are found installed on your system, otherwise it’ll all fall back to the simple search backend (it’s the same solution used by Nautilus for its search support).

The file chooser now has a “Search” shortcut:

GtkFileChooser Search Support/1

If you double click it, you’ll get a search pane:

GtkFileChooser Search Support/2

Where you can search for “foo” and get the matching results:

GtkFileChooser Search Support/3

Next stop: fix all the missing bits (#435343) and add a “Recently Used” shortcut showing the list of recently used files (bug #435342).

By the way: libbeagle has an incredibly nice API, whereas libtracker doesn’t. Please, Tracker developers: instead patching projects or writing a GTK+ widgets library which only new projects can use, focus on writing a nice, GObject-based API for all the existing projects out there. Pretty please, with the sugar on top.

Down on the corner

VFS: Lennart, what you want is GVFS, which is being developed right now by alexl, has dropped the POSIX abstraction approach and it’s surely more portable than FUSE. And, most of all, has a sane API (for a change). For “sane API” I mean that I almost cried tears of joy when I saw the file monitoring interface – and I wasn’t the only one.

Ubuntu: so, it seems that Dell signed on with Canonical to provide Ubuntu on their desktops and laptops. Good for the community, GNOME, Linux and, obviously, good for Canonical. Mark Shuttleworth will be rich (again), and without even having to resort to the patent on the hand-cranked XML parser.