Creating custom URL handlers in Ubuntu 11.04, 11.10, GNOME 3.0

Ubuntu LogoFor those on a time-crunch, here’s the short answer:

  1. Create or edit a .desktop file[1] in /usr/share/applications that looks like this (note lines 6 and 13):
  2. Run the following command:
  3. Done.

For a bit of an explanation, keep reading.

If you’re like me, you sometimes stumble across a strange system administration problem that you solve by hacking together a solution that you don’t know why it works. This happens all the time. Yes, negligence or laziness can be the culprit, but sometimes what you did is so obscure or esoteric that its simply not cost-effective to spend the time researching the reasons it works. That latter scenario can often be blamed on a case of poor documentation.

In my case, it was a case of poor documentation of a recent change in system policy and a lack of uptake in the blogosphere in figuring it out.

The goal was simple: I needed a way to browse iTunes Store links in Linux (specifically, Ubuntu). The immediate solution I found was also simple: install TunesViewer (version 1.2 at the time). The first computer I tried this on it worked, however when it was tried it on a second computer iTunes Store links would not automatically launch TunesViewer from any web browser. Thus began my digging.

The first relevant thing I found was this bug report about Google Chrome. It reflected my situation exactly, as the main difference between the first and second computers was that the first computer was running Ubuntu 10.10 while the second computer was running Ubuntu 11.04. Unfortunately, it also derailed my search into looking up information on how to use gconftool-2[2] [3] and various programs/scripts to auto-detect file associations[4] [5]. This did not end up leading me to a solution. However, I eventually found a forum post which lead me to this Ubuntu bug report, which informed me of another mechanism by which I could specify file associations: Desktop Entry files[1].

When supported by the user’s environment, a Desktop Entry file allows programs to provide various bits of metadata to the environment regarding its execution and presentation. Among other things, you can specify a program icon, name and comments in multiple languages, the command used to launch the program, and (of most importance to me) specify MIME[6] types that the program knows how to deal with.

Ubuntu keeps these Desktop Entry files in various places, but the primary location is /usr/share/applications. Thankfully, TunesViewer (still 1.2) came in a .deb[7] package with a Desktop Entry file included, so it was a simple matter to edit in the necessary changes. The code below highlights the changes needed, namely lines 6 and 13:

The changes to line 6 were minimal: I just had to make sure “%U” was there, as that tells the user environment that the application can take multiple URLs (which TunesViewer can). Line 13 was added new. The MimeType key takes as its value one or more semicolon-delimited MIME types. In my case I was interested in associating TunesViewer with iTunes Store URLs, which use their own protocol identifiers[8], so I had to specify MIME types for those protocols:

  • itms://  -> x-schema-handler/itms
  • itmss:// -> x-schema-handler/itmss
  • itpc://  -> x-schema-handler/itpc

Now, it would be a relatively slow operation if every time a user wanted to open a file the system had to search through individual Desktop Entry files until it found a matching MIME type. To aid in this, the system generates a file that acts as a MIME type cache. This file lists all the known MIME types that have program associations along with the Desktop Entry files in which they appear. In Ubuntu, at least, this file is /usr/share/applications/mimeinfo.cache. As such, once a change is made to a Desktop Entry file, the following command must be run for any changes in MIME type associations to take effect:

Voila! It worked. But something still nagged at me: …why did I need to do this in the first place?

The answer to that question came to me in the form of a software update. A few days after I had solved the problem, TunesViewer released its version 1.3. Among other things, it addressed the compatibility issues it had with Ubuntu 11.04. Even better, included in the version notes was an explanation as to why they had to make the change. It turned out to be because of Ubuntu’s choice to go with GNOME 3.0 as the backend for its default user environment for 11.04, whereas in prior versions they used GNOME 2.x. With the release of version 3.0, GNOME decided to switch its default URL handling scheme from using GConf to using MIME types in Desktop Entry files. Now, while they had understandable and perhaps even good reason for doing this, a year thence there has been almost no coverage on it and there’s still some work to be done on the GNOME project to bring it in-line with the proposed change. There may be other applications that still need to make the transition as well.


    Additional References

  1. [1] Desktop Entry Specification (Latest)
  2. [2] GConf Configuration System
  3. [3] Re: how to add a uri protocol handler? (i.e. irc://) – ubuntuforums.org
  4. [4] Using gnome-open to open pdf files – askubuntu.com
  5. [5] xdg-open vs exo-open – teranex weblog
  6. [6] MIME – Wikipedia
  7. [7] deb (file format) – Wikipedia
  8. [8] Definition of Protocol Identifier – eHow.com

3 comments to Creating custom URL handlers in Ubuntu 11.04, 11.10, GNOME 3.0

  • Great post, I was looking for the command to update the xdg mime database, and update-desktop-database was just the thing. Thanks!

  • Markus

    Thanks a lot for your post! It has helped me out to define the URL for sip and callto links identified by Thunderbird and Firefox addon Telify under Ubuntu 12.10.
    Now I can easily call from both applications using SFLPhone which works very vell

  • Jonathan Pasquier

    Hi,

    Thanks for the article!
    It has helped me a lot with a problem I had making Ubuntu/LibreOffice handling correctly the vnd.sun.star.webdav protocol.
    Thanks to your article I was able to find a workaround and to propose a possible fix to LibreOffice (see https://www.libreoffice.org/bugzilla/show_bug.cgi?id=65261 for the workaround and the fix)

Leave a Reply