Good Intentions/2

April 17, 2008 on 10:30 pm | In Hacking, GNOME, C, developer, gtk, clutter, crack, json-glib, glib | 8 Comments

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

Time to Build

March 23, 2008 on 10:42 pm | In GNOME, recent-files, gtk | 3 Comments

Claudio did some interesting profiling (and patching) of the BookmarkFile implementation in GLib — so kudos to him and Felix.

one thing that he noted is:

However, I still have the feeling that letting ~\.recently-used.xbel grow without control is very, very wrong. In my laptop, this file is about 5MB, which accounts for ca. 9000 files(!).

this is very true, but I feel it needs some context. when I first wrote the RecentManager code I only had the EggRecent implementation as a comparison; the old EggRecentModel had an hardcoded limit of 500 items stored per file. limiting on the number, instead of the age of an item inside a recently used file list did not feel right, so I thought about hardcoding a limit of 30 days — but stopped short of doing it because I realized that hardcoding limits at the toolkit level was not a good idea:

  • application developers will not be able to change it in any way
  • users will not be able to change it in any way
  • system administrators will not be able to change it in any way

just to give a few examples: while I was still writing the RecentManager inside libegg, Alex Graveley was writing Gimmie. Gimmie had1 a local document and application history that could allow you to go back in time of months; had I hardcoded a limit, the Gimmie developers would have needed a new implementation, defeating the purpose of shipping the RecentManager inside GTK+ to cut down the amount of code replication.

hardcoding limits is also something that makes it hard, or even impossible, for users and administrators to control; I might want a 30 days limit, but other might want a 90 days, or a 7 days — or even a 1 day limit. some might not even want to save the recently used files at all (think kiosks).

I don’t believe in strictly hardcoding policies in the toolkit; providing fallbacks is perfectly fine, but preventing people from actually having different settings is akin to convince everyone that you’re right and they’re wrong.

still, this doesn’t solve the problem at hand, that is the current lack of policy.

what I’d like to see is some process taking care of purging the old entries, using some key inside gconf, at the end of the session; gnome-settings-daemon would fit the role for GNOME, and other desktop environments using GTK+ could provide the same functionality2. after all, gnome-settings-daemon should already flush the thumbnails cache — it wouldn’t be much of a complication.

  1. and might still have — I haven’t checked it for a while now []
  2. if you’re not using a GTK+ based desktop environment you’re either using the same spec used by GTK+ so you can provide your own way of purging the cache, or you’re using another way to store the recently used files, so the size of the file saved/read by the RecentManager will not bubble out of control so easily — and you can still flush it yourself []

Berlin/Final

March 15, 2008 on 1:35 am | In gtk, conference, hackfest, berlin | No Comments

some final thoughts on the Hackfest: it has been a great opportunity for discussing with all the usual suspects and more, and on a very high bandwidth channel — unlike IRC or the mailing list. definitely, an experience that must be repeated next year, because the discussions we had and the work we started will keep us all busy at least until GUADEC — and from then on, towards a very bright future for GTK+ and the whole GNOME project.

thanks to Mathias and Openismus for being the local organization; thanks to Tim, Kris and the entire Imendio, for moderating the whole panels; thanks to Vincent and the GNOME Foundation, and obviously all the sponsors, for helping out in organizing and funding this gathering of hackers; and thanks to everyone that made these five days an incredible experience for me: you all really rock the GNOME community.

Berlin/5

March 15, 2008 on 1:35 am | In Hacking, GNOME, C, gtk, conference, hackfest, berlin | 2 Comments

last post of the Berlin Hackfest series, written on the last minutes of day 5

today was “wrap up” day. we got together in the room used for the presentations and summed up all our work during the various sessions of the week. it turned out that the amount of work, even though not reflected by the wiki page, was really enormous; the introspection guys worked a lot and now that they have received a lot of input, they are going to rework things and kick ass even more. apparently, Behdad decided that I would tackle the GL integration inside GDK — which, of course, I’d really like to do; the GL integration, and a GDK wrapper for the GLX_texture_from_pixmap (and the equivalent call for the other platforms) would obviously be the primary way to integrate Cairo 2D high quality drawing and GL 3D and hardware acceleration in a simple way. and this is a step forward the implementation of a scene graph inside GTK+.

