diff options
author | Lars Uebernickel <lars.uebernickel@canonical.com> | 2012-06-27 23:55:52 +0200 |
---|---|---|
committer | Lars Uebernickel <lars.uebernickel@canonical.com> | 2012-06-27 23:55:52 +0200 |
commit | 37acacae18286dbfeceacc74db8e5ff02ae8f8b2 (patch) | |
tree | 56653f2c9c133fade84087f64eda8c9a09f3ad17 | |
parent | 6c93ee8e97bca993273c9dcfbebd3e52d0ac6c83 (diff) | |
download | ayatana-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
-rw-r--r-- | src/app-section.c | 74 | ||||
-rw-r--r-- | src/app-section.h | 1 | ||||
-rw-r--r-- | src/messages-service.c | 39 |
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; |