aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/application-service-appstore.c106
-rw-r--r--src/application-service.xml2
-rw-r--r--src/indicator-application.c24
-rw-r--r--src/libappindicator/app-indicator.c6
4 files changed, 116 insertions, 22 deletions
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c
index fa1b9d2..d95007c 100644
--- a/src/application-service-appstore.c
+++ b/src/application-service-appstore.c
@@ -31,7 +31,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dbus-shared.h"
/* DBus Prototypes */
-static gboolean _application_service_server_get_applications (ApplicationServiceAppstore * appstore, GArray ** apps);
+static gboolean _application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error);
#include "application-service-server.h"
@@ -311,6 +311,28 @@ application_removed_cb (DBusGProxy * proxy, gpointer userdata)
return;
}
+static gboolean
+can_add_application (GList *applications, Application *app)
+{
+ if (applications)
+ {
+ GList *l = NULL;
+
+ for (l = applications; l != NULL; l = g_list_next (l))
+ {
+ Application *tmp_app = (Application *)l->data;
+
+ if (g_strcmp0 (tmp_app->dbus_name, app->dbus_name) == 0 &&
+ g_strcmp0 (tmp_app->dbus_object, app->dbus_object) == 0)
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
/* Change the status of the application. If we're going passive
it removes it from the panel. If we're coming online, then
it add it to the panel. Otherwise it changes the icon. */
@@ -333,8 +355,7 @@ apply_status (Application * app, ApplicationStatus status)
g_signal_emit(G_OBJECT(appstore),
signals[APPLICATION_REMOVED], 0,
position, TRUE);
-
- priv->applications = g_list_remove(priv->applications, app);
+ priv->applications = g_list_remove(priv->applications, app);
} else {
/* Figure out which icon we should be using */
gchar * newicon = app->icon;
@@ -344,21 +365,23 @@ apply_status (Application * app, ApplicationStatus status)
/* Determine whether we're already shown or not */
if (app->status == APP_STATUS_PASSIVE) {
- /* Put on panel */
- priv->applications = g_list_prepend(priv->applications, app);
-
- /* TODO: We need to have the position determined better. This
- would involve looking at the name and category and sorting
- it with the other entries. */
-
- g_signal_emit(G_OBJECT(app->appstore),
- signals[APPLICATION_ADDED], 0,
- newicon,
- 0, /* Position */
- app->dbus_name,
- app->menu,
- app->icon_path,
- TRUE);
+ if (can_add_application (priv->applications, app)) {
+ /* Put on panel */
+ priv->applications = g_list_prepend (priv->applications, app);
+
+ /* TODO: We need to have the position determined better. This
+ would involve looking at the name and category and sorting
+ it with the other entries. */
+
+ g_signal_emit(G_OBJECT(app->appstore),
+ signals[APPLICATION_ADDED], 0,
+ newicon,
+ 0, /* Position */
+ app->dbus_name,
+ app->menu,
+ app->icon_path,
+ TRUE);
+ }
} else {
/* Icon update */
gint position = get_position(app);
@@ -624,9 +647,52 @@ application_service_appstore_application_remove (ApplicationServiceAppstore * ap
/* DBus Interface */
static gboolean
-_application_service_server_get_applications (ApplicationServiceAppstore * appstore, GArray ** apps)
+_application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error)
{
+ ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+
+ *apps = g_ptr_array_new();
+ GList * listpntr;
+ gint position = 0;
+
+ for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
+ GValueArray * values = g_value_array_new(5);
+
+ GValue value = {0};
+
+ /* Icon name */
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, ((Application *)listpntr->data)->icon);
+ g_value_array_append(values, &value);
+ g_value_unset(&value);
+
+ /* Position */
+ g_value_init(&value, G_TYPE_INT);
+ g_value_set_int(&value, position++);
+ g_value_array_append(values, &value);
+ g_value_unset(&value);
+
+ /* DBus Address */
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, ((Application *)listpntr->data)->dbus_name);
+ g_value_array_append(values, &value);
+ g_value_unset(&value);
+
+ /* DBus Object */
+ g_value_init(&value, DBUS_TYPE_G_OBJECT_PATH);
+ g_value_set_static_boxed(&value, ((Application *)listpntr->data)->menu);
+ g_value_array_append(values, &value);
+ g_value_unset(&value);
+
+ /* Icon path */
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, ((Application *)listpntr->data)->icon_path);
+ g_value_array_append(values, &value);
+ g_value_unset(&value);
+
+ g_ptr_array_add(*apps, values);
+ }
- return FALSE;
+ return TRUE;
}
diff --git a/src/application-service.xml b/src/application-service.xml
index d74aaa9..0b2e959 100644
--- a/src/application-service.xml
+++ b/src/application-service.xml
@@ -26,7 +26,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
<!-- Methods -->
<method name="GetApplications">
- <arg type="a(siso)" name="applications" direction="out" />
+ <arg type="a(sisos)" name="applications" direction="out" />
</method>
<!-- Signals -->
diff --git a/src/indicator-application.c b/src/indicator-application.c
index ecaa7ae..5ed7a9e 100644
--- a/src/indicator-application.c
+++ b/src/indicator-application.c
@@ -97,6 +97,7 @@ static void application_added (DBusGProxy * proxy, const gchar * iconname, gint
static void application_removed (DBusGProxy * proxy, gint position , IndicatorApplication * application);
static void application_icon_changed (DBusGProxy * proxy, gint position, const gchar * iconname, IndicatorApplication * application);
static void get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata);
+static void get_applications_helper (gpointer data, gpointer user_data);
static void theme_dir_unref(IndicatorApplication * ia, const gchar * dir);
static void theme_dir_ref(IndicatorApplication * ia, const gchar * dir);
@@ -387,10 +388,33 @@ application_icon_changed (DBusGProxy * proxy, gint position, const gchar * iconn
static void
get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata)
{
+ if (error != NULL) {
+ g_warning("Unable to get application list: %s", error->message);
+ return;
+ }
+ g_ptr_array_foreach(OUT_applications, get_applications_helper, userdata);
return;
}
+/* A little helper that takes apart the DBus structure and calls
+ application_added on every entry in the list. */
+static void
+get_applications_helper (gpointer data, gpointer user_data)
+{
+ GValueArray * array = (GValueArray *)data;
+
+ g_return_if_fail(array->n_values == 5);
+
+ const gchar * icon_name = g_value_get_string(g_value_array_get_nth(array, 0));
+ gint position = g_value_get_int(g_value_array_get_nth(array, 1));
+ const gchar * dbus_address = g_value_get_string(g_value_array_get_nth(array, 2));
+ const gchar * dbus_object = g_value_get_boxed(g_value_array_get_nth(array, 3));
+ const gchar * icon_path = g_value_get_string(g_value_array_get_nth(array, 4));
+
+ return application_added(NULL, icon_name, position, dbus_address, dbus_object, icon_path, user_data);
+}
+
/* Refs a theme directory, and it may add it to the search
path */
static void
diff --git a/src/libappindicator/app-indicator.c b/src/libappindicator/app-indicator.c
index 6c969c2..b0f721e 100644
--- a/src/libappindicator/app-indicator.c
+++ b/src/libappindicator/app-indicator.c
@@ -370,6 +370,10 @@ app_indicator_dispose (GObject *object)
priv->menu = NULL;
}
+ if (priv->menuservice != NULL) {
+ g_object_unref (priv->menuservice);
+ }
+
if (priv->dbus_proxy != NULL) {
g_object_unref(G_OBJECT(priv->dbus_proxy));
priv->dbus_proxy = NULL;
@@ -754,7 +758,7 @@ fallback (AppIndicator * self)
gtk_status_icon_set_title(icon, app_indicator_get_id(self));
g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_STATUS,
- G_CALLBACK(status_icon_changes), icon);
+ G_CALLBACK(status_icon_status_wrapper), icon);
g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_ICON,
G_CALLBACK(status_icon_changes), icon);
g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON,