From 474ff2e997a23c343b08ea0cd8bf2e75dc509ea2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 25 Feb 2011 14:41:39 -0500 Subject: [PATCH] Claim DBus names (Shell, Notifictions) *very* early See commit f2158218bef0c51 in mutter. Basically, we need to grab org.freedesktop.Notifications before anything else in the session gets started. Note: I intentionally removed the Util.killall bits. I believe that for notification-daemon at least, if we specify DBUS_NAME_FLAG_REPLACE_EXISTING, we'll take over the name. Not sure about notify-osd; if that's still a problem, then what we need to do is add killing (and possibly respawning) of notify-osd to "gnome-shell --replace", and not have it embedded randomly in a JS file. https://bugzilla.gnome.org/show_bug.cgi?id=642666 --- js/ui/main.js | 1 - js/ui/notificationDaemon.js | 26 ------------ src/gnome-shell-plugin.c | 83 +++++++++++++++++++++++++++++++++++++ src/shell-global.c | 65 ----------------------------- src/shell-global.h | 2 - 5 files changed, 83 insertions(+), 94 deletions(-) diff --git a/js/ui/main.js b/js/ui/main.js index 6b531fe60..5c6b952d0 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -88,7 +88,6 @@ function start() { Gio.DesktopAppInfo.set_desktop_env('GNOME'); - global.grab_dbus_service(); shellDBusService = new ShellDBus.GnomeShell(); // Force a connection now; dbus.js will do this internally // if we use its name acquisition stuff but we aren't right diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index 4984d4886..2285d588c 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -93,16 +93,6 @@ NotificationDaemon.prototype = { _init: function() { DBus.session.exportObject('/org/freedesktop/Notifications', this); - this._everAcquiredName = false; - DBus.session.acquire_name('org.freedesktop.Notifications', - // We pass MANY_INSTANCES so that if - // notification-daemon is running, we'll - // get queued behind it and then get the - // name after killing it below - DBus.MANY_INSTANCES, - Lang.bind(this, this._acquiredName), - Lang.bind(this, this._lostName)); - this._sources = {}; this._senderToPid = {}; this._notifications = {}; @@ -117,22 +107,6 @@ NotificationDaemon.prototype = { Lang.bind(this, this._onFocusAppChanged)); }, - _acquiredName: function() { - this._everAcquiredName = true; - }, - - _lostName: function() { - if (this._everAcquiredName) - log('Lost name org.freedesktop.Notifications!'); - else if (GLib.getenv('GNOME_SHELL_NO_REPLACE')) - log('Failed to acquire org.freedesktop.Notifications'); - else { - log('Failed to acquire org.freedesktop.Notifications; trying again'); - Util.killall('notification-daemon'); - Util.killall('notify-osd'); - } - }, - _iconForNotificationData: function(icon, hints, size) { let textureCache = St.TextureCache.get_default(); diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c index 1fe7de570..8e1192fa7 100644 --- a/src/gnome-shell-plugin.c +++ b/src/gnome-shell-plugin.c @@ -54,9 +54,13 @@ #include "st.h" #include "shell-a11y.h" +#define SHELL_DBUS_SERVICE "org.gnome.Shell" +#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier" + static void gnome_shell_plugin_dispose (GObject *object); static void gnome_shell_plugin_finalize (GObject *object); +static void gnome_shell_plugin_early_initialize (MetaPlugin *plugin); static void gnome_shell_plugin_start (MetaPlugin *plugin); static void gnome_shell_plugin_minimize (MetaPlugin *plugin, MetaWindowActor *actor); @@ -138,6 +142,7 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass) gobject_class->dispose = gnome_shell_plugin_dispose; gobject_class->finalize = gnome_shell_plugin_finalize; + plugin_class->early_initialize = gnome_shell_plugin_early_initialize; plugin_class->start = gnome_shell_plugin_start; plugin_class->map = gnome_shell_plugin_map; plugin_class->minimize = gnome_shell_plugin_minimize; @@ -403,6 +408,84 @@ muted_log_handler (const char *log_domain, /* Intentionally empty to discard message */ } +static void +gnome_shell_plugin_early_initialize (MetaPlugin *plugin) +{ + GError *error = NULL; + DBusGConnection *session; + DBusGProxy *bus; + guint32 request_name_result; + + /** TODO: + * In the future we should use GDBus for this. However, in + * order to do that, we need to port all of the JavaScript + * code. Otherwise, the name will be claimed on the wrong + * connection. + */ + session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + + bus = dbus_g_proxy_new_for_name (session, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + if (!dbus_g_proxy_call (bus, "RequestName", &error, + G_TYPE_STRING, SHELL_DBUS_SERVICE, + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) + { + g_print ("failed to acquire org.gnome.Shell: %s\n", error->message); + /* If we somehow got started again, it's not an error to be running + * already. So just exit 0. + */ + exit (0); + } + + /* Also grab org.gnome.Panel to replace any existing panel process, + * unless a special environment variable is passed. The environment + * variable is used by the gnome-shell (no --replace) launcher in + * Xephyr */ + if (!dbus_g_proxy_call (bus, "RequestName", &error, G_TYPE_STRING, + "org.gnome.Panel", G_TYPE_UINT, + DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE, + G_TYPE_INVALID, G_TYPE_UINT, + &request_name_result, G_TYPE_INVALID)) + { + g_print ("failed to acquire org.gnome.Panel: %s\n", error->message); + exit (1); + } + + /* ...and the org.gnome.Magnifier service. + */ + if (!dbus_g_proxy_call (bus, "RequestName", &error, + G_TYPE_STRING, MAGNIFIER_DBUS_SERVICE, + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) + { + g_print ("failed to acquire %s: %s\n", MAGNIFIER_DBUS_SERVICE, error->message); + /* Failing to acquire the magnifer service is not fatal. Log the error, + * but keep going. */ + } + + /* ...and the org.freedesktop.Notifications service. + */ + if (!dbus_g_proxy_call (bus, "RequestName", &error, + G_TYPE_STRING, "org.freedesktop.Notifications", + G_TYPE_UINT, DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) + { + g_print ("failed to acquire org.freedesktop.Notifications: %s\n", error->message); + } + + g_object_unref (bus); +} + static void gnome_shell_plugin_start (MetaPlugin *plugin) { diff --git a/src/shell-global.c b/src/shell-global.c index 4271123bc..f42237e63 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -35,9 +35,6 @@ #endif #include "shell-jsapi-compat-private.h" -#define SHELL_DBUS_SERVICE "org.gnome.Shell" -#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier" - static void grab_notify (GtkWidget *widget, gboolean is_grab, gpointer user_data); struct _ShellGlobal { @@ -1231,68 +1228,6 @@ shell_global_maybe_gc (ShellGlobal *global) gjs_context_maybe_gc (global->js_context); } -void -shell_global_grab_dbus_service (ShellGlobal *global) -{ - GError *error = NULL; - DBusGConnection *session; - DBusGProxy *bus; - guint32 request_name_result; - - session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); - - bus = dbus_g_proxy_new_for_name (session, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - if (!dbus_g_proxy_call (bus, "RequestName", &error, - G_TYPE_STRING, SHELL_DBUS_SERVICE, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - { - g_print ("failed to acquire org.gnome.Shell: %s\n", error->message); - /* If we somehow got started again, it's not an error to be running - * already. So just exit 0. - */ - exit (0); - } - - /* Also grab org.gnome.Panel to replace any existing panel process, - * unless a special environment variable is passed. The environment - * variable is used by the gnome-shell (no --replace) launcher in - * Xephyr */ - if (!g_getenv ("GNOME_SHELL_NO_REPLACE")) - { - if (!dbus_g_proxy_call (bus, "RequestName", &error, G_TYPE_STRING, - "org.gnome.Panel", G_TYPE_UINT, - DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE, - G_TYPE_INVALID, G_TYPE_UINT, - &request_name_result, G_TYPE_INVALID)) - { - g_print ("failed to acquire org.gnome.Panel: %s\n", error->message); - exit (1); - } - } - - /* ...and the org.gnome.Magnifier service. - */ - if (!dbus_g_proxy_call (bus, "RequestName", &error, - G_TYPE_STRING, MAGNIFIER_DBUS_SERVICE, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - { - g_print ("failed to acquire %s: %s\n", MAGNIFIER_DBUS_SERVICE, error->message); - /* Failing to acquire the magnifer service is not fatal. Log the error, - * but keep going. */ - } - g_object_unref (bus); -} - static void grab_notify (GtkWidget *widget, gboolean was_grabbed, gpointer user_data) { diff --git a/src/shell-global.h b/src/shell-global.h index 1f8eddf26..0adb32c25 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -59,8 +59,6 @@ gboolean shell_global_add_extension_importer (ShellGlobal *global, const char *directory, GError **error); -void shell_global_grab_dbus_service (ShellGlobal *global); - typedef enum { SHELL_STAGE_INPUT_MODE_NONREACTIVE, SHELL_STAGE_INPUT_MODE_NORMAL,