[gnome-shell] [ShellGenericContainer] Simplify tracking of skip-paint children



commit ed365176154e4c446f273fd7f423259428c1a84d
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Feb 2 19:21:30 2010 -0500

    [ShellGenericContainer] Simplify tracking of skip-paint children
    
    The current way we keep track of skip-paint children is more
    difficult than it needs to be, and can lead to subtle bugs.
    (For one, the skip-paint state of a child is remembered
    when it is removed then added back again, which is completely
    unexpected.)
    
    Instead of using weak references to track children, just remove
    items from the skip-paint list by overriding the remove() virtual
    function of the ClutterContainer interface.
    
    The 'skip_paint' hash table is then destroyed in finalize rather than
    dispose since it doesn't hold references to memory any more but just
    passively tracks an attribute of the children that are currently in
    the container.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=608848

 src/shell-generic-container.c |   61 +++++++++++++++++++++++------------------
 1 files changed, 34 insertions(+), 27 deletions(-)
---
diff --git a/src/shell-generic-container.c b/src/shell-generic-container.c
index b6cdeec..90465ab 100644
--- a/src/shell-generic-container.c
+++ b/src/shell-generic-container.c
@@ -102,7 +102,13 @@ function runTestFixedBox() {
 #include <gtk/gtk.h>
 #include <girepository.h>
 
-G_DEFINE_TYPE(ShellGenericContainer, shell_generic_container, CLUTTER_TYPE_GROUP);
+static void shell_generic_container_iface_init (ClutterContainerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(ShellGenericContainer,
+                        shell_generic_container,
+                        CLUTTER_TYPE_GROUP,
+                        G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
+                                               shell_generic_container_iface_init));
 
 struct _ShellGenericContainerPrivate {
   GHashTable *skip_paint;
@@ -119,6 +125,7 @@ enum
 
 static guint shell_generic_container_signals [LAST_SIGNAL] = { 0 };
 
+static ClutterContainerIface *parent_container_iface;
 
 static gpointer
 shell_generic_container_allocation_ref (ShellGenericContainerAllocation *alloc)
@@ -227,15 +234,6 @@ shell_generic_container_pick (ClutterActor        *actor,
   g_list_free (children);
 }
 
-static void
-on_skip_paint_weakref (gpointer  user_data,
-                       GObject  *location)
-{
-  ShellGenericContainer *self = SHELL_GENERIC_CONTAINER (user_data);
-
-  g_hash_table_remove (self->priv->skip_paint, location);
-}
-
 /**
  * shell_generic_container_set_skip_paint:
  * @container: A #ShellGenericContainer
@@ -257,29 +255,19 @@ shell_generic_container_set_skip_paint (ShellGenericContainer  *self,
     return;
 
   if (!skip)
-    {
-      g_object_weak_unref ((GObject*) child, on_skip_paint_weakref, self);
-      g_hash_table_remove (self->priv->skip_paint, child);
-    }
+    g_hash_table_remove (self->priv->skip_paint, child);
   else
-    {
-      g_object_weak_ref ((GObject*) child, on_skip_paint_weakref, self);
-      g_hash_table_insert (self->priv->skip_paint, child, child);
-    }
+    g_hash_table_insert (self->priv->skip_paint, child, child);
 }
 
 static void
-shell_generic_container_dispose (GObject  *object)
+shell_generic_container_finalize (GObject *object)
 {
   ShellGenericContainer *self = (ShellGenericContainer*) object;
 
-  if (self->priv->skip_paint != NULL)
-    {
-      g_hash_table_destroy (self->priv->skip_paint);
-      self->priv->skip_paint = NULL;
-    }
+  g_hash_table_destroy (self->priv->skip_paint);
 
-  G_OBJECT_CLASS (shell_generic_container_parent_class)->dispose (object);
+  G_OBJECT_CLASS (shell_generic_container_parent_class)->finalize (object);
 }
 
 static void
@@ -288,7 +276,7 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 
-  gobject_class->dispose = shell_generic_container_dispose;
+  gobject_class->finalize = shell_generic_container_finalize;
 
   actor_class->get_preferred_width = shell_generic_container_get_preferred_width;
   actor_class->get_preferred_height = shell_generic_container_get_preferred_height;
@@ -327,11 +315,30 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass)
 }
 
 static void
+shell_generic_container_remove (ClutterContainer *container,
+                                     ClutterActor     *actor)
+{
+  ShellGenericContainer *self = SHELL_GENERIC_CONTAINER (container);
+
+  g_hash_table_remove (self->priv->skip_paint, actor);
+
+  parent_container_iface->remove (container, actor);
+}
+
+static void
+shell_generic_container_iface_init (ClutterContainerIface *iface)
+{
+  parent_container_iface = g_type_interface_peek_parent (iface);
+
+  iface->remove = shell_generic_container_remove;
+}
+
+static void
 shell_generic_container_init (ShellGenericContainer *area)
 {
   area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area, SHELL_TYPE_GENERIC_CONTAINER,
                                             ShellGenericContainerPrivate);
-  area->priv->skip_paint = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_object_unref, NULL);
+  area->priv->skip_paint = g_hash_table_new (NULL, NULL);
 }
 
 GType shell_generic_container_allocation_get_type (void)



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