in the meantime, I’m — as Ryan would put it — deeply recursing. it all started on tuesday, when I decided to start hacking on a real application with Vala using all the bits and pieces a modern GTK+ application requires: GtkUIManager, about dialogs, command-line switches. the application was supposedly going to read the new GTest framework reports, and allow comparing of multiple runs in a fast way. this, in turn, led to some bugs filed against Vala GTK+ bindings. working around these issues, I also found out that the libxml-2.0 bindings in Vala — which I need to parse the GTest report XML — require a lot of pointers usage and are, in general, quite sub-obtimal, due to the very C oriented API. while investigating on a substitute, I found out XmlReader — the cursor-based XML traversal API that .Net and other high-level languages implement1. Thus, today at a coffe shop2 I started hacking very quickly on a rough implementation of a XmlReader GObject class which, as of at this moment works quite nicely:

  XmlReader *reader = xml_reader_new ();
  GError *error = NULL;

  if (xml_reader_load_from_file (reader, “book.xml”, &error))
    g_error (“Unable to parse book.xml: %s, error->message);

  xml_reader_read_start_element (reader, “book-info”);

  xml_reader_read_start_element (reader, “author”);
  author = g_strdup (xml_reader_get_element_value (reader));
  xml_reader_read_end_element (reader);

  xml_reader_read_start_element (reader, “title”);
  title = g_strdup (xml_reader_get_element_value (reader));
  xml_reader_read_end_element (reader);

  xml_reader_read_end_element (reader);

  g_print (“The author of %s is %s\n, title, author);

  g_free (title);
  g_free (author);
  g_object_unref (reader);

and you’re done. at this moment, I’m cleaning it up and adding the gtk-doc API reference to the build3. I’m probably going to add the generic read() method, so that:

  while (xml_reader_read (reader))
    {
    …
    }

will work as expected. it’s, as usual, code replication — but I’m going to need it anyway, so it’s good code replication.

  1. Even libxml-2.0 implements it, even though it suffers from the same issues of its DOM API, and it’s still not GObject-based []
  2. Behdad is right: a coffee shop without any Internet connectivity makes wonders with your productivity levels []
  3. When I write new libraries, I usually stub out the API and document it at the same time; now I started to add the GTest units before I even implement the API []

Berlin/3

March 15, 2008 on 1:35 am | In Hacking, GNOME, gtk, clutter, conference, hackfest, berlin | No Comments

second and third day of the hackfest, edited on day five

on tuesday, Behdad and I started working on OpenGL integration inside GTK+. as stated multiple times on the Bugzilla entry, what we both would like is a Cairo-like integration of GL inside the available drawing systems in GTK+. in short: not a specialized widget like GtkGLArea, which would make it difficult — or plainly impossible without jumping through a long series of hoops. in flames. tied. and blindfolded — to integrate GL inside existsing projects; and not the incredible API dump that GtkGLExt is.

the design we mostly agreed on was a shared object inside GTK+, containing the GL context abstraction object, and two simple calls to delimit the drawing code, wait for vblank and swap the GL buffers. plus, an easy to use wrapper around the texture_from_pixmap extension, to allow drawing with cairo on a Pixmap and then have it pushed into the GL pipeline.

Carl arrived on wednesday, and partecipated at the scene graph BoF we held. the BoF itself was pretty straightforward: we read the slides that Havoc sent on the mailing list and discussed the various points. we all agreed on a lot of points — and we tried to define the problem space more deeply1. being there, I could bring to the table my experience in the past two years2 with the design and implementation of Clutter. some of the attendees were already familiar with it — something very satisfying — and I could expand some points in Havoc’s slides about Clutter that have been recently fixed or are going to be fixed in this cycle. the biggest point is that the scene graph should integrate with Cairo, in order to allow applications and people to gently merge both the 2D drawing of surfaces into a full 3D environment; I’ll leave to Carl to explain the Cairo side, because he’s obviously better at this than I am. :-)

the operative result of the scene graph discussion was that Clutter emerged as an already powerful and established solution for this problem space, and given that it already nicely integrates with GTK+, we can work towards the common goal of making it “the GTK+ canvas”, outside the actual library so that it can grow unrestrained and experiment in new directions.

  1. We did not always succeed in this, but the issue at hand is quite large and it’s understandable []
  2. It’s really two years? holy crap! The time really flew… []

Berlin/1

