diff --git a/ChangeLog b/ChangeLog index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 91b66b8067..69b9bf75ad 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,24 @@ +Fri Apr 24 01:29:04 1998 Tim Janik + + * gtk/gtkaccelerator.h (struct _GtkAcceleratorTable): changed ref_count + field to be of type guint. + * gtk/gtkaccelerator.c (gtk_accelerator_table_unref): added check for + ref_count>0; + (gtk_accelerator_table_install): keep a per object list of accelerator + tables that refer to this object. + (gtk_accelerator_table_remove): remove the accelerator table from the + per object list. + (gtk_accelerator_table_clean): warn if there are any object references + left in an accelerator table upon destruction. + (gtk_accelerator_tables_delete): new function to delete object + references from the accelerator tables associated with this object. + + * gtk/gtkwidget.c (gtk_widget_class_init): changed emission of + GtkWidget::install_accelerator to GTK_RUN_LAST so the installation + of an accelerator can be prevented by gtk_signal_emit_stop(). + (gtk_widget_real_destroy): call gtk_accelerator_tables_delete (), + so there are no stale pointers in accelerator tables left. + Wed Apr 22 04:15:26 1998 Tim Janik * gtk/gtkmain.c (gtk_handle_current_timeouts): prepend the diff --git a/gtk/gtkaccelerator.c b/gtk/gtkaccelerator.c index 7b54b18bf7..8e529efd2d 100644 --- a/gtk/gtkaccelerator.c +++ b/gtk/gtkaccelerator.c @@ -39,6 +39,8 @@ static void gtk_accelerator_table_clean (GtkAcceleratorTable *table); static GtkAcceleratorTable *default_table = NULL; static GSList *tables = NULL; static guint8 gtk_accelerator_table_default_mod_mask = (guint8) ~0; +static const gchar *actable_key = "gtk-accelerator-tables"; +static guint actable_key_id = 0; GtkAcceleratorTable* @@ -46,6 +48,9 @@ gtk_accelerator_table_new () { GtkAcceleratorTable *table; + if (!actable_key_id) + actable_key_id = gtk_object_data_force_id (actable_key); + table = g_new (GtkAcceleratorTable, 1); gtk_accelerator_table_init (table); @@ -109,9 +114,10 @@ void gtk_accelerator_table_unref (GtkAcceleratorTable *table) { g_return_if_fail (table != NULL); + g_return_if_fail (table->ref_count > 0); table->ref_count -= 1; - if (table->ref_count <= 0) + if (table->ref_count == 0) { tables = g_slist_remove (tables, table); gtk_accelerator_table_clean (table); @@ -154,6 +160,12 @@ gtk_accelerator_table_install (GtkAcceleratorTable *table, if ((entry->modifiers & table->modifier_mask) == (accelerator_mods & table->modifier_mask)) { + gtk_object_set_data_by_id (entry->object, + actable_key_id, + g_slist_remove (gtk_object_get_data_by_id (entry->object, + actable_key_id), + table)); + if (GTK_IS_WIDGET (entry->object)) { signame = gtk_signal_name (entry->signal_id); @@ -165,6 +177,12 @@ gtk_accelerator_table_install (GtkAcceleratorTable *table, entry->modifiers = accelerator_mods; entry->object = object; entry->signal_id = signal_id; + gtk_object_set_data_by_id (entry->object, + actable_key_id, + g_slist_prepend (gtk_object_get_data_by_id (entry->object, + actable_key_id), + table)); + return; } @@ -175,7 +193,13 @@ gtk_accelerator_table_install (GtkAcceleratorTable *table, entry->modifiers = accelerator_mods; entry->object = object; entry->signal_id = signal_id; - + gtk_object_set_data_by_id (entry->object, + actable_key_id, + g_slist_prepend (gtk_object_get_data_by_id (entry->object, + actable_key_id), + table)); + gtk_accelerator_table_ref (table); + table->entries[hash] = g_list_prepend (table->entries[hash], entry); } @@ -225,7 +249,14 @@ gtk_accelerator_table_remove (GtkAcceleratorTable *table, temp_list->next = NULL; temp_list->prev = NULL; g_list_free (temp_list); - + + gtk_object_set_data_by_id (object, + actable_key_id, + g_slist_remove (gtk_object_get_data_by_id (object, + actable_key_id), + table)); + gtk_accelerator_table_unref (table); + return; } @@ -332,6 +363,9 @@ gtk_accelerator_table_clean (GtkAcceleratorTable *table) for (i = 0; i < 256; i++) { entries = table->entries[i]; + if (entries) + g_warning ("stale object reference in accelerator table (%d)", i); + while (entries) { entry = entries->data; @@ -344,3 +378,48 @@ gtk_accelerator_table_clean (GtkAcceleratorTable *table) table->entries[i] = NULL; } } + +void +gtk_accelerator_tables_delete (GtkObject *object) +{ + GSList *slist; + + g_return_if_fail (object != NULL); + + slist = gtk_object_get_data_by_id (object, actable_key_id); + if (slist) + { + for (; slist; slist = slist->next) + { + GtkAcceleratorTable *table; + guint i; + + table = slist->data; + + for (i = 0; i < 256; i++) + { + GList *entries; + + entries = table->entries[i]; + + while (entries) + { + GtkAcceleratorEntry *entry; + + entry = entries->data; + entries = entries->next; + + if (entry->object == object) + { + table->entries[i] = g_list_remove (table->entries[i], entry); + g_free (entry); + } + } + } + + gtk_accelerator_table_unref (table); + } + + gtk_object_remove_data_by_id (object, actable_key_id); + } +} diff --git a/gtk/gtkaccelerator.h b/gtk/gtkaccelerator.h index bc7ed45e59..1e8b3120a5 100644 --- a/gtk/gtkaccelerator.h +++ b/gtk/gtkaccelerator.h @@ -26,6 +26,7 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ @@ -34,7 +35,7 @@ typedef struct _GtkAcceleratorTable GtkAcceleratorTable; struct _GtkAcceleratorTable { GList *entries[256]; - gint ref_count; + guint ref_count; guint8 modifier_mask; }; @@ -60,6 +61,8 @@ void gtk_accelerator_table_remove (GtkAcceleratorTable *table, gint gtk_accelerator_table_check (GtkAcceleratorTable *table, const guchar accelerator_key, guint8 accelerator_mods); +void gtk_accelerator_tables_delete (GtkObject *object); + void gtk_accelerator_table_set_mod_mask (GtkAcceleratorTable *table, guint8 modifier_mask); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 1a62b9ecb4..0548f90a6a 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -419,7 +419,7 @@ gtk_widget_class_init (GtkWidgetClass *klass) GTK_TYPE_BOXED); widget_signals[INSTALL_ACCELERATOR] = gtk_signal_new ("install_accelerator", - GTK_RUN_FIRST, + GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkWidgetClass, install_accelerator), gtk_widget_marshal_signal_2, @@ -3490,12 +3490,13 @@ gtk_widget_real_destroy (GtkObject *object) gtk_grab_remove (widget); gtk_selection_remove_all (widget); - - saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id); + gtk_accelerator_tables_delete (object); + + saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id); if (saved_style) { gtk_style_unref (saved_style); - gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id); + gtk_object_remove_data_by_id (object, saved_default_style_key_id); } gtk_style_unref (widget->style);