mark the GtkTooltips struct as private. Keep the tooltips in a hash table

2007-06-19  Sven Neumann  <sven@gimp.org>

	* gtk/gtktooltips.[ch]: mark the GtkTooltips struct as private.
	Keep the tooltips in a hash table instead of a linked list.
	Improves performance when using large amounts of tooltips (#447214).

	* README.in: document the GtkTooltips changes.

svn path=/trunk/; revision=18188
This commit is contained in:
Sven Neumann
2007-06-19 15:08:11 +00:00
committed by Sven Neumann
parent 60a409785f
commit 5de66ab18d
4 changed files with 80 additions and 53 deletions

View File

@ -1,3 +1,11 @@
2007-06-19 Sven Neumann <sven@gimp.org>
* gtk/gtktooltips.[ch]: mark the GtkTooltips struct as private.
Keep the tooltips in a hash table instead of a linked list.
Improves performance when using large amounts of tooltips (#447214).
* README.in: document the GtkTooltips changes.
2007-06-19 Johan Dahlin <jdahlin@async.com.br> 2007-06-19 Johan Dahlin <jdahlin@async.com.br>
* gtk/*: Rename buildable methods to not clash with widget * gtk/*: Rename buildable methods to not clash with widget

View File

@ -86,6 +86,10 @@ Release notes for 2.12
documented as an abstract class, and there is little reason to documented as an abstract class, and there is little reason to
instantiate it. instantiate it.
* The GtkTooltips struct (this is the old tooltips API) is now considered
private. Code that used to access this struct, in particular the
tips_data_list field, will need to change.
* The memory management of the GtkRecentManager object has been changed, * The memory management of the GtkRecentManager object has been changed,
as using the screen didn't guarantee that the singleton instance was as using the screen didn't guarantee that the singleton instance was
correctly destroyed. The screen-related functions have been deprecated, correctly destroyed. The screen-related functions have been deprecated,

View File

@ -48,9 +48,21 @@
#define STICKY_REVERT_DELAY 1000 /* Delay before sticky tooltips revert #define STICKY_REVERT_DELAY 1000 /* Delay before sticky tooltips revert
* to normal * to normal
*/ */
#define GTK_TOOLTIPS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOLTIPS, GtkTooltipsPrivate))
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_destroy (GtkObject *object);
static void gtk_tooltips_destroy_data (GtkTooltipsData *tooltipsdata);
static void gtk_tooltips_event_handler (GtkWidget *widget, static void gtk_tooltips_event_handler (GtkWidget *widget,
GdkEvent *event); GdkEvent *event);
static void gtk_tooltips_widget_unmap (GtkWidget *widget, static void gtk_tooltips_widget_unmap (GtkWidget *widget,
@ -75,19 +87,24 @@ G_DEFINE_TYPE (GtkTooltips, gtk_tooltips, GTK_TYPE_OBJECT)
static void static void
gtk_tooltips_class_init (GtkTooltipsClass *class) 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; object_class->destroy = gtk_tooltips_destroy;
g_type_class_add_private (gobject_class, sizeof (GtkTooltipsPrivate));
} }
static void static void
gtk_tooltips_init (GtkTooltips *tooltips) gtk_tooltips_init (GtkTooltips *tooltips)
{ {
GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
tooltips->tip_window = NULL; tooltips->tip_window = NULL;
tooltips->active_tips_data = NULL; tooltips->active_tips_data = NULL;
tooltips->tips_data_list = NULL; tooltips->_tips_data_list = NULL;
tooltips->delay = DEFAULT_DELAY; tooltips->delay = DEFAULT_DELAY;
tooltips->enabled = TRUE; tooltips->enabled = TRUE;
@ -95,6 +112,20 @@ gtk_tooltips_init (GtkTooltips *tooltips)
tooltips->use_sticky_delay = FALSE; tooltips->use_sticky_delay = FALSE;
tooltips->last_popdown.tv_sec = -1; tooltips->last_popdown.tv_sec = -1;
tooltips->last_popdown.tv_usec = -1; tooltips->last_popdown.tv_usec = -1;
private->tips_data_table =
g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) gtk_tooltips_destroy_data);
}
static void
gtk_tooltips_finalize (GObject *object)
{
GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (object);
g_hash_table_destroy (private->tips_data_table);
G_OBJECT_CLASS (gtk_tooltips_parent_class)->finalize (object);
} }
GtkTooltips * GtkTooltips *
@ -106,6 +137,8 @@ gtk_tooltips_new (void)
static void static void
gtk_tooltips_destroy_data (GtkTooltipsData *tooltipsdata) gtk_tooltips_destroy_data (GtkTooltipsData *tooltipsdata)
{ {
gtk_tooltips_widget_unmap (tooltipsdata->widget, tooltipsdata);
g_free (tooltipsdata->tip_text); g_free (tooltipsdata->tip_text);
g_free (tooltipsdata->tip_private); g_free (tooltipsdata->tip_private);
@ -156,8 +189,7 @@ static void
gtk_tooltips_destroy (GtkObject *object) gtk_tooltips_destroy (GtkObject *object)
{ {
GtkTooltips *tooltips = GTK_TOOLTIPS (object); GtkTooltips *tooltips = GTK_TOOLTIPS (object);
GList *current; GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
GtkTooltipsData *tooltipsdata;
g_return_if_fail (tooltips != NULL); g_return_if_fail (tooltips != NULL);
@ -167,16 +199,7 @@ gtk_tooltips_destroy (GtkObject *object)
tooltips->timer_tag = 0; tooltips->timer_tag = 0;
} }
if (tooltips->tips_data_list != NULL) g_hash_table_remove_all (private->tips_data_table);
{
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);
}
}
gtk_tooltips_unset_tip_window (tooltips); gtk_tooltips_unset_tip_window (tooltips);
@ -327,8 +350,9 @@ gtk_tooltips_set_tip (GtkTooltips *tooltips,
tooltipsdata->tip_text = g_strdup (tip_text); tooltipsdata->tip_text = g_strdup (tip_text);
tooltipsdata->tip_private = g_strdup (tip_private); tooltipsdata->tip_private = g_strdup (tip_private);
tooltips->tips_data_list = g_list_append (tooltips->tips_data_list, g_hash_table_insert (GTK_TOOLTIPS_GET_PRIVATE (tooltips)->tips_data_table,
tooltipsdata); widget, tooltipsdata);
g_signal_connect_after (widget, "event_after", g_signal_connect_after (widget, "event_after",
G_CALLBACK (gtk_tooltips_event_handler), G_CALLBACK (gtk_tooltips_event_handler),
tooltipsdata); tooltipsdata);
@ -478,23 +502,15 @@ gtk_tooltips_set_active_widget (GtkTooltips *tooltips,
tooltips->active_tips_data = NULL; 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)
{ {
GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
GtkTooltipsData *tooltipsdata; GtkTooltipsData *tooltipsdata;
tooltipsdata = list->data; tooltipsdata = g_hash_table_lookup (private->tips_data_table, widget);
if (tooltipsdata->widget == widget && if (tooltipsdata)
GTK_WIDGET_DRAWABLE (widget))
{
tooltips->active_tips_data = tooltipsdata; tooltips->active_tips_data = tooltipsdata;
break;
}
}
} }
else else
{ {
@ -728,11 +744,9 @@ gtk_tooltips_widget_remove (GtkWidget *widget,
{ {
GtkTooltipsData *tooltipsdata = (GtkTooltipsData*) data; GtkTooltipsData *tooltipsdata = (GtkTooltipsData*) data;
GtkTooltips *tooltips = tooltipsdata->tooltips; GtkTooltips *tooltips = tooltipsdata->tooltips;
GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
gtk_tooltips_widget_unmap (widget, data); g_hash_table_remove (private->tips_data_table, tooltipsdata->widget);
tooltips->tips_data_list = g_list_remove (tooltips->tips_data_list,
tooltipsdata);
gtk_tooltips_destroy_data (tooltipsdata);
} }
void void

View File

@ -57,10 +57,11 @@ struct _GtkTooltips
{ {
GtkObject parent_instance; GtkObject parent_instance;
/*< private >*/
GtkWidget *tip_window; GtkWidget *tip_window;
GtkWidget *tip_label; GtkWidget *tip_label;
GtkTooltipsData *active_tips_data; GtkTooltipsData *active_tips_data;
GList *tips_data_list; GList *_tips_data_list; /* unused */
guint delay : 30; guint delay : 30;
guint enabled : 1; guint enabled : 1;