March 11, 2008 on 7:22 pm | In travel, gtk, celebrations, conference, hackfest, berlin | No Comments

day two of the gtk+ hackfest.

yesterday was devoted to the Imendio vision of a better toolkit, and how to get out of the hole we dug for ourselves with the current API/ABI contract - but others have written about it better than I could possibly do.

today was introspection day; Johan Dahlin showed the current state of the GObject introspection code by using a Vala widget, subclassing a GtkDrawingArea, from a Perl script — which was beyond cool. kudos to everyone that has been working on it.

today it’s also six years since the gtk+ 2.0.0 release, so happy birthday gtk+ 2.x!

Time is Running Out

June 19, 2007 on 1:59 pm | In Hacking, GNOME, C, gtk | 6 Comments

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.

Expect

June 7, 2007 on 1:47 pm | In rants, gtk | 4 Comments

Well, it seems that after six years a new release of Emacs is out - and it uses GTK+ as the GUI toolkit. I’d like to think that what took so long was not adding this thing to the file selection dialog:

screenshot-emacs-file-chooser.png

Otherwise, I might expect something like this for the next release.

And this has nothing to do with the fact that I’m a ViM user. No, really.

Company Calls Epilogue

May 4, 2007 on 5:45 pm | In Hacking, GNOME, C, recent-files, gtk | 9 Comments

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

May 3, 2007 on 10:20 am | In Hacking, GNOME, C, gtk | 20 Comments

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

May 1, 2007 on 8:28 pm | In GNOME, gtk | 1 Comment

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.

Time For Lovin’

March 15, 2007 on 10:15 pm | In Hacking, GNOME, recent-files, gtk | No Comments

You can see I’m listening to the Beastie Boys, right now

In the last three days I’ve finally managed to resolve as fixed these GTK+ bugs:

  • Bug 347375 – Not possible to set startup notification ID on a GtkWindow
  • Bug 418219 – GtkRecentChooser should apply filter before sorting and clamping the list
  • Bug 418634 – gtk_recent_chooser_menu_set_show_numbers docs
  • Bug 418673 – gtk_recent_manager_add_item
  • Bug 338843 – add recent files support inside the ui manager

Bug #347375 contained a patch Vytautas Liuolia wrote last year, as part of his guniqueapp Summer of Code project.

Bugs #418219, #418634 and #418673 have also been backported to the stable branch, as they fixed documentation or simply bad behaviours in the code.

Bug #338843 finally closes the long standing bug about the integration between the recent files and GtkUIManager; you can now add a GtkRecentAction to your actions group and let it do the right thing.

Many thanks go to Vytautas Liuolia, Matthias Clasen, Paolo Borelli and Morten Welinder.

Of Angels And Angles

March 8, 2007 on 6:46 pm | In Hacking, GNOME, C, open-source, developer, gtk | 6 Comments

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

March 2, 2007 on 2:09 pm | In Hacking, GNOME, C, project-ridley, developer, fosdem, gtk | 3 Comments

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

February 22, 2007 on 5:52 pm | In GNOME, C, open-source, developer, gtk | 7 Comments

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+.

Come and See

February 9, 2007 on 4:18 pm | In Hacking, GNOME, Life, recent-files, developer, fosdem, london, gtk, music | 1 Comment

Decemberists: Yesterday evening, The Decemberists were in London, and made a wonderful concert at Shepherd Bush. I’ve fallen in love with the band after vieweing the video of their song Sixteen Military Wives and I started getting my hands on their whole discography (right now, only the singles are missing). They played mostly songs from their new album, The Crane Wife, which is really as good as it can get (so go out and buy it now).

gnome-utils: It seems that my plea for someone to work on GFloppy has been useful; right now, Paul Betts and Riccardo Setti are working on a replacement using HAL and libparted, and are also getting the ball rolling for adding formatting support directly in HAL. Guys, you rock!

GTK+: I’ve been working on fixing some bugs of the GtkRecentChooserMenu widget; specifically, bug #377164 and bug #405696. While I was at it, I finally closed the FIXME I left in code, for supporting both appending and prepending custom menu items in the recent files menu, and finally added a test case for the widget, so I can track regressions.

Recent files menu

Obligatory screenshot of the test application

FOSDEM ‘07: Like last year, at the end of February I’ll be in Bruxelles, attending FOSDEM.

