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.

6 Replies to “Time is Running Out”

  1. “polling of recent files storage file”?

    Using seconds precision rather than millisecond precision is an improvement, but isn’t polling at all for something like that pretty evil? As a laptop owner, I’ll hold off my rejoicing until you’ve switched to inotify… ;)

  2. @stewart

    if you’ll be able to implement a generic file monitoring api working reliably on every platform gtk+ uses, I’ll more than gladly switch to that api. ;-)

    anyway, I’m waiting for gvfs – when that’s ready, using it will be easy enough.

  3. I haven’t programmed in C in years, but I think I could manage to come up with such an API. The implementation would look something like this:

    #ifdef HAS_INOTIFY
    /* Use inotify */
    #else
    /* poll */
    #endif

    Does such a thing really not exist in glib/gtk yet? My understanding is that Mono’s FileSystemWatcher class, for example, does exactly that…

  4. you don’t really want to use inotify api directly; not even in a library, unless you’re writing a library wrapping it.

    anyway, if you think gtk+ should use inotify, open a bug in bugzilla.

    personally, I’m more interested in gvfs and I’m perfectly fine in waiting for that to be ready and included.

  5. Fair enough. I’ll get off my OMG WTF POLLING IZ TEH EVIL high horse now, since I’m not actually offering to write any code to fix it.

    I was just surprised to learn that it isn’t already a solved problem…

Comments are closed.