diff options
Diffstat (limited to 'src/im-application-list.c')
-rw-r--r-- | src/im-application-list.c | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/src/im-application-list.c b/src/im-application-list.c index 14af69b..684a2e4 100644 --- a/src/im-application-list.c +++ b/src/im-application-list.c @@ -21,10 +21,13 @@ #include "indicator-messages-application.h" #include "gactionmuxer.h" +#include "indicator-desktop-shortcuts.h" #include <gio/gdesktopappinfo.h> #include <string.h> +#include "glib/gi18n.h" + typedef GObjectClass ImApplicationListClass; struct _ImApplicationList @@ -66,12 +69,12 @@ typedef struct gchar *id; IndicatorMessagesApplication *proxy; GActionMuxer *muxer; - GSimpleActionGroup *actions; GSimpleActionGroup *source_actions; GSimpleActionGroup *message_actions; GActionMuxer *message_sub_actions; GCancellable *cancellable; gboolean draws_attention; + IndicatorDesktopShortcuts * shortcuts; } Application; @@ -108,9 +111,39 @@ application_free (gpointer data) g_object_unref (app->message_sub_actions); } + g_clear_object (&app->shortcuts); + g_slice_free (Application, app); } +/* Check to see if we have actions by getting the full list of + names and see if there is one. Not exactly efficient :-/ */ +static gboolean +_g_action_group_has_actions (GActionGroup * ag) +{ + gchar ** list = NULL; + gboolean retval = FALSE; + + list = g_action_group_list_actions(ag); + retval = (list[0] != NULL); + g_strfreev(list); + + return retval; +} + +/* Check to see if either of our action groups has any actions, if + so return TRUE so we get chosen! */ +static gboolean +application_has_items (gpointer key, + gpointer value, + gpointer user_data) +{ + Application *app = value; + + return _g_action_group_has_actions(G_ACTION_GROUP(app->source_actions)) || + _g_action_group_has_actions(G_ACTION_GROUP(app->message_actions)); +} + static gboolean application_draws_attention (gpointer key, gpointer value, @@ -124,18 +157,61 @@ application_draws_attention (gpointer key, static void im_application_list_update_draws_attention (ImApplicationList *list) { + const gchar *base_icon_name; + const gchar *accessible_name; const gchar *icon_name; + GIcon * icon; + GVariantBuilder builder; GVariant *state; - GActionGroup *main_actions; - if (g_hash_table_find (list->applications, application_draws_attention, NULL)) - icon_name = "indicator-messages-new"; - else - icon_name = "indicator-messages"; + /* Figure out what type of icon we should be drawing */ + if (g_hash_table_find (list->applications, application_draws_attention, NULL)) { + base_icon_name = "indicator-messages-new-%s"; + accessible_name = _("New Messages"); + } else { + base_icon_name = "indicator-messages-%s"; + accessible_name = _("Messages"); + } - main_actions = g_action_muxer_get_group (list->muxer, NULL); - state = g_variant_new ("(sssb)", "", icon_name, "Messages", TRUE); - g_action_group_change_action_state (main_actions, "messages", state); + /* Include the IM state in the icon */ + state = g_action_group_get_action_state(G_ACTION_GROUP(list->globalactions), "status"); + icon_name = g_strdup_printf(base_icon_name, g_variant_get_string(state, NULL)); + g_variant_unref(state); + + /* Build up the dictionary of values for the state */ + g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY); + + /* icon */ + g_variant_builder_open(&builder, G_VARIANT_TYPE_DICT_ENTRY); + g_variant_builder_add_value(&builder, g_variant_new_string("icon")); + icon = g_themed_icon_new_with_default_fallbacks(icon_name); + g_variant_builder_add_value(&builder, g_variant_new_variant(g_icon_serialize(icon))); + g_object_unref(icon); + g_variant_builder_close(&builder); + + /* accessible description */ + g_variant_builder_open(&builder, G_VARIANT_TYPE_DICT_ENTRY); + g_variant_builder_add_value(&builder, g_variant_new_string("accessible-desc")); + g_variant_builder_add_value(&builder, g_variant_new_variant(g_variant_new_string(accessible_name))); + g_variant_builder_close(&builder); + + /* visibility */ + g_variant_builder_open(&builder, G_VARIANT_TYPE_DICT_ENTRY); + g_variant_builder_add_value(&builder, g_variant_new_string("visible")); + g_variant_builder_add_value(&builder, g_variant_new_variant(g_variant_new_boolean(TRUE))); + g_variant_builder_close(&builder); + + /* Set the state */ + g_action_group_change_action_state (G_ACTION_GROUP(list->globalactions), "messages", g_variant_builder_end(&builder)); + + GAction * remove_action = g_simple_action_group_lookup(list->globalactions, "remove-all"); + if (g_hash_table_find (list->applications, application_has_items, NULL)) { + g_debug("Enabling remove-all"); + g_simple_action_set_enabled(G_SIMPLE_ACTION(remove_action), TRUE); + } else { + g_debug("Disabling remove-all"); + g_simple_action_set_enabled(G_SIMPLE_ACTION(remove_action), FALSE); + } } /* Check a source action to see if it draws */ @@ -490,7 +566,6 @@ static void im_application_list_init (ImApplicationList *list) { const GActionEntry action_entries[] = { - { "messages", NULL, NULL, "('', 'indicator-messages', 'Messages', true)", NULL }, { "remove-all", im_application_list_remove_all } }; @@ -498,6 +573,10 @@ im_application_list_init (ImApplicationList *list) list->app_status = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); list->globalactions = g_simple_action_group_new (); + { + GSimpleAction * messages = g_simple_action_new_stateful("messages", G_VARIANT_TYPE("a{sv}"), g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0)); + g_simple_action_group_insert(list->globalactions, G_ACTION(messages)); + } g_simple_action_group_add_entries (list->globalactions, action_entries, G_N_ELEMENTS (action_entries), list); list->statusaction = g_simple_action_new_stateful("status", G_VARIANT_TYPE_STRING, g_variant_new_string("offline")); @@ -507,6 +586,7 @@ im_application_list_init (ImApplicationList *list) list->muxer = g_action_muxer_new (); g_action_muxer_insert (list->muxer, NULL, G_ACTION_GROUP (list->globalactions)); + im_application_list_update_draws_attention (list); } ImApplicationList * @@ -573,7 +653,7 @@ im_application_list_activate_app_action (GSimpleAction *action, { Application *app = user_data; - g_desktop_app_info_launch_action (app->info, g_action_get_name (G_ACTION (action)), NULL); + indicator_desktop_shortcuts_nick_exec_with_context (app->shortcuts, g_action_get_name (G_ACTION (action)), NULL); } gboolean @@ -585,6 +665,7 @@ im_application_list_add (ImApplicationList *list, const gchar *id; GSimpleActionGroup *actions; GSimpleAction *launch_action; + IndicatorDesktopShortcuts * shortcuts = NULL; g_return_if_fail (IM_IS_APPLICATION_LIST (list)); g_return_if_fail (desktop_id != NULL); @@ -602,6 +683,12 @@ im_application_list_add (ImApplicationList *list, id = g_app_info_get_id (G_APP_INFO (info)); g_return_if_fail (id != NULL); + { + const char * filename = g_desktop_app_info_get_filename(info); + if (filename != NULL) + shortcuts = indicator_desktop_shortcuts_new(filename, "Messaging Menu"); + } + app = g_slice_new0 (Application); app->info = info; app->id = im_application_list_canonical_id (id); @@ -611,6 +698,7 @@ im_application_list_add (ImApplicationList *list, app->message_actions = g_simple_action_group_new (); app->message_sub_actions = g_action_muxer_new (); app->draws_attention = FALSE; + app->shortcuts = shortcuts; actions = g_simple_action_group_new (); @@ -618,14 +706,14 @@ im_application_list_add (ImApplicationList *list, g_signal_connect (launch_action, "activate", G_CALLBACK (im_application_list_activate_launch), app); g_action_map_add_action (G_ACTION_MAP (actions), G_ACTION (launch_action)); - { - const gchar *const *app_actions; + if (app->shortcuts != NULL) { + const gchar ** nicks; - for (app_actions = g_desktop_app_info_list_actions (app->info); *app_actions; app_actions++) + for (nicks = indicator_desktop_shortcuts_get_nicks (app->shortcuts); *nicks; nicks++) { GSimpleAction *action; - action = g_simple_action_new (*app_actions, NULL); + action = g_simple_action_new (*nicks, NULL); g_signal_connect (action, "activate", G_CALLBACK (im_application_list_activate_app_action), app); g_action_map_add_action (G_ACTION_MAP (actions), G_ACTION (action)); @@ -715,15 +803,21 @@ im_application_list_source_changed (Application *app, gint64 time; const gchar *string; gboolean draws_attention; + gboolean old_draw; g_variant_get (source, "(&s&s&sux&sb)", &id, &label, &iconstr, &count, &time, &string, &draws_attention); + old_draw = app_source_action_check_draw(app, id); + g_action_group_change_action_state (G_ACTION_GROUP (app->source_actions), id, g_variant_new ("(uxsb)", count, time, string, draws_attention)); g_signal_emit (app->list, signals[SOURCE_CHANGED], 0, app->id, id, label, iconstr); + if (!old_draw && draws_attention) + app->draws_attention = TRUE; + im_application_list_update_draws_attention (app->list); } @@ -1091,6 +1185,8 @@ status_activated (GSimpleAction * action, GVariant * param, gpointer user_data) g_signal_emit (list, signals[STATUS_SET], 0, status); + im_application_list_update_draws_attention(list); + return; } @@ -1136,6 +1232,8 @@ im_application_list_set_status (ImApplicationList * list, const gchar * id, cons g_simple_action_set_state(list->statusaction, g_variant_new_string(status_ids[final_status])); + im_application_list_update_draws_attention(list); + return; } |