+
+ g_object_unref (main_icon);
+ }
+ else
+ icon = NULL;
+
+ g_variant_iter_free (emblems);
+ g_variant_unref (icon_data);
+
+ return icon;
+}
+
+/**
+ * g_icon_deserialize:
+ * @value: a #GVariant created with g_icon_serialize()
+ *
+ * Deserializes a #GIcon previously serialized using g_icon_serialize().
+ *
+ * Returns: (transfer full): a #GIcon, or %NULL when deserialization fails.
+ *
+ * Since: 2.38
+ */
+GIcon *
+g_icon_deserialize (GVariant *value)
+{
+ const gchar *tag;
+ GVariant *val;
+ GIcon *icon;
+
+ g_return_val_if_fail (value != NULL, NULL);
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) ||
+ g_variant_is_of_type (value, G_VARIANT_TYPE ("(sv)")), NULL);
+
+ /* Handle some special cases directly so that people can hard-code
+ * stuff into GMenuModel xml files without resorting to using GVariant
+ * text format to describe one of the explicitly-tagged possibilities
+ * below.
+ */
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ return g_icon_new_for_string_simple (g_variant_get_string (value, NULL));
+
+ /* Otherwise, use the tagged union format */
+ g_variant_get (value, "(&sv)", &tag, &val);
+
+ icon = NULL;
+
+ if (g_str_equal (tag, "file") && g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
+ {
+ GFile *file;
+
+ file = g_file_new_for_commandline_arg (g_variant_get_string (val, NULL));
+ icon = g_file_icon_new (file);
+ g_object_unref (file);
+ }
+ else if (g_str_equal (tag, "themed") && g_variant_is_of_type (val, G_VARIANT_TYPE_STRING_ARRAY))
+ {
+ const gchar **names;
+ gsize size;
+
+ names = g_variant_get_strv (val, &size);
+ icon = g_themed_icon_new_from_names ((gchar **) names, size);
+ g_free (names);
+ }
+ else if (g_str_equal (tag, "bytes") && g_variant_is_of_type (val, G_VARIANT_TYPE_BYTESTRING))
+ {
+ GBytes *bytes;
+
+ bytes = g_variant_get_data_as_bytes (val);
+ icon = g_bytes_icon_new (bytes);
+ g_bytes_unref (bytes);
+ }
+ else if (g_str_equal (tag, "emblem") && g_variant_is_of_type (val, G_VARIANT_TYPE ("(va{sv})")))
+ {
+ GEmblem *emblem;
+
+ emblem = g_icon_deserialize_emblem (val);
+ if (emblem)
+ icon = G_ICON (emblem);
+ }
+ else if (g_str_equal (tag, "emblemed") && g_variant_is_of_type (val, G_VARIANT_TYPE ("(va(va{sv}))")))
+ {
+ icon = g_icon_deserialize_emblemed (val);
+ }
+ else if (g_str_equal (tag, "gvfs"))
+ {
+ GVfsClass *class;
+ GVfs *vfs;
+
+ vfs = g_vfs_get_default ();
+ class = G_VFS_GET_CLASS (vfs);
+ if (class->deserialize_icon)
+ icon = (* class->deserialize_icon) (vfs, val);