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 <libgnome/gnome-util.h>
#include <libgnomeui/gnome-url.h>
#include <gdk/gdkx.h>
+#include <gmenu-tree.h>
#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_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 <gio/gio.h>
+
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;