Boogie Woogie Bugle Boy

August 1, 2006 on 11:50 pm | In Hacking, C, recent-files, developer, gtk | 2 Comments

Lately there has been some activity in projects moving from EggRecent to GtkRecent. Obviously, this led to questions and bugs opened about the API.

One of the questions is: if I had a EggRecentModel singleton what should I use now?. Since EggRecent needed a EggRecentModel around for the entire lifetime of the recently used files list, you had to keep at least a singleton around; you also had to pass it to the objects (not widgets) displaying the list, because each istance of the objects would modify the list itself. GtkRecentManager does not need that, since the widgets usually use their own internal instance of the manager and they don’t change the list in any way. So you can create a new GtkRecentManager and keep it around as a singleton (remember to call g_object_unref() on it when finished, otherwise you’ll leak it):

GtkRecentManager *manager_singleton = gtk_recent_manager_new ();

and then pass it to the widgets:

GtkWidget *dialog =
  gtk_recent_chooser_dialog_new_with_manager (“Recent Documents”
                                              parent,
                                              manager_singleton,
                                              GTK_STOCK_CLOSE,  GTK_RESPONSE_CLOSE,
                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                              NULL);

Nevertheless, you should really use gtk_recent_manager_get_default() which will do the right thing, and pass you a per-process instance and you won’t have to care about its memory management (no g_object_unref() when quitting). Also, using gtk_recent_manager_get_default() means that you don’t have to use the _with_manager variant of the widgets constructor, as they will use the per-process GtkRecentManager by default. Using your own GtkRecentManager makes sense only if you want to use the “filename” constructor-only property to specify your own storage file (and you should do that only if you know what you are doing):

GtkRecentManager *manager = gtk_recent_manager_get_default ();

  ...

GtkWidget *dialog =
  gtk_recent_chooser_dialog_new (“Recent Documents”
                                 parent,
                                 GTK_STOCK_CLOSE,  GTK_RESPONSE_CLOSE,
                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                 NULL);

Another question is the dreaded I want an inline list of recent files in the File menu; I’ll redirect you to the bug report linked for the rationales about why I think the inline list sucks, and should be removed from the UIs of GNOME applications in favour of the sub-menu. Anyhow, for those Unbelievers still using this Windows-cloned relic of the past, here’s a simple function for adding an inline list to an existing GtkUIManager instance; it’s part of a example of integration between GtkRecent and the UI manager I sent to the gtk-devel mailing list before GUADEC.

