Hi, You have probably noticed that Ubuntu has generic symlinks for launching some types of applications, such as "x-www-browser", "x-terminal-emulator", "gnome-text-editor", etc. However, the exact application they launch is pretty much undefined from the user perspecitve, e.g. "x-www-browser" will launch Chrome even Firefox is set as preferred web browser.
The cause of it lies in Debian alternatives system (see http://wiki.debian.org/DebianAlternatives) which controls the symlinks; the priority for each candidate for the generic name is set by package maintainer, thus alternatives system doesn't take user preference into account. The symlinks can be controlled by the user via "update-alternatives" command-line tool, but the preferences in alternatives system are system-wide so if different users of an OS instance prefer different web browsers, you can't satisfy both of them. That aside, requiring the user to meddle with command line in addition to flipping a switch in gnome-control-center just to change the preferred app is not a great idea. To solve this, I wrote a wrapper that registers itself in alternatives system with a very high priority (500) and, when invoked via a symlink controlled by alternatives system, it determines the symlink by which it was invoked based on argv[0], then looks up the user preference for this kind of app by its primary mimetype and launches it. If it fails to do so, it falls back to the second-highest-priority item in alternatives system, i.e. executes the behavior which would happen if the wrapper wouldn't exist at all. The wrapper is ~200 lines of Vala code; the runtime dependencies are only Glib and Granite, but the latter is used for just one line - initialization of its logger service - and may be trivially avoided. The supported application types are hardcoded, because I don't think using a plugin system like libpeas will be of any benefit while it definitely will introduce much greater complexity. It currently supports web browsers, text editors and terminal emulators. It should be trivial to add support for other types of applications though. When invoking an application, the wrapper passes all parameters it receives to the target app as well as all open file descriptors, so stdin input and stdout/stderr redirection work properly. The wrapper is completely transparent, except one aspect: it launches applications asynchronously and exits as soon as one is invoked, so it always returns 0 if succeeds to launch the desired application and exits before the desired application exits. However, it should not be a problem since all the supported applications typically exhibit such behavior themselves (e.g. Firefox, Gedit, gnome-terminal). The wrapper doesn't support slave links, but they are rarely used for GUI applications anyway, so I don't think it will be a problem. Also, terminal emulators are kind of a special case because they don't have an associated mimetype, so the wrapper currently checks XDG_CURRENT_DESKTOP variable and if it's "unity", "gnome" or "pantheon" it reads the relevant GSettings key. Otherwise it exhibits the "I wasn't here" fallback behavior :) The source code can be found at https://code.launchpad.net/~elementary-os/elementaryos/user-specific-alternatives/ The branch includes Debian packaging as well; it's lintian-clean but wasn't reviewed by a Debian maintainer or Ubunty MOTU. The wrapper was originally written for use in elementary OS, but I believe it will be of use to Ubuntu too. Any feedback is welcome, not to mention instructions on proposing this for review and eventual inclusion in Ubuntu :) -- Sergey "Shnatsel" Davidoff -- Ubuntu-devel-discuss mailing list Ubuntu-devel-discuss@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel-discuss