[gnome-control-center] background: Add "added" signal to CcBackgroundXml



commit c2e84e2c8a63a182f730eb277211a3e86061ad5d
Author: Bastien Nocera <hadess hadess net>
Date:   Sat Feb 12 02:37:04 2011 +0000

    background: Add "added" signal to CcBackgroundXml
    
    So that the front-end can load the wallpapers piece-meal, and
    avoid overloading the UI on startup.

 panels/background/cc-background-xml.c |   64 ++++++++++++++++++++++++++++++++-
 panels/background/cc-background-xml.h |   11 +++---
 2 files changed, 69 insertions(+), 6 deletions(-)
---
diff --git a/panels/background/cc-background-xml.c b/panels/background/cc-background-xml.c
index 1292b0c..a3de333 100644
--- a/panels/background/cc-background-xml.c
+++ b/panels/background/cc-background-xml.c
@@ -30,13 +30,26 @@
 #include "cc-background-item.h"
 #include "cc-background-xml.h"
 
+/* The number of items we signal as "added" before
+ * returning to the main loop */
+#define NUM_ITEMS_PER_BATCH 1
+
 struct CcBackgroundXmlPrivate
 {
-  GHashTable *wp_hash;
+  GHashTable  *wp_hash;
+  GAsyncQueue *item_added_queue;
+  guint        item_added_id;
 };
 
 #define CC_BACKGROUND_XML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BACKGROUND_XML, CcBackgroundXmlPrivate))
 
+enum {
+	ADDED,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static void     cc_background_xml_class_init     (CcBackgroundXmlClass *klass);
 static void     cc_background_xml_init           (CcBackgroundXml      *background_item);
 static void     cc_background_xml_finalize       (GObject              *object);
@@ -113,6 +126,37 @@ enum_string_to_value (GType type,
 	return value->value;
 }
 
+static gboolean
+idle_emit (CcBackgroundXml *xml)
+{
+	GObject *item;
+	guint i = NUM_ITEMS_PER_BATCH;
+
+	g_async_queue_lock (xml->priv->item_added_queue);
+
+	while (i > 0 && (item = g_async_queue_try_pop_unlocked (xml->priv->item_added_queue)) != NULL) {
+		g_signal_emit (G_OBJECT (xml), signals[ADDED], 0, item);
+		g_object_unref (item);
+		i--;
+	}
+
+	xml->priv->item_added_id = 0;
+	g_async_queue_unlock (xml->priv->item_added_queue);
+
+	return (g_async_queue_length (xml->priv->item_added_queue) > 0);
+}
+
+static void
+emit_added_in_idle (CcBackgroundXml *xml,
+		    GObject         *object)
+{
+	g_async_queue_lock (xml->priv->item_added_queue);
+	g_async_queue_push_unlocked (xml->priv->item_added_queue, object);
+	if (xml->priv->item_added_id == 0)
+		xml->priv->item_added_id = g_idle_add ((GSourceFunc) idle_emit, xml);
+	g_async_queue_unlock (xml->priv->item_added_queue);
+}
+
 #define NONE "(none)"
 #define UNSET_FLAG(flag) G_STMT_START{ (flags&=~(flag)); }G_STMT_END
 #define SET_FLAG(flag) G_STMT_START{ (flags|=flag); }G_STMT_END
@@ -249,6 +293,7 @@ cc_background_xml_load_xml (CcBackgroundXml *xml,
       g_object_set (G_OBJECT (item), "flags", flags, NULL);
       g_hash_table_insert (xml->priv->wp_hash, id, item);
       /* Don't free ID, we added it to the hash table */
+      emit_added_in_idle (xml, g_object_ref (item));
     }
   }
   xmlFreeDoc (wplist);
@@ -499,6 +544,14 @@ cc_background_xml_finalize (GObject *object)
 		g_hash_table_destroy (xml->priv->wp_hash);
 		xml->priv->wp_hash = NULL;
 	}
+	if (xml->priv->item_added_id != 0) {
+		g_source_remove (xml->priv->item_added_id);
+		xml->priv->item_added_id = 0;
+	}
+	if (xml->priv->item_added_queue) {
+		g_async_queue_unref (xml->priv->item_added_queue);
+		xml->priv->item_added_queue = NULL;
+	}
 }
 
 static void
@@ -508,6 +561,14 @@ cc_background_xml_class_init (CcBackgroundXmlClass *klass)
 
         object_class->finalize = cc_background_xml_finalize;
 
+	signals[ADDED] = g_signal_new ("added",
+				       G_OBJECT_CLASS_TYPE (object_class),
+				       G_SIGNAL_RUN_LAST,
+				       0,
+				       NULL, NULL,
+				       g_cclosure_marshal_VOID__OBJECT,
+				       G_TYPE_NONE, 1, CC_TYPE_BACKGROUND_ITEM);
+
         g_type_class_add_private (klass, sizeof (CcBackgroundXmlPrivate));
 }
 
@@ -519,6 +580,7 @@ cc_background_xml_init (CcBackgroundXml *xml)
 						    g_str_equal,
 						    (GDestroyNotify) g_free,
 						    (GDestroyNotify) g_object_unref);
+	xml->priv->item_added_queue = g_async_queue_new_full ((GDestroyNotify) g_object_unref);
 }
 
 CcBackgroundXml *
diff --git a/panels/background/cc-background-xml.h b/panels/background/cc-background-xml.h
index f302e0d..9f3d206 100644
--- a/panels/background/cc-background-xml.h
+++ b/panels/background/cc-background-xml.h
@@ -38,15 +38,16 @@ typedef struct CcBackgroundXmlPrivate CcBackgroundXmlPrivate;
 
 typedef struct
 {
-  GObjectClass parent_class;
-} CcBackgroundXmlClass;
-
-typedef struct
-{
   GObject parent;
   CcBackgroundXmlPrivate *priv;
 } CcBackgroundXml;
 
+typedef struct
+{
+  GObjectClass parent_class;
+  void (*added) (CcBackgroundXml *xml, GObject *item);
+} CcBackgroundXmlClass;
+
 GType              cc_background_xml_get_type (void);
 
 CcBackgroundXml *cc_background_xml_new (void);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]