aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-01-07 16:27:18 -0600
committerTed Gould <ted@gould.cx>2010-01-07 16:27:18 -0600
commit45e742eba4c7cae1c732c83acae43033f5c39e90 (patch)
treee2ea202c99647d7b1a230890362f0823a6d77545 /src
parent16fb78b663704da483de14c54fbcc4088a754c0e (diff)
downloadlibayatana-appindicator-45e742eba4c7cae1c732c83acae43033f5c39e90.tar.gz
libayatana-appindicator-45e742eba4c7cae1c732c83acae43033f5c39e90.tar.bz2
libayatana-appindicator-45e742eba4c7cae1c732c83acae43033f5c39e90.zip
Moving the list of applications management into the state change function. This makes it so that we can handle it appearing and disappearing all in one special place.
Diffstat (limited to 'src')
-rw-r--r--src/application-service-appstore.c136
1 files changed, 111 insertions, 25 deletions
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c
index 128139b..385bd16 100644
--- a/src/application-service-appstore.c
+++ b/src/application-service-appstore.c
@@ -53,6 +53,10 @@ struct _ApplicationServiceAppstorePrivate {
GList * applications;
};
+#define APP_STATUS_PASSIVE_STR "passive"
+#define APP_STATUS_ACTIVE_STR "active"
+#define APP_STATUS_ATTENTION_STR "attention"
+
typedef enum _ApplicationStatus ApplicationStatus;
enum _ApplicationStatus {
APP_STATUS_PASSIVE,
@@ -69,6 +73,9 @@ struct _Application {
DBusGProxy * prop_proxy;
gboolean validated; /* Whether we've gotten all the parameters and they look good. */
ApplicationStatus status;
+ gchar * icon;
+ gchar * aicon;
+ gchar * menu;
};
#define APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(o) \
@@ -89,6 +96,8 @@ static void application_service_appstore_class_init (ApplicationServiceAppstoreC
static void application_service_appstore_init (ApplicationServiceAppstore *self);
static void application_service_appstore_dispose (GObject *object);
static void application_service_appstore_finalize (GObject *object);
+static ApplicationStatus string_to_status(const gchar * status_string);
+static void apply_status (Application * app, ApplicationStatus status);
G_DEFINE_TYPE (ApplicationServiceAppstore, application_service_appstore, G_TYPE_OBJECT);
@@ -190,6 +199,7 @@ get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * err
Application * app = (Application *)data;
if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU) == NULL ||
+ g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_STATUS) == NULL ||
g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME) == NULL) {
g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name);
g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for.
@@ -198,24 +208,28 @@ get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * err
app->validated = TRUE;
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(app->appstore);
- 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,
- g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME)),
- 0, /* Position */
- app->dbus_name,
- g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU)),
- TRUE);
+ app->icon = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME));
+ app->menu = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU));
+ if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_AICON_NAME) != NULL) {
+ app->aicon = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME));
+ }
+
+ apply_status(app, string_to_status(g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_STATUS))));
return;
}
+/* Simple translation function -- could be optimized */
+static ApplicationStatus
+string_to_status(const gchar * status_string)
+{
+ if (!g_strcmp0(status_string, APP_STATUS_ACTIVE_STR))
+ return APP_STATUS_ACTIVE;
+ if (!g_strcmp0(status_string, APP_STATUS_ATTENTION_STR))
+ return APP_STATUS_ATTENTION;
+ return APP_STATUS_PASSIVE;
+}
+
/* A simple global function for dealing with freeing the information
in an Application structure */
static void
@@ -229,6 +243,15 @@ application_free (Application * app)
if (app->dbus_object != NULL) {
g_free(app->dbus_object);
}
+ if (app->icon != NULL) {
+ g_free(app->icon);
+ }
+ if (app->aicon != NULL) {
+ g_free(app->aicon);
+ }
+ if (app->menu != NULL) {
+ g_free(app->menu);
+ }
g_free(app);
return;
@@ -240,24 +263,84 @@ static void
application_removed_cb (DBusGProxy * proxy, gpointer userdata)
{
Application * app = (Application *)userdata;
- ApplicationServiceAppstore * appstore = app->appstore;
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
- GList * applistitem = g_list_find(priv->applications, app);
- if (applistitem == NULL) {
- g_warning("Removing an application that isn't in the application list?");
+ /* Remove from the panel */
+ apply_status(app, APP_STATUS_PASSIVE);
+
+ /* Destroy the data */
+ application_free(app);
+ return;
+}
+
+/* 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. */
+static void
+apply_status (Application * app, ApplicationStatus status)
+{
+ if (app->status == status) {
return;
}
- gint position = g_list_position(priv->applications, applistitem);
+ ApplicationServiceAppstore * appstore = app->appstore;
+ ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
- g_signal_emit(G_OBJECT(appstore),
- signals[APPLICATION_REMOVED], 0,
- position, TRUE);
+ /* This means we're going off line */
+ if (status == APP_STATUS_PASSIVE) {
+ GList * applistitem = g_list_find(priv->applications, app);
+ if (applistitem == NULL) {
+ g_warning("Removing an application that isn't in the application list?");
+ return;
+ }
+
+ gint position = g_list_position(priv->applications, applistitem);
+
+ g_signal_emit(G_OBJECT(appstore),
+ signals[APPLICATION_REMOVED], 0,
+ position, TRUE);
+
+ priv->applications = g_list_remove(priv->applications, app);
+ } else {
+ /* Figure out which icon we should be using */
+ gchar * newicon = app->icon;
+ if (status == APP_STATUS_ATTENTION && app->aicon != NULL) {
+ newicon = app->aicon;
+ }
+
+ /* 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,
+ TRUE);
+ } else {
+ /* Icon update */
+ GList * applistitem = g_list_find(priv->applications, app);
+ if (applistitem == NULL) {
+ g_warning("Change the icon of an application that isn't in the application list?");
+ return;
+ }
+
+ gint position = g_list_position(priv->applications, applistitem);
+
+ g_signal_emit(G_OBJECT(appstore),
+ signals[APPLICATION_ICON_CHANGED], 0,
+ position, newicon, TRUE);
+ }
+ }
- priv->applications = g_list_remove(priv->applications, app);
+ app->status = status;
- application_free(app);
return;
}
@@ -317,6 +400,9 @@ application_service_appstore_application_add (ApplicationServiceAppstore * appst
app->dbus_object = g_strdup(dbus_object);
app->appstore = appstore;
app->status = APP_STATUS_PASSIVE;
+ app->icon = NULL;
+ app->aicon = NULL;
+ app->menu = NULL;
/* Get the DBus proxy for the NotificationItem interface */
GError * error = NULL;