Index: gtk/gtktooltips.c
===================================================================
--- gtk/gtktooltips.c	(revision 18125)
+++ gtk/gtktooltips.c	(working copy)
@@ -48,8 +48,18 @@
 #define STICKY_REVERT_DELAY 1000    /* Delay before sticky tooltips revert
 				     * to normal
                                      */
+#define GTK_TOOLTIPS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOLTIPS, GtkTooltipsPrivate))
 
-static void gtk_tooltips_destroy           (GtkObject        *object);
+typedef struct _GtkTooltipsPrivate GtkTooltipsPrivate;
+
+struct _GtkTooltipsPrivate
+{
+  GHashTable *tips_data_table;
+};
+
+
+static void gtk_tooltips_finalize          (GObject     *object);
+static void gtk_tooltips_destroy           (GtkObject   *object);
 
 static void gtk_tooltips_event_handler     (GtkWidget   *widget,
                                             GdkEvent    *event);
@@ -75,26 +85,41 @@ G_DEFINE_TYPE (GtkTooltips, gtk_tooltips
 static void
 gtk_tooltips_class_init (GtkTooltipsClass *class)
 {
-  GtkObjectClass *object_class;
+  GtkObjectClass *object_class = (GtkObjectClass *) class;
+  GObjectClass *gobject_class = (GObjectClass *) class;
 
-  object_class = (GtkObjectClass*) class;
+  gobject_class->finalize = gtk_tooltips_finalize;
 
   object_class->destroy = gtk_tooltips_destroy;
+
+  g_type_class_add_private (gobject_class, sizeof (GtkTooltipsPrivate));
 }
 
 static void
 gtk_tooltips_init (GtkTooltips *tooltips)
 {
+  GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
+
   tooltips->tip_window = NULL;
   tooltips->active_tips_data = NULL;
-  tooltips->tips_data_list = NULL;
-  
+  tooltips->tips_data_list = NULL;  /* unused */
+
   tooltips->delay = DEFAULT_DELAY;
   tooltips->enabled = TRUE;
   tooltips->timer_tag = 0;
   tooltips->use_sticky_delay = FALSE;
   tooltips->last_popdown.tv_sec = -1;
   tooltips->last_popdown.tv_usec = -1;
+
+  private->tips_data_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+static void
+gtk_tooltips_finalize (GObject *object)
+{
+  GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (object);
+
+  g_hash_table_destroy (private->tips_data_table);
 }
 
 GtkTooltips *
@@ -153,11 +178,18 @@ gtk_tooltips_unset_tip_window (GtkToolti
 }
 
 static void
+gtk_tooltips_table_destroy_data (GtkWidget       *widget,
+                                 GtkTooltipsData *tooltipsdata)
+{
+  gtk_tooltips_widget_unmap (widget, tooltipsdata);
+  gtk_tooltips_destroy_data (tooltipsdata);
+}
+
+static void
 gtk_tooltips_destroy (GtkObject *object)
 {
   GtkTooltips *tooltips = GTK_TOOLTIPS (object);
-  GList *current;
-  GtkTooltipsData *tooltipsdata;
+  GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
 
   g_return_if_fail (tooltips != NULL);
 
@@ -167,16 +199,9 @@ gtk_tooltips_destroy (GtkObject *object)
       tooltips->timer_tag = 0;
     }
 
-  if (tooltips->tips_data_list != NULL)
-    {
-      current = g_list_first (tooltips->tips_data_list);
-      while (current != NULL)
-	{
-	  tooltipsdata = (GtkTooltipsData*) current->data;
-	  current = current->next;
-	  gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
-	}
-    }
+  g_hash_table_foreach (private->tips_data_table,
+                        (GHFunc) gtk_tooltips_table_destroy_data, NULL);
+  g_hash_table_remove_all (private->tips_data_table);
 
   gtk_tooltips_unset_tip_window (tooltips);
 
@@ -327,8 +352,9 @@ gtk_tooltips_set_tip (GtkTooltips *toolt
       tooltipsdata->tip_text = g_strdup (tip_text);
       tooltipsdata->tip_private = g_strdup (tip_private);
 
-      tooltips->tips_data_list = g_list_append (tooltips->tips_data_list,
-                                                tooltipsdata);
+      g_hash_table_insert (GTK_TOOLTIPS_GET_PRIVATE (tooltips)->tips_data_table,
+                           widget, tooltipsdata);
+
       g_signal_connect_after (widget, "event_after",
                               G_CALLBACK (gtk_tooltips_event_handler),
 			      tooltipsdata);
@@ -478,23 +504,15 @@ gtk_tooltips_set_active_widget (GtkToolt
   
   tooltips->active_tips_data = NULL;
   
-  if (widget)
+  if (widget && GTK_WIDGET_DRAWABLE (widget))
     {
-      GList *list;
-      
-      for (list = tooltips->tips_data_list; list; list = list->next)
-	{
-	  GtkTooltipsData *tooltipsdata;
-	  
-	  tooltipsdata = list->data;
-	  
-	  if (tooltipsdata->widget == widget &&
-	      GTK_WIDGET_DRAWABLE (widget))
-	    {
-	      tooltips->active_tips_data = tooltipsdata;
-	      break;
-	    }
-	}
+      GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
+      GtkTooltipsData    *tooltipsdata;
+
+      tooltipsdata = g_hash_table_lookup (private->tips_data_table, widget);
+
+      if (tooltipsdata)
+        tooltips->active_tips_data = tooltipsdata;
     }
   else
     {
@@ -728,10 +746,12 @@ gtk_tooltips_widget_remove (GtkWidget *w
 {
   GtkTooltipsData *tooltipsdata = (GtkTooltipsData*) data;
   GtkTooltips *tooltips = tooltipsdata->tooltips;
+  GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
 
   gtk_tooltips_widget_unmap (widget, data);
-  tooltips->tips_data_list = g_list_remove (tooltips->tips_data_list,
-					    tooltipsdata);
+
+  g_hash_table_remove (private->tips_data_table, tooltipsdata->widget);
+
   gtk_tooltips_destroy_data (tooltipsdata);
 }
 
