aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2012-06-27 23:55:52 +0200
committerLars Uebernickel <lars.uebernickel@canonical.com>2012-06-27 23:55:52 +0200
commit37acacae18286dbfeceacc74db8e5ff02ae8f8b2 (patch)
tree56653f2c9c133fade84087f64eda8c9a09f3ad17 /src
parent6c93ee8e97bca993273c9dcfbebd3e52d0ac6c83 (diff)
downloadayatana-indicator-messages-37acacae18286dbfeceacc74db8e5ff02ae8f8b2.tar.gz
ayatana-indicator-messages-37acacae18286dbfeceacc74db8e5ff02ae8f8b2.tar.bz2
ayatana-indicator-messages-37acacae18286dbfeceacc74db8e5ff02ae8f8b2.zip
Only show chat section when necessary
The chat section is only shown when an application that is registered to use it is running. Applications are registered if their desktop file contains: X-MessagingMenu-UsesChatStatus: true
Diffstat (limited to 'src')
-rw-r--r--src/app-section.c74
-rw-r--r--src/app-section.h1
-rw-r--r--src/messages-service.c39
3 files changed, 110 insertions, 4 deletions
diff --git a/src/app-section.c b/src/app-section.c
index e7a2e1d..fb3d8f9 100644
--- a/src/app-section.c
+++ b/src/app-section.c
@@ -46,6 +46,7 @@ struct _AppSectionPrivate
GActionGroup *actions;
gboolean draws_attention;
+ gboolean uses_chat_status;
guint name_watch_id;
};
@@ -55,6 +56,7 @@ enum {
PROP_APPINFO,
PROP_ACTIONS,
PROP_DRAWS_ATTENTION,
+ PROP_USES_CHAT_STATUS,
NUM_PROPERTIES
};
@@ -123,6 +125,12 @@ app_section_class_init (AppSectionClass *klass)
FALSE,
G_PARAM_READABLE);
+ properties[PROP_USES_CHAT_STATUS] = g_param_spec_boolean ("uses-chat-status",
+ "Uses chat status",
+ "Whether the section uses the global chat status",
+ FALSE,
+ G_PARAM_READABLE);
+
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
@@ -165,6 +173,10 @@ app_section_get_property (GObject *object,
g_value_set_boolean (value, app_section_get_draws_attention (self));
break;
+ case PROP_USES_CHAT_STATUS:
+ g_value_set_boolean (value, app_section_get_uses_chat_status (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -245,11 +257,58 @@ nick_activate_cb (GSimpleAction *action,
}
static void
+keyfile_loaded (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AppSection *self = user_data;
+ gchar *contents;
+ gsize length;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+
+ if (!g_file_load_contents_finish (G_FILE (source_object), result,
+ &contents, &length, NULL, &error)) {
+ g_warning ("could not read key file: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_data (keyfile, contents, length, 0, &error)) {
+ g_warning ("could not read key file: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ self->priv->uses_chat_status = g_key_file_get_boolean (keyfile,
+ G_KEY_FILE_DESKTOP_GROUP,
+ "X-MessagingMenu-UsesChatStatus",
+ &error);
+ if (error) {
+ if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) {
+ g_warning ("could not read X-MessagingMenu-UsesChatSection: %s",
+ error->message);
+ }
+ g_error_free (error);
+ goto out;
+ }
+
+ if (self->priv->uses_chat_status)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]);
+
+out:
+ g_key_file_free (keyfile);
+ g_free (contents);
+}
+
+static void
app_section_set_app_info (AppSection *self,
GDesktopAppInfo *appinfo)
{
AppSectionPrivate *priv = self->priv;
GSimpleAction *launch;
+ GFile *keyfile;
g_return_if_fail (priv->appinfo == NULL);
@@ -288,6 +347,10 @@ app_section_set_app_info (AppSection *self,
g_free(name);
}
+ keyfile = g_file_new_for_path (g_desktop_app_info_get_filename (priv->appinfo));
+ g_file_load_contents_async (keyfile, NULL, keyfile_loaded, self);
+ g_object_unref (keyfile);
+
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]);
@@ -466,6 +529,7 @@ app_section_set_object_path (AppSection *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]);
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]);
g_object_thaw_notify (G_OBJECT (self));
}
@@ -507,6 +571,7 @@ app_section_unset_object_path (AppSection *self)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]);
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]);
}
static gboolean
@@ -594,3 +659,12 @@ action_removed (GActionGroup *group,
g_variant_unref (state);
}
+
+gboolean
+app_section_get_uses_chat_status (AppSection *self)
+{
+ AppSectionPrivate * priv = self->priv;
+
+ /* chat status is only useful when the app is running */
+ return priv->uses_chat_status && priv->actions;
+}
diff --git a/src/app-section.h b/src/app-section.h
index 9b2c99d..c351ada 100644
--- a/src/app-section.h
+++ b/src/app-section.h
@@ -63,6 +63,7 @@ void app_section_set_object_path (AppSection *self,
const gchar *bus_name,
const gchar *object_path);
void app_section_unset_object_path (AppSection *self);
+gboolean app_section_get_uses_chat_status (AppSection *self);
G_END_DECLS
diff --git a/src/messages-service.c b/src/messages-service.c
index 53d6509..6e88087 100644
--- a/src/messages-service.c
+++ b/src/messages-service.c
@@ -41,6 +41,7 @@ static GSimpleActionGroup *actions;
static GActionMuxer *action_muxer;
static GMenu *toplevel_menu;
static GMenu *menu;
+static GMenuModel *chat_section;
static GSettings *settings;
@@ -104,6 +105,36 @@ draws_attention_changed (GObject *object,
g_simple_action_set_enabled (clear, attention);
}
+static gboolean
+app_section_uses_chat (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ AppSection *section = value;
+ return app_section_get_uses_chat_status (section);
+}
+
+static void
+uses_chat_status_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ gboolean show_chat;
+ GMenuModel *first_section;
+
+ show_chat = g_hash_table_find (applications, app_section_uses_chat, NULL) != NULL;
+
+ first_section = g_menu_model_get_item_link (G_MENU_MODEL (menu), 0, G_MENU_LINK_SECTION);
+ if (first_section == chat_section) {
+ if (!show_chat)
+ g_menu_remove (menu, 0);
+ }
+ else {
+ if (show_chat)
+ g_menu_insert_section (menu, 0, NULL, chat_section);
+ }
+}
+
static AppSection *
add_application (const gchar *desktop_id)
{
@@ -131,6 +162,8 @@ add_application (const gchar *desktop_id)
G_CALLBACK (actions_changed), NULL);
g_signal_connect (section, "notify::draws-attention",
G_CALLBACK (draws_attention_changed), NULL);
+ g_signal_connect (section, "notify::uses-chat-status",
+ G_CALLBACK (uses_chat_status_changed), NULL);
/* TODO insert it at the right position (alphabetically by application name) */
menuitem = g_menu_item_new_section (NULL, app_section_get_menu (section));
@@ -429,7 +462,6 @@ main (int argc, char ** argv)
{
GMainLoop * mainloop = NULL;
IndicatorService * service = NULL;
- GMenuModel *status_items;
GMenuItem *header;
/* Glib init */
@@ -465,8 +497,7 @@ main (int argc, char ** argv)
G_CALLBACK (set_status), NULL);
menu = g_menu_new ();
- status_items = create_status_section ();
- g_menu_append_section (menu, NULL, status_items);
+ chat_section = create_status_section ();
g_menu_append (menu, _("Clear"), "clear");
toplevel_menu = g_menu_new ();
@@ -486,7 +517,7 @@ main (int argc, char ** argv)
/* Clean up */
g_object_unref (messages_service);
- g_object_unref (status_items);
+ g_object_unref (chat_section);
g_object_unref (settings);
g_hash_table_unref (applications);
return 0;