static void
add_inline_recent_items (guint         merge_id,
                         GtkUIManager *ui_manager)
{
  GtkActionGroup *action_group;
  GtkRecentManager *manager;
  GList *items, *l;
  guint i;

  action_group = gtk_action_group_new (“recent-info”);
  gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

  manager = gtk_recent_manager_get_default ();

  /* we don’t care about sorting and filtering, but it can
   * be done using g_list_sort_with_data() and clamping the
   * resulting list to the desired length
   */
  gtk_recent_manager_set_limit (manager, 4);
  items = gtk_recent_manager_get_items (manager);

  /* no items: attach an insensitive place holder */
  if (!items)
    {
      GtkAction *action;

      action = g_object_new (GTK_TYPE_ACTION,
      			     “name”, “recent-info-empty”,
			     “label”, “No recently used files”,
			     “sensitive”, FALSE,
			     NULL);
      gtk_action_group_add_action (action_group, action);
      g_object_unref (action);

      gtk_ui_manager_add_ui (ui_manager, merge_id,
  			     “/MenuBar/FileMenu/RecentFiles”,
			     “recent-info-empty”,
			     “recent-info-empty”,
			     GTK_UI_MANAGER_MENUITEM,
			     FALSE);

      return;
    }

  for (i = 0, l = items;
       l != NULL;
       i += 1, l = l->next)
    {
      GtkRecentInfo *info = l->data;
      gchar *name = g_strdup_printf (“recent-info-%d-%lu”,
      				     i,
				     (gulong) time (NULL));
      gchar *action_name = g_strdup (name);
      GtkAction *action;

      action = g_object_new (GTK_TYPE_ACTION,
      			     “name”, action_name,
			     “label”, gtk_recent_info_get_display_name (info),
			     “stock_id”, NULL,
			     NULL);
      g_object_set_data_full (G_OBJECT (action), “gtk-recent-info”,
                              gtk_recent_info_ref (info),
			      (GDestroyNotify) gtk_recent_info_unref);
      g_signal_connect (action, “activate”,
                        G_CALLBACK (recent_activate_cb), NULL);
      gtk_action_group_add_action (action_group, action);
      g_object_unref (action);

      /* all you need is a UI definition with a “placeholder” element called
       * “RecentFiles” under a “menu” element called “FileMenu”.
       */
      gtk_ui_manager_add_ui (ui_manager, merge_id,
  			     “/MenuBar/FileMenu/RecentFiles”,
			     name,
			     action_name,
			     GTK_UI_MANAGER_MENUITEM,
			     FALSE);

      g_print (“* adding action `%s’n”, action_name);

      g_free (action_name);
      g_free (name);
    }

  /* unref the info objects so that they will be destroyed when
   * the actions to which they are bound are destroyed with the
   * UIManager instance
   */
  g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL);
  g_list_free (items);
}

This code should give you an idea on how to implement your own version. Making the menu reloading the inline list means removing the UI definitions using the merge_id integer and calling this function again inside a callback attached to the “changed” signal of a GtkRecentManager instance, and it is left as an exercise for the reader. ;-)

GtkRecent and GtkUIManager

I’m really sorry that the UIManager integration did not happen in time for 2.10; it means that some applications will have to implement it by themselves until GTK+ 2.12 is out with a common implementation. In the meantime, continue asking me or opening bugs in Bugzilla.

Update@2006-08-02T09:51+0100: the complete code now has the “reload-when-list-change” feature. Remember: you may cut and paste this code for a basic support of recent files inside an inline menu; there are at least another couple of ways to implement the same level of support, and mostly it depends on how you handle your own documents. I’d like for GTK+ or libgnome or GLib to have a “document” class abstracting most of this and other stuff, like Cocoa on OSX has the NSDocument class.

Update@2006-08-02T16:05+0100: another update - I’ve fixed a couple of leaks (a GtkAction is a GObject and not a GtkObject) and added the sorting function for the inlined list.

Tides that I tried to swim against

July 12, 2006 on 2:14 pm | In Hacking, Perl, C, recent-files, gtk, ohand, clutter | No Comments

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

You got me all wrong

May 8, 2006 on 11:23 pm | In Hacking, C, gtk | 2 Comments

This is actually a mail I sent on gtk-devel-list. Obligatory disclaimer: this is not a proposal for getting gnome-vfs inside GLib, or for making GTK depend on gnome-vfs or for replacing gnome-vfs entirely; please, read on before commenting.

A while ago, on IRC, Christian Persch made the request that the monitoring of the storage file used by the GtkRecentManager could be overridden by libgnome, so that every application using the GnomeProgram API would automagically have notifications of file changes using gnome-vfs, instead of the default implementation which stat()s the file once in a while.

This spawned a more interesting discussion about how to implement a simple file monitoring API inside GLib; my approach and Christian’s were equivalent, and resolved in a new object with a vtable to be overridden per-process. Matthias, instead, suggested using a GSource, and having the file monitor to play nice with the main loop. Thus GFileMonitor was born.

Continue reading You got me all wrong…

The Mariner’s Revenge Song

May 7, 2006 on 11:28 pm | In GNOME, recent-files, announce, gtk | No Comments

From the libegg’s ChangeLog:

2006-05-07  Emmanuele Bassi  

	Finally deprecate EggRecent.  So long, and thanks for all the bugs.

	* libegg/recent-files/THIS_IS_DEPRECATED_USE_GTK_RECENT_CHOOSER:
	* libegg/recent-files/egg-recent-model.h: Deprecate the EggRecent code,
	now that GTK 2.9.0 is out; if you want to compile it, you
	must define EGG_ENABLE_RECENT_FILES before including
	egg-recent-model.h.

This is the first version of the so-called “Ramone Deprecation System”: it means that if you blindly re-sync with libegg HEAD, or if you decide to use the EggRecent code now, a guy called Ramone will be sent directly to your home by the Gtk+ Cabal; he will politely knock at your door and once you’ve opened, he will beat the crap out of you.

Next, the Gtk+ Cabal will implement the “Puppies Deprecation System”. And believe me: you don’t want to know how that works.

Now listening: The Decemberists, Picaresque

Next Page »

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^