diff options
-rw-r--r-- | libindicator/indicator-service-manager.c | 22 | ||||
-rw-r--r-- | libindicator/indicator-service.c | 39 | ||||
-rw-r--r-- | libindicator/indicator-service.xml | 1 |
3 files changed, 58 insertions, 4 deletions
diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index f3a29d0..f58c148 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -536,8 +536,9 @@ service_proxy_name_changed (GDBusConnection * connection, const gchar * sender_n { IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); - const gchar * new_name; - g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_name); + const gchar * new_name = NULL; + const gchar * prev_name = NULL; + g_variant_get(parameters, "(&s&s&s)", NULL, &prev_name, &new_name); if (new_name == NULL || new_name[0] == 0) { if (priv->connected) { @@ -547,10 +548,27 @@ service_proxy_name_changed (GDBusConnection * connection, const gchar * sender_n start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); } else { + /* If we weren't connected before, we are now. Let's tell the + world! */ if (!priv->connected) { priv->connected = TRUE; g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, TRUE, TRUE); } + + /* If the names are both valid, and they're not the same, it means that + we've actually changed. So we need to tell the new guy that we're + watching them */ + if (new_name != NULL && prev_name != NULL && new_name[0] != 0 && prev_name != 0 && g_strcmp0(prev_name, new_name) != 0) { + /* Send watch */ + g_dbus_proxy_call(priv->service_proxy, + "Watch", + NULL, /* params */ + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->watch_cancel, + watch_cb, + user_data); + } } return; diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index e5eaa5b..d7ab375 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -57,6 +57,7 @@ struct _IndicatorServicePrivate { GHashTable * watchers; guint this_service_version; guint dbus_registration; + gboolean replace_mode; }; /* Signals Stuff */ @@ -192,6 +193,7 @@ indicator_service_init (IndicatorService *self) priv->this_service_version = 0; priv->timeout_length = 500; priv->dbus_registration = 0; + priv->replace_mode = FALSE; const gchar * timeoutenv = g_getenv("INDICATOR_SERVICE_SHUTDOWN_TIMEOUT"); if (timeoutenv != NULL) { @@ -202,6 +204,12 @@ indicator_service_init (IndicatorService *self) } } + const gchar * replaceenv = g_getenv("INDICATOR_SERVICE_REPLACE_MODE"); + if (replaceenv != NULL) { + priv->replace_mode = TRUE; + g_debug("Putting into replace mode"); + } + /* NOTE: We're using g_free here because that's what needs to happen, but you really should call watchers_remove first as well since that disconnects the signals. We can't do that with a callback @@ -397,6 +405,8 @@ bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar retval = bus_watch(service, sender); } else if (g_strcmp0(method, "UnWatch") == 0) { unwatch_core(service, sender); + } else if (g_strcmp0(method, "Shutdown") == 0) { + g_signal_emit(G_OBJECT(service), signals[SHUTDOWN], 0, TRUE); } else { g_warning("Calling method '%s' on the indicator service and it's unknown", method); } @@ -462,8 +472,33 @@ try_and_get_name_lost_cb (GDBusConnection * connection, const gchar * name, gpoi g_return_if_fail(connection != NULL); g_return_if_fail(INDICATOR_IS_SERVICE(user_data)); - g_warning("Name request failed."); - g_signal_emit(G_OBJECT(user_data), signals[SHUTDOWN], 0, TRUE); + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data); + + if (!priv->replace_mode) { + g_warning("Name request failed."); + g_signal_emit(G_OBJECT(user_data), signals[SHUTDOWN], 0, TRUE); + } else { + /* If we're in replace mode we can be a little more trickey + here. We're going to tell the other guy to shutdown and hope + that we get the name. */ + GDBusMessage * message = NULL; + message = g_dbus_message_new_method_call(name, + INDICATOR_SERVICE_OBJECT, + INDICATOR_SERVICE_INTERFACE, + "Shutdown"); + + g_dbus_connection_send_message(connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref(message); + + /* Check to see if we need to clean up a timeout */ + if (priv->timeout != 0) { + g_source_remove(priv->timeout); + priv->timeout = 0; + } + + /* Set a timeout for no watchers if we can't get the name */ + priv->timeout = g_timeout_add(priv->timeout_length * 4, timeout_no_watchers, user_data); + } return; } diff --git a/libindicator/indicator-service.xml b/libindicator/indicator-service.xml index 6bd7d80..71ef4df 100644 --- a/libindicator/indicator-service.xml +++ b/libindicator/indicator-service.xml @@ -13,6 +13,7 @@ <method name="UnWatch"> <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> </method> + <method name="Shutdown" /> <!-- Signals --> <!-- None currently --> |