GtkMenuItem *
ido_media_player_menu_item_new_from_model (GMenuItem    *menuitem,
                                           GActionGroup *actions)
{
  GtkMenuItem *widget;
  gchar *label;
  gchar *action;
  GVariant *v;

  widget = g_object_new (IDO_TYPE_MEDIA_PLAYER_MENU_ITEM, NULL);

  if (g_menu_item_get_attribute (menuitem, "label", "s", &label))
    {
      ido_media_player_menu_item_set_player_name (IDO_MEDIA_PLAYER_MENU_ITEM (widget), label);
      g_free (label);
    }

  if ((v = g_menu_item_get_attribute_value (menuitem, "icon", NULL)))
    {
      GIcon *icon;

      icon = g_icon_deserialize (v);
      if (icon)
        {
          ido_media_player_menu_item_set_player_icon (IDO_MEDIA_PLAYER_MENU_ITEM (widget), icon);
          g_object_unref (icon);
        }

      g_variant_unref (v);
    }

  if (g_menu_item_get_attribute (menuitem, "action", "s", &action))
    {
      IdoActionHelper *helper;

      helper = ido_action_helper_new (GTK_WIDGET (widget), actions, action, NULL);
      g_signal_connect (helper, "action-state-changed",
                        G_CALLBACK (ido_media_player_menu_item_state_changed), NULL);

      g_signal_connect_object (widget, "activate",
                               G_CALLBACK (ido_action_helper_activate),
                               helper, G_CONNECT_SWAPPED);

      g_signal_connect_swapped (widget, "destroy", G_CALLBACK (g_object_unref), helper);

      g_free (action);
    }

  return widget;
}
GtkMenuItem *
ido_source_menu_item_new_from_menu_model (GMenuItem    *menuitem,
                                          GActionGroup *actions)
{
  GtkMenuItem *item;
  GVariant *serialized_icon;
  GIcon *icon = NULL;
  gchar *label;
  gchar *action = NULL;

  item = g_object_new (IDO_TYPE_SOURCE_MENU_ITEM, NULL);

  if (g_menu_item_get_attribute (menuitem, "label", "s", &label))
    {
      ido_source_menu_item_set_label (IDO_SOURCE_MENU_ITEM (item), label);
      g_free (label);
    }

  serialized_icon = g_menu_item_get_attribute_value (menuitem, "icon", NULL);
  if (serialized_icon)
    {
      icon = g_icon_deserialize (serialized_icon);
      g_variant_unref (serialized_icon);
    }
  ido_source_menu_item_set_icon (IDO_SOURCE_MENU_ITEM (item), icon);

  if (g_menu_item_get_attribute (menuitem, "action", "s", &action))
    {
      IdoActionHelper *helper;

      helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, NULL);
      g_signal_connect (helper, "action-state-changed",
                        G_CALLBACK (ido_source_menu_item_state_changed), item);
      g_signal_connect_object (item, "activate",
                               G_CALLBACK (ido_source_menu_item_activate), helper,
                               0);
      g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper);

      g_free (action);
    }

  if (icon)
    g_object_unref (icon);

  return item;
}
static void
test_serialize (void)
{
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  GdkPixbuf *pixbuf2;
  GVariant *data;
  GIcon *icon;
  GInputStream *stream;

  pixbuf = gdk_pixbuf_new_from_file (g_test_get_filename (G_TEST_DIST, "test-image.png", NULL), &error);
  g_assert_no_error (error);
  g_assert (pixbuf != NULL);

  /* turn it into a GVariant */
  data = g_icon_serialize (G_ICON (pixbuf));

  /* back to a GIcon, but this will be a GBytesIcon, not GdkPixbuf */
  icon = g_icon_deserialize (data);
  g_assert (G_IS_BYTES_ICON (icon));

  /* but since that is a GLoadableIcon, we can load it again */
  stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), 0, NULL, NULL, &error);
  g_assert_no_error (error);
  pixbuf2 = gdk_pixbuf_new_from_stream (stream, NULL, &error);
  g_assert_no_error (error);

  /* make sure that the pixels are the same.
   * our _serialize() uses png, so this should be perfect.
   */
  {
    guchar *pixels_a, *pixels_b;
    guint len_a, len_b;
    pixels_a = gdk_pixbuf_get_pixels_with_length (pixbuf, &len_a);
    pixels_b = gdk_pixbuf_get_pixels_with_length (pixbuf2, &len_b);
    g_assert (len_a == len_b);
    g_assert (memcmp (pixels_a, pixels_b, len_a) == 0);
  }

  g_object_unref (pixbuf2);
  g_object_unref (pixbuf);
  g_object_unref (stream);
  g_variant_unref (data);

}