diff -up gnome-panel-2.21.91/gnome-panel/main.c.preferred-apps gnome-panel-2.21.91/gnome-panel/main.c --- gnome-panel-2.21.91/gnome-panel/main.c.preferred-apps 2008-02-11 16:15:47.000000000 -0500 +++ gnome-panel-2.21.91/gnome-panel/main.c 2008-02-13 20:44:49.000000000 -0500 @@ -26,6 +26,7 @@ #include "panel-action-protocol.h" #include "panel-lockdown.h" #include "panel-icon-names.h" +#include "launcher.h" #include "xstuff.h" #include "nothing.cP" @@ -81,6 +82,7 @@ main (int argc, char **argv) GCONF_CLIENT_PRELOAD_NONE, NULL); + panel_preferred_apps_init (); panel_global_config_load (); panel_lockdown_init (); panel_profile_load (); diff -up gnome-panel-2.21.91/gnome-panel/launcher.c.preferred-apps gnome-panel-2.21.91/gnome-panel/launcher.c --- gnome-panel-2.21.91/gnome-panel/launcher.c.preferred-apps 2008-02-13 20:44:49.000000000 -0500 +++ gnome-panel-2.21.91/gnome-panel/launcher.c 2008-02-13 20:44:49.000000000 -0500 @@ -23,6 +23,7 @@ #include #include #include +#include #include "launcher.h" @@ -40,6 +41,7 @@ #include "panel-compatibility.h" #include "panel-ditem-editor.h" #include "panel-icon-names.h" +#include "panel-run-dialog.h" static GdkScreen * launcher_get_screen (Launcher *launcher) @@ -1299,3 +1301,173 @@ panel_launcher_set_dnd_enabled (Launcher } else gtk_drag_source_unset (launcher->button); } + +static gchar * +find_desktop_file_from_exec (const gchar *exec) +{ + GSList *all_applications, *l; + gchar *path = NULL; + gchar **tokens, **tokens2; + gint i, match = 0; + + /* FIXME no need to construct a humongous list here */ + all_applications = get_all_applications (); + + for (l = all_applications; l; l = l->next) { + GMenuTreeEntry *entry = l->data; + const char *entry_exec; + + entry_exec = gmenu_tree_entry_get_exec (entry); + + if (strcmp (exec, entry_exec) == 0) { + path = gmenu_tree_entry_get_desktop_file_path (entry); + break; + } + + tokens = g_strsplit (exec, " ", -1); + tokens2 = g_strsplit (entry_exec, " ", -1); + + for (i = 0; tokens[i] && tokens2[i]; i++) { + if (strcmp (tokens[i], tokens2[i]) != 0) + break; + } + if (i > match) { + match = i; + path = gmenu_tree_entry_get_desktop_file_path (entry); + } + + g_strfreev (tokens); + g_strfreev (tokens2); + } + + path = g_strdup (path); + g_slist_free (all_applications); + + return path; +} + +static void +update_preferred_app (const gchar *filename, + const gchar *key, + const gchar *exec) +{ + gchar *location; + GKeyFile *key_file; + GError *error = NULL; + gchar *data; + gsize len; + gboolean needs_terminal; + + location = find_desktop_file_from_exec (exec); + key_file = g_key_file_new (); + if (!panel_util_key_file_load_from_uri (key_file, location, + G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, + NULL)) { + /* FIXME would be much better if preferred apps were backed by desktop files */ + g_key_file_set_string (key_file, "Desktop Entry", "Version", "1.0"); + g_key_file_set_string (key_file, "Desktop Entry", "Encoding", "UTF-8"); + g_key_file_set_string (key_file, "Desktop Entry", "Type", "Application"); + g_key_file_set_string (key_file, "Desktop Entry", "Exec", exec); + if (strstr (key, "http")) { + g_key_file_set_string (key_file, "Desktop Entry", "Name", "Preferred Web Browser"); + g_key_file_set_string (key_file, "Desktop Entry", "GenericName", "Web Browser"); + g_key_file_set_string (key_file, "Desktop Entry", "Comment", "Browse the Web"); + g_key_file_set_string (key_file, "Desktop Entry", "Icon", "redhat-web-browser.png"); + } + else if (strstr (key, "mailto")) { + g_key_file_set_string (key_file, "Desktop Entry", "Name", "Preferred Mail Reader"); + g_key_file_set_string (key_file, "Desktop Entry", "GenericName", "Mail Reader"); + g_key_file_set_string (key_file, "Desktop Entry", "Comment", "Send email"); + g_key_file_set_string (key_file, "Desktop Entry", "Icon", "redhat-email.png"); + } + if (g_str_has_suffix (key, "command")) { + int len; + char *key2; + + len = strlen (key); + key2 = g_new (char, len - strlen ("command") + strlen ("needs_terminal") + 1); + strncpy (key2, key, len - strlen ("command")); + strcpy (key2 + len - strlen ("command"), "needs_terminal"); + needs_terminal = gconf_client_get_bool (panel_gconf_get_client (), + key2, + NULL); + g_free (key2); + } + else + needs_terminal = FALSE; + g_key_file_set_boolean (key_file, "Desktop Entry", "Terminal", needs_terminal); + } + + g_free (location); + + g_key_file_set_boolean (key_file, "Desktop Entry", "X-Panel-Monitor", TRUE); + g_key_file_set_boolean (key_file, "Desktop Entry", "NoDisplay", TRUE); + + data = g_key_file_to_data (key_file, &len, &error); + if (error) { + g_printerr (_("Failed to convert data for '%s': %s"), + filename, error->message); + g_error_free (error); + g_key_file_free (key_file); + + return; + } + if (!g_file_set_contents (filename, data, len, &error)) { + g_printerr (_("Failed to save '%s': %s"), + filename, error->message); + g_error_free (error); + } + + g_key_file_free (key_file); + g_free (data); +} + +static void +preferred_app_changed (GConfClient *client, + gint notify_id, + GConfEntry *entry, + const gchar *filename) +{ + update_preferred_app (filename, + gconf_entry_get_key (entry), + gconf_value_get_string (entry->value)); +} + +void +panel_preferred_apps_init (void) +{ + GConfClient *client; + gchar *dirname, *filename, *exec; + gint i; + + const gchar *keys[] = { + "/desktop/gnome/url-handlers/http/command", + "/desktop/gnome/url-handlers/mailto/command", + NULL }; + const gchar *files[] = { + "preferred-web-browser.desktop", + "preferred-mail-reader.desktop", + NULL }; + + client = panel_gconf_get_client (); + + for (i = 0; keys[i]; i++) { + dirname = g_build_filename (g_get_user_data_dir (), + "applications", NULL); + filename = g_build_filename (dirname, files[i], NULL); + if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { + + if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) + g_mkdir_with_parents (dirname, 0755); + + exec = gconf_client_get_string (client, keys[i], NULL); + update_preferred_app (filename, keys[i], exec); + g_free (exec); + } + g_free (dirname); + + gconf_client_notify_add (client, keys[i], + (GConfClientNotifyFunc) preferred_app_changed, + filename, g_free, NULL); + } +} diff -up gnome-panel-2.21.91/gnome-panel/launcher.h.preferred-apps gnome-panel-2.21.91/gnome-panel/launcher.h --- gnome-panel-2.21.91/gnome-panel/launcher.h.preferred-apps 2008-02-13 20:44:49.000000000 -0500 +++ gnome-panel-2.21.91/gnome-panel/launcher.h 2008-02-13 20:45:58.000000000 -0500 @@ -14,6 +14,8 @@ #include "applet.h" #include "panel-widget.h" +#include + G_BEGIN_DECLS #define PANEL_LAUNCHERS_PATH "panel2.d/default/launchers" @@ -73,6 +75,7 @@ void launcher_properties_dest void panel_launcher_set_dnd_enabled (Launcher *launcher, gboolean dnd_enabled); +void panel_preferred_apps_init (void); G_END_DECLS diff -up gnome-panel-2.21.91/gnome-panel/panel-run-dialog.h.preferred-apps gnome-panel-2.21.91/gnome-panel/panel-run-dialog.h --- gnome-panel-2.21.91/gnome-panel/panel-run-dialog.h.preferred-apps 2008-02-11 16:15:47.000000000 -0500 +++ gnome-panel-2.21.91/gnome-panel/panel-run-dialog.h 2008-02-13 20:44:49.000000000 -0500 @@ -32,6 +32,8 @@ G_BEGIN_DECLS void panel_run_dialog_present (GdkScreen *screen, guint32 activate_time); +GSList *get_all_applications (void); + G_END_DECLS #endif /* __PANEL_RUN_DIALOG_H__ */ diff -up gnome-panel-2.21.91/gnome-panel/panel-run-dialog.c.preferred-apps gnome-panel-2.21.91/gnome-panel/panel-run-dialog.c --- gnome-panel-2.21.91/gnome-panel/panel-run-dialog.c.preferred-apps 2008-02-11 16:15:47.000000000 -0500 +++ gnome-panel-2.21.91/gnome-panel/panel-run-dialog.c 2008-02-13 20:44:49.000000000 -0500 @@ -816,7 +816,7 @@ get_all_applications_from_dir (GMenuTree return list; } -static GSList * +GSList * get_all_applications (void) { GMenuTree *tree;