Now boarding…

holidays: I’m leaving for a week in Amsterdam, with Marta.

I’ve already been in Netherlands, years ago with my family, so I already know the city; it’ll be fun to track down what changed, and to see new things.

work: As of july 26th I’m officially unemployed – or, better, in recovery (in a Scary Devil Monastery sense). And, by the way, if you are hiring, and you need a C/Perl developer with sysadmin skills, please feel free to contact me.

hacking: Well, the infamous RecentChooserWidget is finally here:

RecentChooserWidget

Still lacking the filter and drag and drop on the list, but everything else is here.

I’m planning to write an applet soon as I return from Amsterdam.

Hit me

cvs: The New! And! Improved! code for handling and viewing the recently used resources list has hit cvs.gnome.org:

recentchooser-commit

It basically works, even though the menu has still some rough edges.

I plan to work on the list widget until this week-end.

life: Marta got graduated! She held her dissertation last friday, and got full grades with a cum laude. Now she is a Math major, and she’d like to get a Ph.D., possibly abroad and not in Italy. That would mean a job in a foreign country also for me.

holidays: A week in Amsterdam. And I think I said all that is needed to be said.

Recent files woes

Yesterday, on IRC, there has been some discussion about my recently used resources handling proposal – especially with regards to the storage format.

I hate discussing on IRC; I’m not fast enough a typist – and since english is not my primary language, I find it very difficult to make myself understandable. So, I decided to put here some of the rationales for changing the storage format of the recently used resources list, written down in form of Q&A.

Storage format

Q: Why did you have to change the format?
A: Because the old format, as defined by the recent-file spec has shown its limits, since it has been proposed. Also, that spec is still a draft, and it’s not used by anyone else but Gnome.

Q: What limits the recent-file spec has?
A: It lacks the meta-data needed to know which applications registered a recently used resources. It lacks descriptors for meta-data such as a human readable name for the recently used reosurce.

Q: But recently used files need not a human readable name. Why should we use it?
A: The “human readable” name and description are not mandatory. Anyway, a user might have set that meta-data on its document; we strongly encourage the existence of this metadata. It would be totally unfriendly to show the file name instead of what the user decided to use as a name for that document. Also, “Wireless adapter WX-6615 Manual” is more readable than “wx-6615.pdf”. Anyway, the XBEL DTD makes the title and desc entities non-mandatory, so we can use them only if needed.

Q: Still, a recent file is not bookmark; then, why allow things that a bookmark allows on a recently used file pointer?
A: For me, a recent file is a bookmark to a file, with a lifetime that is kept artificially short, so it makes perfectly sense to use a bookmark-definition language in order to store it. You are gladly invited to prove me wrong, by providing examples on how a pointer to a recently used resource could be described apart from using a URI, and why does XBEL fail to store and describe a pointer to a recently used resource on.

Q: We could extend the recent-file spec, then, instead of using XBEL; did you think about it?
A: Yes, in fact I did. The first proposal of the desktop-bookmark spec used an updated version of the recent-file spec, but it was shot down, and usage of XBEL was proposed.

I’ll add more entries…

Update: directly from the libegg/recentchooser/README file:

Dependencies

Q: Why did you wrote the RecentManager?
A: The code living recent-files started to bit-rot, after being unmaintained for a long time; also, we never made clear whether the RecentModel code should live in a Gnome platform library on the same level of libgnome, or on a lower position on the dependency chain. The RecentManager code should go into Gtk, so it does not depend on anything more than GLib, Gtk+ and libxml2.

Q: In which library this code should go?
A: Inside Gtk+, starting from the 2.9 development cycle (I hope).

Q: Why Gtk? Why not libgnome?
A: We are in the process of getting rid of libgnome, so Gtk makes sense.

Q: Why this shouldn’t go inside a custom library?
A: Because I don’t want to create Yet Another Library upon which Gnome should depend; also, the requirements of this library would really be Glib, Gtk+ and libxml2, so there would be nothing gained by keeping this code outside Gtk+.

Q: The old recent-files code depended on libgnomevfs. Why yours does not?
A:The recent-files code depended on libgnomevfs for the fancy stuff needed in order to retrieve the MIME type of a file, and on the conversion of the URI in order to be displayable; also, it needed libgnomevfs for the monitor on the storage file. The MIME stuff could go away, since we require the user of this code to pass the MIME type of the resource when registering it; it makes sense, because if you used libgnomevfs yourself in your code, you wouldn’t have to check the MIME type twice. Also, many of the UTF-8 and URI manipulation code it’s now available directly inside GLib. At the end of the day, the recent-files code only needed the GnomeVFSMonitor from libgnomevfs – and that could be easily replaced with a timed poll() on the file.

Q: The old recent-files code depended on libgnomeui. Why yours does not?
A: The only left-over of the libgnomeui dependency inside libegg/recent-files was the usage of gnome_icon_lookup() function in order to retrieve the icon bound to the MIME type. I removed it, and switched to the same system used by the GtkFileChooser object (we’ll also share the icon cache, so it should even be more efficient once this code goes in Gtk+).

