diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2013-11-08 20:44:47 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2013-11-08 20:44:47 +0000 |
commit | 102ef5c6977f53eb5dc211a0f1f2f5b1cde0352f (patch) | |
tree | ff47b2498dcac9b119b0b2257df9565df0654c46 | |
parent | 4af45b95b38c9fee98ddcfdf616fb8cda3e31823 (diff) | |
parent | 57ff63f095c33bb90a2eaf64acdb22d529bd0621 (diff) | |
download | ayatana-indicator-session-102ef5c6977f53eb5dc211a0f1f2f5b1cde0352f.tar.gz ayatana-indicator-session-102ef5c6977f53eb5dc211a0f1f2f5b1cde0352f.tar.bz2 ayatana-indicator-session-102ef5c6977f53eb5dc211a0f1f2f5b1cde0352f.zip |
fix a minor memory leak that was caused by treating the variant returned by g_icon_serialize() as floating.
Approved by Ted Gould, PS Jenkins bot.
-rw-r--r-- | src/service.c | 59 | ||||
-rw-r--r-- | tests/test-service.cc | 2 |
2 files changed, 49 insertions, 12 deletions
diff --git a/src/service.c b/src/service.c index efcb04f..9d9b953 100644 --- a/src/service.c +++ b/src/service.c @@ -105,6 +105,10 @@ struct _IndicatorSessionServicePrivate int rebuild_flags; GDBusConnection * conn; GCancellable * cancellable; + + /* serialized icon cache */ + GVariant * alert_icon_serialized; + GVariant * default_icon_serialized; }; typedef IndicatorSessionServicePrivate priv_t; @@ -148,7 +152,7 @@ action_state_for_header (IndicatorSessionService * self) { const priv_t * const p = self->priv; gboolean need_attn; - GIcon * icon; + GVariant * serialized_icon; gboolean show_name; const gchar * real_name; const gchar * label; @@ -159,12 +163,12 @@ action_state_for_header (IndicatorSessionService * self) if (indicator_session_actions_has_online_account_error (p->backend_actions)) { need_attn = TRUE; - icon = g_themed_icon_new (ICON_ALERT); + serialized_icon = p->alert_icon_serialized; } else { need_attn = FALSE; - icon = g_themed_icon_new (ICON_DEFAULT); + serialized_icon = p->default_icon_serialized; } show_name = g_settings_get_boolean (p->indicator_settings, @@ -196,7 +200,8 @@ action_state_for_header (IndicatorSessionService * self) /* build the state */ g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (a11y)); - g_variant_builder_add (&b, "{sv}", "icon", g_icon_serialize (icon)); + if (serialized_icon != NULL) + g_variant_builder_add (&b, "{sv}", "icon", serialized_icon); if (label && *label) g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); @@ -204,7 +209,6 @@ action_state_for_header (IndicatorSessionService * self) /* cleanup */ g_free (a11y); - g_object_unref (G_OBJECT (icon)); return state; } @@ -437,6 +441,25 @@ compare_users_by_label (gconstpointer ga, gconstpointer gb) return g_strcmp0 (a->user_name, b->user_name); } +static GVariant * +serialize_icon_file (const gchar * filename) +{ + GVariant * serialized_icon = NULL; + + if (filename != NULL) + { + GFile * file = g_file_new_for_path (filename); + GIcon * icon = g_file_icon_new (file); + + serialized_icon = g_icon_serialize (icon); + + g_object_unref (icon); + g_object_unref (file); + } + + return serialized_icon; +} + static GMenuModel * create_switch_section (IndicatorSessionService * self) { @@ -511,17 +534,16 @@ create_switch_section (IndicatorSessionService * self) for (i=0; i<users->len; ++i) { const IndicatorSessionUser * u = g_ptr_array_index (users, i); + GVariant * serialized_icon; + item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item"); - if (u->icon_file != NULL) + if ((serialized_icon = serialize_icon_file (u->icon_file))) { - GFile * file = g_file_new_for_path (u->icon_file); - GIcon * icon = g_file_icon_new (file); - g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, g_icon_serialize (icon)); - g_clear_object (&icon); - g_clear_object (&file); + g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, serialized_icon); + g_variant_unref (serialized_icon); } g_menu_append_item (menu, item); @@ -980,6 +1002,7 @@ indicator_session_service_init (IndicatorSessionService * self) GList * uids; priv_t * p; gpointer gp; + GIcon * icon; /* init our priv pointer */ p = G_TYPE_INSTANCE_GET_PRIVATE (self, @@ -995,6 +1018,16 @@ indicator_session_service_init (IndicatorSessionService * self) &p->backend_users, &p->backend_guest); + /* build the serialized icon cache */ + + icon = g_themed_icon_new_with_default_fallbacks (ICON_ALERT); + p->alert_icon_serialized = g_icon_serialize (icon); + g_object_unref (icon); + + icon = g_themed_icon_new_with_default_fallbacks (ICON_DEFAULT); + p->default_icon_serialized = g_icon_serialize (icon); + g_object_unref (icon); + /* init our key-to-User table */ p->users = g_hash_table_new_full (g_direct_hash, g_direct_equal, @@ -1152,6 +1185,10 @@ my_dispose (GObject * o) g_clear_object (&p->guest_switcher_action); g_clear_object (&p->conn); + /* clear the serialized icon cache */ + g_clear_pointer (&p->alert_icon_serialized, g_variant_unref); + g_clear_pointer (&p->default_icon_serialized, g_variant_unref); + G_OBJECT_CLASS (indicator_session_service_parent_class)->dispose (o); } diff --git a/tests/test-service.cc b/tests/test-service.cc index 19ec619..5ec86d2 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -342,7 +342,7 @@ class ServiceTest: public GTestDBusFixture if (expected_icon != NULL) { GVariant * v = g_variant_lookup_value (state, "icon", NULL); - GIcon * expected = g_themed_icon_new (expected_icon); + GIcon * expected = g_themed_icon_new_with_default_fallbacks (expected_icon); GIcon * actual = g_icon_deserialize (v); ASSERT_TRUE (g_icon_equal (expected, actual)); g_object_unref (actual); |