読者です 読者をやめる 読者になる 読者になる

I wrote a patch to xdg-open to support open url by preferred application which set by libfm-pref-apps command.

lxde

If you are using LXDE, you can set preferred application by libfm-pref-apps command(Preferences -> Preferred Application) but unfortunately xdg-open doesn't open your preferred application.
That code is here. If an URL is given, xdg-open calls open_generic().

open_lxde()
{
    # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
    if (echo "$1" | grep -q '^file://' ||
        ! echo "$1" | egrep -q '^[a-zA-Z+\.\-]+:')
    then
        local file="$(echo "$1" | sed 's%^file://%%')"

        # handle relative paths
        if ! echo "$file" | grep -q '^/'; then
            file="$(pwd)/$file"
        fi

        pcmanfm "$file"

    else
        open_generic "$1"
    fi

    if [ $? -eq 0 ]; then
        exit_success
    else
        exit_failure_operation_failed
    fi
}

Actually, it uses x-www-browser to open the URL.

[masami@rune]~% /usr/bin/xdg-open http://www.google.com
/usr/bin/xdg-open: line 584: x-www-browser: command not found

If you use Debian, you may not have any problems with x-www-browser but Fedora does have because default installation of Fedora doesn't set x-www-browser. so there was a two ways to open url by your favorite browser. One is set x-www-browser by update-alternatives command and the other is to write patch to read preferred application setting from system. Using update-alternatives is easy but you need to do libfm-pref-apps and update-alternatives. However, to read preferred application setting from system seems fun so that I chose it :D

At first, I checked libfm-pref-apps.c to where it saves configuration.

 191 
 192         /* get currently selected web browser */
 193         app = fm_app_chooser_combo_box_get_selected(GTK_COMBO_BOX(browser), &is_changed);
 194         if(app)
 195         {
 196             if(is_changed)
 197             {
 198 //                g_key_file_set_string(kf, "Preferred Applications", "WebBrowser", g_app_info_get_id(app));
 199                 g_app_info_set_as_default_for_type(app, "x-scheme-handler/http", NULL);
 200             }
 201             g_object_unref(app);
 202         }
 203         custom_apps = fm_app_chooser_combo_box_get_custom_apps(GTK_COMBO_BOX(browser));
 204         if(custom_apps)
 205         {
 206             const char** sl;
 207             len = g_list_length(custom_apps);
 208             sl = g_new0(char*, len);
 209             for(i = 0, l=custom_apps;l;l=l->next, ++i)
 210             {
 211                 app = G_APP_INFO(l->data);
 212                 sl[i] = g_app_info_get_id(app);
 213             }
 214             g_key_file_set_string_list(kf, "Preferred Applications", "CustomWebBrowsers", sl, len);
 215             g_free(sl);
 216             /* custom_apps is owned by the combobox and shouldn't be freed. */
 217         }

As you can see there is two if conditions. If you choose Customize, it configuration stored in ~/.config/libfm/pref-apps.conf. However, if you choose an application, it stored in ~/.local/share/applications/mimeapps.list.
In ~/.config/libfm/pref-apps.conf, data stores like that.

[Preferred Applications]
CustomWebBrowsers=fedora-jd.desktop;

In ~/.local/share/applications/mimeapps.list, data stores like that.

[Default Applications]
x-scheme-handler/http=google-chrome.desktop
image/png=fedora-gpicview.desktop
video/x-ms-wmv=totem.desktop
x-scheme-handler/mailto=redhat-sylpheed.desktop

[Added Associations]
x-scheme-handler/http=google-chrome.desktop;mozilla-firefox.desktop;fedora-jd.desktop;
image/png=fedora-gpicview.desktop;
video/x-ms-wmv=fedora-gxine.desktop;
x-scheme-handler/mailto=mozilla-thunderbird.desktop;redhat-sylpheed.desktop;

If both files aren't found, default setting may read from /etc/xdg/libfm/pref-apps.conf. This file contains following lines.

[Preferred Applications]
WebBrowser=mozilla-firefox.desktop
MailClient=

So, there is three configuration files to store preferred application setting. These priority seems that.
1. ~/.local/share/applications/mimeapps.list
2. ~/.config/libfm/pref-apps.conf
3. /etc/xdg/libfm/pref-apps.conf
OK, now I understand what files should I read, and reading order :)

--- xdg-open.bk 2011-10-16 12:24:30.424863283 +0900
+++ xdg-open    2011-10-16 12:21:52.827920993 +0900
@@ -610,7 +610,34 @@
         pcmanfm "$file"
 
     else
-        open_generic "$1"
+        # Lxde's default application setting will be in ~/.local/share/applications/mimeapps.list or
+        # ~/.config/libfm/prep-apps.conf, or /etc/xdg/libfm/prep-apps.conf.
+        # That setting has done by libfm-pref-apps command.
+       desktopfile=""
+       searchfile="$HOME/.local/share/applications/mimeapps.list"
+       if [ -e $searchfile ]; then
+           tmp=`grep "x-scheme-handler/http" $searchfile | grep -v ";"`
+           if [ x"$tmp" != "x" ]; then
+               desktopfile=`echo $tmp | cut -f2 -d'='`
+           fi
+       fi
+       if [ x"$desktopfile" = "x" ]; then
+           for searchfile in "$HOME/.config/libfm/pref-apps.conf" "/etc/xdg/libfm/pref-apps.conf"; do
+               if [ -e $searchfile ]; then
+                   tmp=`grep Browser $searchfile`
+                   if [ x"$tmp" != "x" ]; then
+                       desktopfile=`echo $tmp | cut -f2 -d'=' | cut -f1 -d';'`
+                       break
+                   fi
+               fi
+           done
+       fi
+       browser=""
+       if [ x"$desktopfile" != "x" ]; then
+           browser=`desktop_file_to_binary $desktopfile`
+       fi
+
+       $browser $1
     fi
 
     if [ $? -eq 0 ]; then