Manager API

Q: Shouldn’t you have tried to save the RecentModel object first?
A: I tried, at first. It soon became obvious that the RecentModel code had become a collection of hacks, especially WRT visualization, trying to hide its usage of Gnome-VFS; also, the storage file format was subject to a review process, both for enhancements and for interoperability. The model code would have been subject to a mass rewrite process anyway.

Q: No, really, I liked the RecentModel API, can’t you please keep it?
A: The short answer is no. The long answer is: it’s not worth it. The RecentModel tried to retrieve for itself most of the metadata reguarding a recently used resource. While this kept the API simple (what you had to do was to feed it a URI, in most of the cases), it also had a negative impact on the performances of the RecentModel object – which, obviously, negatively impacted on the overall performance of the widgets. Even if you did not use Gnome-VFS, the RecentModel was depending on it for querying the file metadata; if you did use it, you ended up with twice the number of the queries: one did by you code, and one did by the RecentModel code; this, especially in a networked environment, had caused many performance issues that the only solution was to create a RecentItem by yourself – and that made the API as complex as the RecentManager API could be (in fact, a bit more complex, since a RecentData structure is very lightweight when compared to a RecentItem object).

Widgetry

Q: You even changed the viewer widget. Why did you scrapped the entire EggRecentViewGtk object?
A: I really hated its name.

Q: Now, be serious…
A: Okay: I hated the whole thing – starting from the name. It was a clever hack, which tried to be useful for both the “inlined recent files” and the “recent files sub-menu” concepts. But it was an hack – which, clever or not, had passed the point of being maintainable. The interface upon which was based was too simple for being useful (EggRecentView only has two methods: “set_model” and “get_model”), so it had to be refactored; the menu API was too dependent on the RecentModel code – which led to separation issues when it came to visualization; for instance, you don’t sort a ListStore: you pass a sorting function to the TreeView, so that you can have multiple views of the same data. The same should happen with the Recently Used Resources List: same data, multiple viewers. Oh, and did I mention that the name was ugly?

Q: Why the RecentChooserMenu shows up in a sub-menu? Wasn’t this removed from the HIG?
A: It was indeed removed, and I consider it a mistake made by the GUP. The rationale for its removal was, shortly: “recently used files should live on the same level of the Open menu item”; which could be fine – if it didn’t bring up issues involving latency when building the File menu; or issues involving the total utility of a list composed of just four items. I believe that the “Open Recent” menu just as appears in OS-X should be the right approach, WRT recently used resources shown in a menu. Also, this keeps the code compact (the entire RecentChooserMenu size is < 1 kLOC), and maintainable.

Q: What if I wanted an inlined recently used resources list?
A: It’s not difficult to build, using the list returned by the RecentManager; you don’t even need to implement a widget:

     ...
     menu_item = gtk_separator_menu_item_new ();
     gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), menu_item);
     gtk_widget_show (menu_item);

     manager = egg_recent_manager_new ();
     egg_recent_manager_set_limit (manager, 4);
     egg_recent_manager_set_sort_type (manager, EGG_RECENT_SORT_MRU);

     items = egg_recent_manager_get_items (manager);
     for (l = items, count = 1; l != NULL; l = l->next, count++)
       {
         EggRecentInfo *info = (EggRecentInfo *) l->data;
         gchar *text, *name;

         name = egg_recent_info_get_display_name (info);
         text = g_strdup_printf ("_%d. %s", count, name);

         menu_item = gtk_menu_item_new_with_mnemonic (text);
         gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), menu_item);
         gtk_widget_show (menu_item);

         egg_recent_info_unref (info);
       }

     g_list_free (item);

     menu_item = gtk_separator_menu_item_new ();
     gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), menu_item);
     gtk_widget_show (menu_item);
     ...

Less than thirty lines of code.

Q: Do you plan to create a inlined menu widget?
A: Eventually; if the HIG does not change, or if the demand is high enough. Or you could implement it. It’s Open Source, you know…

Recent Menu

recent-chooser: Finally, after more than one month of hacking on the RecentManager object, I’ve been able to create a reasonable “Open Recent” menu widget:

EggRecentChooserMenu
Obligatory screenshot of the new and improved recent menu

The icon code is placed in the RecentInfo object, and it’s based on the GtkFileSystemUnix code, complete with the pixbuf cache (ideally, it should be shared across GtkFileChooser implementations and GtkRecentChooser implementations).

Right now, it does not have filtering abilities other than a filter function you must feed to the RecentManager (for that, I’ll implement a RecentFilter object); also, the “Clear” item is always shown, and the tooltips aren’t attached yet.

But it’s a start, and it’s also a way lot saner than the current EggRecentViewGtk object (starting from the class name).

recent-files: bug-fixing still going on… The bug count is down to twenty items, with 6 marked as enhancement (which I keep open as a feature reminder).