diff options
author | Tim Janik <timj@src.gnome.org> | 1998-01-30 23:47:09 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-01-30 23:47:09 +0000 |
commit | 4af33fa24df69f335f07f43e5904a766c8d8ec97 (patch) | |
tree | ccc23ba16332f44ae45418f6cf9580036c4c76da | |
parent | ee7038f9fddd0213c65474e5d59609107caed7c6 (diff) | |
download | gdk-pixbuf-4af33fa24df69f335f07f43e5904a766c8d8ec97.tar.gz |
hm, initital refcount revolution commit ;)
still some gnits left, but keep working on it ;)
-timj
56 files changed, 2026 insertions, 1657 deletions
diff --git a/REFCOUNTING b/REFCOUNTING index d51d81092..64e43707b 100644 --- a/REFCOUNTING +++ b/REFCOUNTING @@ -7,10 +7,14 @@ functions that follow these conventions: *_new: Create a new structure with a reference count of 1. *_ref: Increase ref count by one. *_unref: Decrease ref count by one. If the count drops to zero, - free the memory. No user visible actions should take place, - like destryoing windows, etc. + run aprropriate finalization code and free the memory. + No user visible actions should take place, like + destryoing windows, etc. -Some structures also provide a *_destroy function. +Some structures also provide a *_destroy function, but it is generally +unrelated to freeing the memory. `Destroying' merely renders an +object `unusable'. But as long as there are references to it, it will +stick around. GdkWindow --------- @@ -28,7 +32,7 @@ ref_count is updated accordingly. You can call gdk_window_destroy more than once on a particular GdkWindow, it will only be destroyed when it hasn't been yet. The -ref_count is *always* decremented, tho. +ref_count is *always* decremented, tho. Be careful. GdkPixmap --------- @@ -86,7 +90,112 @@ There is no gtk_style_destroy function. GtkObject --------- -This one is the most tricky and I'm still meditating over it. +GtkObjects follow the usual ref_counting strategy, but with a twist. + +They are created with a ref_count of 1. GtkObjects are able able to +run finalization code when the ref_count drops to zero but you cannot +register arbitrary signal handlers to run at finalization time. + +There is also the old gtk_object_destroy function and the "destroy" +signal but they are somewhat independent from finalization. Just as +stated at the top of this text, gtk_object_destroy merely renders an +object unusable. When the object is a container widget for example, +it unrealizes that widget, removes all children and disconnects all +signal handlers. The finalization code is different, it would for +example free associated memory for text strings and release the +attached style. + +[This is the biggest change. Every widget must be revised to have a + proper "destroy" function, etc. Such a destroy function must be able + to be called any number of times and generally leave the widget in a + minimal but consistent state. The "finalization" function is new and + should perform last-minute cleanup actions. It can assume that the + "destroy" function has been called as the last function on this + widget. + + Essentially, the old "destroy" function has been split into a + "finalize" plus a "destroy" function.] + +It is not possible to create GtkObjects with a ref_count of 0 (as it +is done now) because the first ref/unref pair will destroy it +unintentionally. + +To be mostly backward compatible with existing practice, a GtkObject +leads a more complicated life than the other reference counted structures. + +When a GtkObject is created, it starts out in a special state called +"floating" (this is the twist). This means that it is alive and has a +reference to it, but the `owner' of this reference is not known. +There are certain `potential owners' that will adopt a floating +GtkObject. For GtkWidgets the most common adopters are the parent +widget. + +When you want to adopt a possibly floating GtkObject, you call +gtk_object_sink on it. This clears the floating state of the +GtkObject and decrements the ref_count by one, if it has been floating +previously. Once the floating state has been cleared, it will never +be set again. + +All widgets that are part of the display are linked into a +parent/child tree. The link from the parent to a child is reflected +in the ref_count of the child, but the link from the child to the +parent is not reflected in the ref_count of the parent. + +Like a GtkObject, a GtkWidget is created with a ref_count of 1 and +initially flagged as `floating'. As soon as it is added as a child to +a parent, the `floating' flag is cleared and never will be set again. +Not even when it is later unparented. The act of clearing the +`floating' flag also decrements the ref_count of the widget by one. + +When the widget is unparented, its underlying GdkWindow is destroyed +(when it has one), it loses its reference from the parent and +naturally the ref_count is decremented. + +It is considered a bug if a widget still has a GdkWindow when it is +being freed. + +Toplevel widgets, which don't have a `natural' parent, are adopted by +a special widget, maybe a GtkDisplay or GtkScreen. This special +parent of all toplevel widgets is never freed. The toplevel widgets +are added to this parent as soon as they are created. [Maybe this +special widget will only exist conceptually because toplevel widgets +are identified by parent == NULL through-out the code.] + +So, the typical career of a GtkWindow and the GtkButton that sits in +it looks like this: + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + // window is created with ref_count == 1. It is not flagged as + // `floating' because it has already been added to the special + // parent of all toplevel widgets. + + button = gtk_button_new_with_label ("Yo!"); + + // button->ref_count == 1 and it is flagged as `floating'. + + gtk_container_add (window, button); + + // button->ref_count still == 1, but it is no longer `floating'. + + gtk_widget_show (button); + gtk_widget_show (window); + + // The widgets get their GdkWindows, nothing significant happens to + // the ref_counts. + +Then, when the user wants to get rid of the window: + + gtk_widget_destroy (window); + + // The GdkWindow of `window' and all its child GdkWindows are + // destroyed. + + // window is removed from its (conceptual) parent and its ref_count + // drops to zero. The destroy code of `window' destroyes `button'. + + // The destriction of the button removes it from its parent, the + // button->ref_count drops to zero and the button is freed, too. - Marius Vollmer <mvo@zagadka.ping.de> @@ -300,6 +300,8 @@ GdkGC* gdk_gc_new (GdkWindow *window); GdkGC* gdk_gc_new_with_values (GdkWindow *window, GdkGCValues *values, GdkGCValuesMask values_mask); +GdkGC* gdk_gc_ref (GdkGC *gc); +void gdk_gc_unref (GdkGC *gc); void gdk_gc_destroy (GdkGC *gc); void gdk_gc_get_values (GdkGC *gc, GdkGCValues *values); diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c index d007fd6e6..7210acd8f 100644 --- a/gdk/gdkgc.c +++ b/gdk/gdkgc.c @@ -50,6 +50,7 @@ gdk_gc_new_with_values (GdkWindow *window, xwindow = window_private->xwindow; private->xdisplay = window_private->xdisplay; + private->ref_count = 1; xvalues.function = GXcopy; xvalues.fill_style = FillSolid; @@ -220,15 +221,35 @@ gdk_gc_new_with_values (GdkWindow *window, void gdk_gc_destroy (GdkGC *gc) { - GdkGCPrivate *private; + gdk_gc_unref (gc); +} - g_return_if_fail (gc != NULL); +GdkGC * +gdk_gc_ref (GdkGC *gc) +{ + GdkGCPrivate *private = (GdkGCPrivate*) gc; - private = (GdkGCPrivate*) gc; - XFreeGC (private->xdisplay, private->xgc); + g_return_val_if_fail (gc != NULL, NULL); + private->ref_count += 1; + + return gc; +} - memset (gc, 0, sizeof (GdkGCPrivate)); - g_free (gc); +void +gdk_gc_unref (GdkGC *gc) +{ + GdkGCPrivate *private = (GdkGCPrivate*) gc; + + g_return_if_fail (gc != NULL); + + if (private->ref_count > 1) + private->ref_count -= 1; + else + { + XFreeGC (private->xdisplay, private->xgc); + memset (gc, 0, sizeof (GdkGCPrivate)); + g_free (gc); + } } void diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index 03b02f81c..55e150563 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -58,8 +58,8 @@ struct _GdkWindowPrivate guint16 width; guint16 height; guint8 resize_count; - guint8 ref_count; guint8 window_type; + guint ref_count; guint destroyed : 2; guint dnd_drag_enabled : 1, dnd_drag_datashow : 1, @@ -104,6 +104,7 @@ struct _GdkGCPrivate GdkGC gc; GC xgc; Display *xdisplay; + guint ref_count; }; struct _GdkColormapPrivate @@ -114,7 +115,7 @@ struct _GdkColormapPrivate GdkVisual *visual; gint private_val; gint next_color; - gint ref_count; + guint ref_count; }; struct _GdkVisualPrivate @@ -130,7 +131,7 @@ struct _GdkFontPrivate /* generic pointer point to XFontStruct or XFontSet */ gpointer xfont; Display *xdisplay; - gint ref_count; + guint ref_count; }; struct _GdkCursorPrivate diff --git a/gtk/gtkadjustment.c b/gtk/gtkadjustment.c index 47d422bc5..eceebdfa6 100644 --- a/gtk/gtkadjustment.c +++ b/gtk/gtkadjustment.c @@ -117,3 +117,15 @@ gtk_adjustment_new (gfloat value, return GTK_OBJECT (adjustment); } + +void +gtk_adjustment_set_value (GtkAdjustment *adjustment, + gfloat value) +{ + g_return_if_fail (adjustment != NULL); + g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); + + adjustment->value = CLAMP (value, adjustment->lower, adjustment->upper); + + gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed"); +} diff --git a/gtk/gtkadjustment.h b/gtk/gtkadjustment.h index 7832d1dd1..b2bb1577b 100644 --- a/gtk/gtkadjustment.h +++ b/gtk/gtkadjustment.h @@ -64,6 +64,10 @@ GtkObject* gtk_adjustment_new (gfloat value, gfloat step_increment, gfloat page_increment, gfloat page_size); +void gtk_adjustment_set_value (GtkAdjustment *adjustment, + gfloat value); + + #ifdef __cplusplus diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c index 3e60b5976..aff8043e4 100644 --- a/gtk/gtkbin.c +++ b/gtk/gtkbin.c @@ -20,7 +20,6 @@ static void gtk_bin_class_init (GtkBinClass *klass); static void gtk_bin_init (GtkBin *bin); -static void gtk_bin_destroy (GtkObject *object); static void gtk_bin_map (GtkWidget *widget); static void gtk_bin_unmap (GtkWidget *widget); static void gtk_bin_draw (GtkWidget *widget, @@ -76,8 +75,6 @@ gtk_bin_class_init (GtkBinClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); - object_class->destroy = gtk_bin_destroy; - widget_class->map = gtk_bin_map; widget_class->unmap = gtk_bin_unmap; widget_class->draw = gtk_bin_draw; @@ -98,27 +95,6 @@ gtk_bin_init (GtkBin *bin) static void -gtk_bin_destroy (GtkObject *object) -{ - GtkBin *bin; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_BIN (object)); - - bin = GTK_BIN (object); - - if (bin->child) - { - bin->child->parent = NULL; - gtk_object_unref (GTK_OBJECT (bin->child)); - gtk_widget_destroy (bin->child); - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_bin_map (GtkWidget *widget) { GtkBin *bin; @@ -261,7 +237,6 @@ gtk_bin_remove (GtkContainer *container, if (bin->child == widget) { gtk_widget_unparent (widget); - bin->child = NULL; if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container)) diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index 4ba393584..ad4c11d65 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -31,7 +31,6 @@ static void gtk_box_get_arg (GtkBox *box, static void gtk_box_set_arg (GtkBox *box, GtkArg *arg, guint arg_id); -static void gtk_box_destroy (GtkObject *object); static void gtk_box_map (GtkWidget *widget); static void gtk_box_unmap (GtkWidget *widget); static void gtk_box_draw (GtkWidget *widget, @@ -90,8 +89,6 @@ gtk_box_class_init (GtkBoxClass *class) gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, ARG_SPACING); gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, ARG_HOMOGENEOUS); - object_class->destroy = gtk_box_destroy; - widget_class->map = gtk_box_map; widget_class->unmap = gtk_box_unmap; widget_class->draw = gtk_box_draw; @@ -419,37 +416,6 @@ gtk_box_set_child_packing (GtkBox *box, } } - -static void -gtk_box_destroy (GtkObject *object) -{ - GtkBox *box; - GtkBoxChild *child; - GList *children; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_BOX (object)); - - box = GTK_BOX (object); - - children = box->children; - while (children) - { - child = children->data; - children = children->next; - - child->widget->parent = NULL; - gtk_object_unref (GTK_OBJECT (child->widget)); - gtk_widget_destroy (child->widget); - g_free (child); - } - - g_list_free (box->children); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - static void gtk_box_map (GtkWidget *widget) { diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index 75633764a..a9ed0d7f6 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -48,7 +48,6 @@ static void gtk_button_init (GtkButton *button); static void gtk_button_set_arg (GtkButton *button, GtkArg *arg, guint arg_id); -static void gtk_button_destroy (GtkObject *object); static void gtk_button_map (GtkWidget *widget); static void gtk_button_unmap (GtkWidget *widget); static void gtk_button_realize (GtkWidget *widget); @@ -170,8 +169,6 @@ gtk_button_class_init (GtkButtonClass *klass) gtk_object_class_add_signals (object_class, button_signals, LAST_SIGNAL); - object_class->destroy = gtk_button_destroy; - widget_class->activate_signal = button_signals[CLICKED]; widget_class->map = gtk_button_map; widget_class->unmap = gtk_button_unmap; @@ -223,7 +220,10 @@ gtk_button_set_arg (GtkButton *button, gtk_container_disable_resize (GTK_CONTAINER (button)); if (button->child) - gtk_widget_destroy (button->child); + { + gtk_widget_unparent (button->child); + button->child = NULL; + } label = gtk_label_new (GTK_VALUE_STRING(*arg)); gtk_widget_show (label); @@ -290,27 +290,6 @@ gtk_button_leave (GtkButton *button) } static void -gtk_button_destroy (GtkObject *object) -{ - GtkButton *button; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_BUTTON (object)); - - button = GTK_BUTTON (object); - - if (button->child) - { - button->child->parent = NULL; - gtk_object_unref (GTK_OBJECT (button->child)); - gtk_widget_destroy (button->child); - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_button_map (GtkWidget *widget) { GtkButton *button; diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index f78f1b580..188ad4483 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -109,7 +109,7 @@ static void gtk_color_selection_rgb_updater (GtkWidget *widget, static void gtk_color_selection_opacity_updater (GtkWidget *widget, gpointer data); static void gtk_color_selection_realize (GtkWidget *widget); -static void gtk_color_selection_destroy (GtkObject *object); +static void gtk_color_selection_finalize (GtkObject *object); static void gtk_color_selection_color_changed (GtkColorSelection *colorsel); static void gtk_color_selection_update_input (GtkWidget *scale, GtkWidget *entry, @@ -159,8 +159,6 @@ static void gtk_color_selection_hsv_to_rgb (gdouble h, gdouble s, gdoub static void gtk_color_selection_rgb_to_hsv (gdouble r, gdouble g, gdouble b, gdouble *h, gdouble *s, gdouble *v); -static void gtk_color_selection_dialog_destroy (GtkObject *object); - static GtkVBoxClass *color_selection_parent_class = NULL; static GtkWindowClass *color_selection_dialog_parent_class = NULL; @@ -229,7 +227,7 @@ gtk_color_selection_class_init (GtkColorSelectionClass *klass) gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL); - object_class->destroy = gtk_color_selection_destroy; + object_class->finalize = gtk_color_selection_finalize; widget_class->realize = gtk_color_selection_realize; } @@ -515,7 +513,7 @@ gtk_color_selection_realize (GtkWidget *widget) } static void -gtk_color_selection_destroy (GtkObject *object) +gtk_color_selection_finalize (GtkObject *object) { GtkColorSelection *colorsel; @@ -531,8 +529,7 @@ gtk_color_selection_destroy (GtkObject *object) if (colorsel->sample_buf != NULL) g_free (colorsel->sample_buf); - if (GTK_OBJECT_CLASS (color_selection_parent_class)->destroy) - (*GTK_OBJECT_CLASS (color_selection_parent_class)->destroy) (object); + (*GTK_OBJECT_CLASS (color_selection_parent_class)->finalize) (object); } static void @@ -1423,8 +1420,6 @@ gtk_color_selection_dialog_class_init (GtkColorSelectionDialogClass *klass) object_class = (GtkObjectClass*) klass; color_selection_dialog_parent_class = gtk_type_class (gtk_window_get_type ()); - - object_class->destroy = gtk_color_selection_dialog_destroy; } static void @@ -1477,18 +1472,3 @@ gtk_color_selection_dialog_new (const gchar *title) return GTK_WIDGET (colorseldiag); } - -static void -gtk_color_selection_dialog_destroy (GtkObject *object) -{ - GtkColorSelectionDialog *colorseldiag; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_COLOR_SELECTION_DIALOG (object)); - - colorseldiag = GTK_COLOR_SELECTION_DIALOG (object); - - - if (GTK_OBJECT_CLASS (color_selection_dialog_parent_class)->destroy) - (*GTK_OBJECT_CLASS (color_selection_dialog_parent_class)->destroy) (object); -} diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index eff9781c7..ba7cc8152 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -71,6 +71,7 @@ static void gtk_container_marshal_signal_4 (GtkObject *object, static void gtk_container_class_init (GtkContainerClass *klass); static void gtk_container_init (GtkContainer *container); +static void gtk_container_destroy (GtkObject *object); static void gtk_container_get_arg (GtkContainer *container, GtkArg *arg, guint arg_id); @@ -101,6 +102,7 @@ static void gtk_container_hide_all (GtkWidget *widget); static gint container_signals[LAST_SIGNAL] = { 0 }; +static GtkWidgetClass *parent_class = NULL; guint gtk_container_get_type () @@ -134,7 +136,8 @@ gtk_container_class_init (GtkContainerClass *class) object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; - + parent_class = gtk_type_class (gtk_widget_get_type ()); + gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_LONG, ARG_BORDER_WIDTH); gtk_object_add_arg_type ("GtkContainer::auto_resize", GTK_TYPE_BOOL, ARG_AUTO_RESIZE); gtk_object_add_arg_type ("GtkContainer::block_resize", GTK_TYPE_BOOL, ARG_BLOCK_RESIZE); @@ -182,10 +185,12 @@ gtk_container_class_init (GtkContainerClass *class) GTK_TYPE_DIRECTION_TYPE); gtk_object_class_add_signals (object_class, container_signals, LAST_SIGNAL); - + + object_class->destroy = gtk_container_destroy; + /* Other container classes should overwrite show_all and hide_all, - unless they make all their children accessable - through gtk_container_foreach. + * for the purpose of showing internal children also, which are not + * accessable through gtk_container_foreach. */ widget_class->show_all = gtk_container_show_all; widget_class->hide_all = gtk_container_hide_all; @@ -202,6 +207,29 @@ gtk_container_init (GtkContainer *container) container->auto_resize = TRUE; container->need_resize = FALSE; container->block_resize = FALSE; + container->resize_widgets = NULL; +} + +static void +gtk_container_destroy (GtkObject *object) +{ + GSList *node; + + for (node = GTK_CONTAINER (object)->resize_widgets; node; node = node->next) + { + GtkWidget *child; + + child = (GtkWidget*) node->data; + GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED); + } + g_slist_free (GTK_CONTAINER (object)->resize_widgets); + GTK_CONTAINER (object)->resize_widgets = NULL; + + gtk_container_foreach (GTK_CONTAINER (object), + (GtkCallback) gtk_widget_destroy, NULL); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void @@ -330,7 +358,7 @@ gtk_container_unblock_resize (GtkContainer *container) { g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); - + container->block_resize = FALSE; } @@ -338,12 +366,12 @@ gint gtk_container_need_resize (GtkContainer *container) { gint return_val; - + g_return_val_if_fail (container != NULL, FALSE); g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE); - + return_val = FALSE; - + if (!container->block_resize) { if (container->auto_resize) @@ -353,7 +381,7 @@ gtk_container_need_resize (GtkContainer *container) else container->need_resize = TRUE; } - + return return_val; } @@ -367,12 +395,56 @@ gtk_container_foreach (GtkContainer *container, callback, callback_data); } +typedef struct _GtkForeachData GtkForeachData; +struct _GtkForeachData +{ + GtkObject *container; + GtkCallbackMarshal callback; + gpointer callback_data; +}; + +static void +gtk_container_foreach_unmarshal (GtkWidget *child, + gpointer data) +{ + GtkForeachData *fdata = (GtkForeachData*) data; + GtkArg args[2]; + + /* first argument */ + args[0].name = NULL; + args[0].type = GTK_OBJECT(child)->klass->type; + GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT (child); + + /* location for return value */ + args[1].name = NULL; + args[1].type = GTK_TYPE_NONE; + + fdata->callback (fdata->container, fdata->callback_data, 1, args); +} + +void +gtk_container_foreach_interp (GtkContainer *container, + GtkCallbackMarshal callback, + gpointer callback_data, + GtkDestroyNotify notify) +{ + GtkForeachData fdata; + + fdata.container = GTK_OBJECT (container); + fdata.callback = callback; + fdata.callback_data = callback_data; + + gtk_container_foreach (container, gtk_container_foreach_unmarshal, &fdata); + + notify (callback_data); +} + gint gtk_container_focus (GtkContainer *container, GtkDirectionType direction) { gint return_val; - + gtk_signal_emit (GTK_OBJECT (container), container_signals[FOCUS], direction, &return_val); diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h index 80c1ce033..bcb43aec1 100644 --- a/gtk/gtkcontainer.h +++ b/gtk/gtkcontainer.h @@ -47,6 +47,11 @@ struct _GtkContainer guint auto_resize : 1; guint need_resize : 1; guint block_resize : 1; + + + /* The list of children that requested a resize + */ + GSList *resize_widgets; }; struct _GtkContainerClass @@ -82,6 +87,10 @@ gint gtk_container_need_resize (GtkContainer *container); void gtk_container_foreach (GtkContainer *container, GtkCallback callback, gpointer callback_data); +void gtk_container_foreach_interp (GtkContainer *container, + GtkCallbackMarshal callback, + gpointer callback_data, + GtkDestroyNotify notify); gint gtk_container_focus (GtkContainer *container, GtkDirectionType direction); GList* gtk_container_children (GtkContainer *container); diff --git a/gtk/gtkcurve.c b/gtk/gtkcurve.c index a606dbd80..3e1d74207 100644 --- a/gtk/gtkcurve.c +++ b/gtk/gtkcurve.c @@ -45,7 +45,7 @@ static gint curve_type_changed_signal = 0; /* forward declarations: */ static void gtk_curve_class_init (GtkCurveClass *class); static void gtk_curve_init (GtkCurve *curve); -static void gtk_curve_destroy (GtkObject *object); +static void gtk_curve_finalize (GtkObject *object); guint @@ -86,7 +86,7 @@ gtk_curve_class_init (GtkCurveClass *class) gtk_signal_default_marshaller, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, &curve_type_changed_signal, 1); - object_class->destroy = gtk_curve_destroy; + object_class->finalize = gtk_curve_finalize; } static void @@ -842,7 +842,7 @@ gtk_curve_new (void) } static void -gtk_curve_destroy (GtkObject *object) +gtk_curve_finalize (GtkObject *object) { GtkCurve *curve; @@ -857,6 +857,5 @@ gtk_curve_destroy (GtkObject *object) if (curve->ctlpoint) g_free (curve->ctlpoint); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (*GTK_OBJECT_CLASS (parent_class)->finalize) (object); } diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index dca61fc1a..6eddcde60 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -64,7 +64,7 @@ static void gtk_entry_marshal_signal_2 (GtkObject *object, static void gtk_entry_class_init (GtkEntryClass *klass); static void gtk_entry_init (GtkEntry *entry); -static void gtk_entry_destroy (GtkObject *object); +static void gtk_entry_finalize (GtkObject *object); static void gtk_entry_realize (GtkWidget *widget); static void gtk_entry_unrealize (GtkWidget *widget); static void gtk_entry_draw_focus (GtkWidget *widget); @@ -289,7 +289,7 @@ gtk_entry_class_init (GtkEntryClass *class) gtk_object_class_add_signals (object_class, entry_signals, LAST_SIGNAL); - object_class->destroy = gtk_entry_destroy; + object_class->finalize = gtk_entry_finalize; widget_class->realize = gtk_entry_realize; widget_class->unrealize = gtk_entry_unrealize; @@ -521,7 +521,7 @@ gtk_entry_marshal_signal_2 (GtkObject *object, } static void -gtk_entry_destroy (GtkObject *object) +gtk_entry_finalize (GtkObject *object) { GtkEntry *entry; @@ -548,8 +548,7 @@ gtk_entry_destroy (GtkObject *object) if (entry->backing_pixmap) gdk_pixmap_unref (entry->backing_pixmap); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void @@ -682,7 +681,7 @@ gtk_entry_unrealize (GtkWidget *widget) g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); - GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); entry = GTK_ENTRY (widget); gtk_style_detach (widget->style); diff --git a/gtk/gtkfixed.c b/gtk/gtkfixed.c index b17404795..2a1b35e2f 100644 --- a/gtk/gtkfixed.c +++ b/gtk/gtkfixed.c @@ -20,7 +20,6 @@ static void gtk_fixed_class_init (GtkFixedClass *klass); static void gtk_fixed_init (GtkFixed *fixed); -static void gtk_fixed_destroy (GtkObject *object); static void gtk_fixed_map (GtkWidget *widget); static void gtk_fixed_unmap (GtkWidget *widget); static void gtk_fixed_realize (GtkWidget *widget); @@ -84,8 +83,6 @@ gtk_fixed_class_init (GtkFixedClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); - object_class->destroy = gtk_fixed_destroy; - widget_class->map = gtk_fixed_map; widget_class->unmap = gtk_fixed_unmap; widget_class->realize = gtk_fixed_realize; @@ -182,36 +179,6 @@ gtk_fixed_move (GtkFixed *fixed, } static void -gtk_fixed_destroy (GtkObject *object) -{ - GtkFixed *fixed; - GtkFixedChild *child; - GList *children; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_FIXED (object)); - - fixed = GTK_FIXED (object); - - children = fixed->children; - while (children) - { - child = children->data; - children = children->next; - - child->widget->parent = NULL; - gtk_object_unref (GTK_OBJECT (child->widget)); - gtk_widget_destroy (child->widget); - g_free (child); - } - - g_list_free (fixed->children); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_fixed_map (GtkWidget *widget) { GtkFixed *fixed; @@ -288,6 +255,7 @@ gtk_fixed_unrealize (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); gtk_style_detach (widget->style); + gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); widget->window = NULL; } diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c index 04c622d70..5fc6aaea6 100644 --- a/gtk/gtkframe.c +++ b/gtk/gtkframe.c @@ -35,7 +35,7 @@ static void gtk_frame_set_arg (GtkFrame *frame, static void gtk_frame_get_arg (GtkFrame *frame, GtkArg *arg, guint arg_id); -static void gtk_frame_destroy (GtkObject *object); +static void gtk_frame_finalize (GtkObject *object); static void gtk_frame_paint (GtkWidget *widget, GdkRectangle *area); static void gtk_frame_draw (GtkWidget *widget, @@ -91,7 +91,7 @@ gtk_frame_class_init (GtkFrameClass *class) gtk_object_add_arg_type ("GtkFrame::label_yalign", GTK_TYPE_DOUBLE, ARG_LABEL_YALIGN); gtk_object_add_arg_type ("GtkFrame::shadow", GTK_TYPE_ENUM, ARG_SHADOW); - object_class->destroy = gtk_frame_destroy; + object_class->finalize = gtk_frame_finalize; widget_class->draw = gtk_frame_draw; widget_class->expose_event = gtk_frame_expose; @@ -279,7 +279,7 @@ gtk_frame_set_shadow_type (GtkFrame *frame, static void -gtk_frame_destroy (GtkObject *object) +gtk_frame_finalize (GtkObject *object) { GtkFrame *frame; @@ -291,8 +291,7 @@ gtk_frame_destroy (GtkObject *object) if (frame->label) g_free (frame->label); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void diff --git a/gtk/gtkgamma.c b/gtk/gtkgamma.c index 5812ec858..9d88de54e 100644 --- a/gtk/gtkgamma.c +++ b/gtk/gtkgamma.c @@ -455,10 +455,7 @@ gtk_gamma_curve_destroy (GtkObject *object) c = GTK_GAMMA_CURVE (object); if (c->gamma_dialog) - { - gtk_widget_destroy (c->gamma_dialog); - c->gamma_dialog = 0; - } + gtk_widget_destroy (c->gamma_dialog); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); diff --git a/gtk/gtkinputdialog.c b/gtk/gtkinputdialog.c index 709eb00c3..380f82c83 100644 --- a/gtk/gtkinputdialog.c +++ b/gtk/gtkinputdialog.c @@ -78,7 +78,7 @@ static void gtk_input_dialog_class_init (GtkInputDialogClass *klass); static void gtk_input_dialog_init (GtkInputDialog *inputd); static GdkDeviceInfo *gtk_input_dialog_get_device_info(guint32 deviceid); static void gtk_input_dialog_set_device(GtkWidget *widget, gpointer data); -static void gtk_input_dialog_destroy (GtkObject *object); +static void gtk_input_dialog_finalize (GtkObject *object); static void gtk_input_dialog_set_mapping_mode(GtkWidget *w, gpointer data); static void gtk_input_dialog_set_axis(GtkWidget *widget, gpointer data); @@ -180,7 +180,7 @@ gtk_input_dialog_class_init (GtkInputDialogClass *klass) LAST_SIGNAL); - object_class->destroy = gtk_input_dialog_destroy; + object_class->finalize = gtk_input_dialog_finalize; klass->enable_device = NULL; klass->disable_device = NULL; } @@ -401,14 +401,13 @@ gtk_input_dialog_set_device(GtkWidget *widget, gpointer data) } static void -gtk_input_dialog_destroy (GtkObject *object) +gtk_input_dialog_finalize (GtkObject *object) { /* GtkInputDialog *inputd = GTK_INPUT_DIALOG (object); */ /* Clean up ? */ - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index b09e2beb6..c9ccce5cb 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -33,7 +33,7 @@ static void gtk_label_set_arg (GtkLabel *label, static void gtk_label_get_arg (GtkLabel *label, GtkArg *arg, guint arg_id); -static void gtk_label_destroy (GtkObject *object); +static void gtk_label_finalize (GtkObject *object); static void gtk_label_size_request (GtkWidget *widget, GtkRequisition *requisition); static gint gtk_label_expose (GtkWidget *widget, @@ -81,15 +81,16 @@ gtk_label_class_init (GtkLabelClass *class) gtk_object_add_arg_type ("GtkLabel::label", GTK_TYPE_STRING, ARG_LABEL); gtk_object_add_arg_type ("GtkLabel::justify", GTK_TYPE_ENUM, ARG_JUSTIFY); - object_class->destroy = gtk_label_destroy; + object_class->finalize = gtk_label_finalize; widget_class->size_request = gtk_label_size_request; widget_class->expose_event = gtk_label_expose; } -static void gtk_label_set_arg (GtkLabel *label, - GtkArg *arg, - guint arg_id) +static void +gtk_label_set_arg (GtkLabel *label, + GtkArg *arg, + guint arg_id) { switch (arg_id) { @@ -219,24 +220,19 @@ gtk_label_get (GtkLabel *label, static void -gtk_label_destroy (GtkObject *object) +gtk_label_finalize (GtkObject *object) { GtkLabel *label; - + g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_LABEL (object)); - + label = GTK_LABEL (object); - - if (GTK_WIDGET (object)->parent && - GTK_WIDGET_MAPPED (object)) - gtk_widget_unmap (GTK_WIDGET (object)); - + g_free (label->label); g_slist_free (label->row); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void diff --git a/gtk/gtklist.c b/gtk/gtklist.c index b93aca511..b5c63a20c 100644 --- a/gtk/gtklist.c +++ b/gtk/gtklist.c @@ -181,6 +181,40 @@ gtk_list_new () return GTK_WIDGET (gtk_type_new (gtk_list_get_type ())); } +static void +gtk_list_destroy (GtkObject *object) +{ + GList *node; + + GtkList *list = GTK_LIST (object); + + for (node = list->children; node; node = node->next) + { + GtkWidget *child; + + child = (GtkWidget *)node->data; + gtk_widget_ref (child); + gtk_widget_unparent (child); + gtk_widget_destroy (child); + gtk_widget_unref (child); + } + g_list_free (list->children); + list->children = NULL; + + for (node = list->selection; node; node = node->next) + { + GtkWidget *child; + + child = (GtkWidget *)node->data; + gtk_widget_unref (child); + } + g_list_free (list->selection); + list->selection = NULL; + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + void gtk_list_insert_items (GtkList *list, GList *items, @@ -387,12 +421,13 @@ gtk_list_clear_items (GtkList *list, { selection_changed = TRUE; list->selection = g_list_remove (list->selection, widget); + gtk_widget_unref (widget); } /* list->children = g_list_remove (list->children, widget); */ /* gtk_widget_unparent (widget); */ - gtk_widget_destroy (widget); + gtk_widget_unparent (widget); } if (list->children && !list->selection && @@ -489,36 +524,6 @@ gtk_list_set_selection_mode (GtkList *list, static void -gtk_list_destroy (GtkObject *object) -{ - GtkList *list; - GtkWidget *child; - GList *children; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_LIST (object)); - - list = GTK_LIST (object); - - children = list->children; - while (children) - { - child = children->data; - children = children->next; - - child->parent = NULL; - gtk_object_unref (GTK_OBJECT (child)); - gtk_widget_destroy (child); - } - - g_list_free (list->children); - g_list_free (list->selection); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_list_map (GtkWidget *widget) { GtkList *list; @@ -674,7 +679,10 @@ gtk_list_button_press (GtkWidget *widget, list = GTK_LIST (widget); item = gtk_get_event_widget ((GdkEvent*) event); - + + if (!item) + return FALSE; + while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_list_item_get_type ())) item = item->parent; @@ -811,9 +819,7 @@ gtk_list_add (GtkContainer *container, list->children = g_list_append (list->children, widget); if (!list->selection && (list->selection_mode == GTK_SELECTION_BROWSE)) - { - gtk_list_select_child (list, widget); - } + gtk_list_select_child (list, widget); if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container)) gtk_widget_queue_resize (widget); @@ -890,11 +896,12 @@ gtk_real_list_select_child (GtkList *list, if (tmp_item != child) { gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item)); - + tmp_list = selection; selection = selection->next; list->selection = g_list_remove_link (list->selection, tmp_list); + gtk_widget_unref (GTK_WIDGET (tmp_item)); g_list_free (tmp_list); } @@ -906,11 +913,13 @@ gtk_real_list_select_child (GtkList *list, { gtk_list_item_select (GTK_LIST_ITEM (child)); list->selection = g_list_prepend (list->selection, child); + gtk_widget_ref (child); } else if (child->state == GTK_STATE_SELECTED) { gtk_list_item_deselect (GTK_LIST_ITEM (child)); list->selection = g_list_remove (list->selection, child); + gtk_widget_unref (child); } gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); @@ -926,11 +935,12 @@ gtk_real_list_select_child (GtkList *list, if (tmp_item != child) { gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item)); - + tmp_list = selection; selection = selection->next; list->selection = g_list_remove_link (list->selection, tmp_list); + gtk_widget_unref (GTK_WIDGET (tmp_item)); g_list_free (tmp_list); } @@ -942,6 +952,7 @@ gtk_real_list_select_child (GtkList *list, { gtk_list_item_select (GTK_LIST_ITEM (child)); list->selection = g_list_prepend (list->selection, child); + gtk_widget_ref (child); gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); } break; @@ -951,12 +962,14 @@ gtk_real_list_select_child (GtkList *list, { gtk_list_item_select (GTK_LIST_ITEM (child)); list->selection = g_list_prepend (list->selection, child); + gtk_widget_ref (child); gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); } else if (child->state == GTK_STATE_SELECTED) { gtk_list_item_deselect (GTK_LIST_ITEM (child)); list->selection = g_list_remove (list->selection, child); + gtk_widget_unref (child); gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); } break; @@ -984,6 +997,7 @@ gtk_real_list_unselect_child (GtkList *list, { gtk_list_item_deselect (GTK_LIST_ITEM (child)); list->selection = g_list_remove (list->selection, child); + gtk_widget_unref (child); gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); } break; diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 07ec23b51..646834d82 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -368,21 +368,17 @@ gtk_main_iteration_do (gboolean blocking) break; case GDK_DELETE: - gtk_object_ref (GTK_OBJECT (event_widget)); + gtk_widget_ref (event_widget); if (gtk_widget_event (event_widget, event)) - { - gtk_object_unref (GTK_OBJECT (event_widget)); - gtk_widget_destroy (event_widget); - } - else - gtk_object_unref (GTK_OBJECT (event_widget)); + gtk_widget_destroy (event_widget); + gtk_widget_unref (event_widget); break; case GDK_DESTROY: - gtk_object_ref (GTK_OBJECT (event_widget)); + gtk_widget_ref (event_widget); gtk_widget_event (event_widget, event); - gtk_object_unref (GTK_OBJECT (event_widget)); gtk_widget_destroy (event_widget); + gtk_widget_unref (event_widget); break; case GDK_PROPERTY_NOTIFY: @@ -494,11 +490,12 @@ gtk_grab_add (GtkWidget *widget) { g_return_if_fail (widget != NULL); - if (!GTK_WIDGET_HAS_GRAB (widget) && !GTK_OBJECT_NEED_DESTROY (widget)) + if (!GTK_WIDGET_HAS_GRAB (widget)) { GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_GRAB); - + grabs = g_slist_prepend (grabs, widget); + gtk_widget_ref (widget); } } @@ -512,6 +509,7 @@ gtk_grab_remove (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_GRAB); grabs = g_slist_remove (grabs, widget); + gtk_widget_unref (widget); } } @@ -885,7 +883,10 @@ GtkWidget* gtk_get_event_widget (GdkEvent *event) { GtkWidget *widget; - gdk_window_get_user_data (event->any.window, (void**) &widget); + + widget = NULL; + if (event->any.window) + gdk_window_get_user_data (event->any.window, (void**) &widget); return widget; } @@ -1117,8 +1118,6 @@ gtk_propagate_event (GtkWidget *widget, { GtkWidget *parent; gint handled_event; - gint parent_old_value; - gint old_value; g_return_if_fail (widget != NULL); g_return_if_fail (event != NULL); @@ -1134,62 +1133,21 @@ gtk_propagate_event (GtkWidget *widget, * for that window. */ parent = gtk_widget_get_ancestor (widget, gtk_window_get_type ()); - if (parent && GTK_WIDGET_IS_SENSITIVE (parent)) - { - parent_old_value = GTK_OBJECT_IN_CALL (parent); - GTK_OBJECT_SET_FLAGS (parent, GTK_IN_CALL); - - handled_event = gtk_widget_event (parent, event); - - if (!parent_old_value) - GTK_OBJECT_UNSET_FLAGS (parent, GTK_IN_CALL); - - if (GTK_OBJECT_NEED_DESTROY (parent) && !GTK_OBJECT_IN_CALL (parent)) - { - gtk_object_destroy (GTK_OBJECT (parent)); - return; - } - } + if (parent && GTK_WIDGET_IS_SENSITIVE (parent) + && gtk_widget_event (parent, event)) + return; } - if (!handled_event) + /* Other events get propagated up the widget tree + * so that parents can see the button and motion + * events of the children. + */ + while (!handled_event && widget) { - old_value = GTK_OBJECT_IN_CALL (widget); - GTK_OBJECT_SET_FLAGS (widget, GTK_IN_CALL); - - /* Other events get propagated up the widget tree - * so that parents can see the button and motion - * events of the children. - */ - parent = widget; - while (parent) - { - parent_old_value = GTK_OBJECT_IN_CALL (parent); - GTK_OBJECT_SET_FLAGS (parent, GTK_IN_CALL); - - handled_event = (!GTK_WIDGET_IS_SENSITIVE (parent) || - gtk_widget_event (parent, event)); - - if (!parent_old_value) - GTK_OBJECT_UNSET_FLAGS (parent, GTK_IN_CALL); - - if (handled_event) - break; - - if (GTK_OBJECT_NEED_DESTROY (parent) && !GTK_OBJECT_IN_CALL (parent)) - { - gtk_object_destroy (GTK_OBJECT (parent)); - break; - } - - parent = parent->parent; - } - - if (!old_value) - GTK_OBJECT_UNSET_FLAGS (widget, GTK_IN_CALL); - - if (GTK_OBJECT_NEED_DESTROY (widget) && !GTK_OBJECT_IN_CALL (widget)) - gtk_object_destroy (GTK_OBJECT (widget)); + parent = widget->parent; + handled_event = (!GTK_WIDGET_IS_SENSITIVE (widget) || + gtk_widget_event (widget, event)); + widget = parent; } } diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 8a83154ca..ea1b273af 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -108,15 +108,18 @@ gtk_menu_class_init (GtkMenuClass *class) static void gtk_menu_init (GtkMenu *menu) { - GTK_WIDGET_SET_FLAGS (menu, GTK_ANCHORED); + GTK_WIDGET_SET_FLAGS (menu, GTK_ANCHORED | GTK_TOPLEVEL); menu->parent_menu_item = NULL; menu->old_active_menu_item = NULL; menu->accelerator_table = NULL; menu->position_func = NULL; menu->position_func_data = NULL; - + GTK_MENU_SHELL (menu)->menu_flag = TRUE; + + /* gtk_container_add (gtk_root, GTK_WIDGET (menu)); */ + gtk_widget_set_parent (GTK_WIDGET (menu), NULL); } GtkWidget* diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index d48693968..8ead19f50 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -197,8 +197,9 @@ gtk_menu_item_destroy (GtkObject *object) if (menu_item->submenu) { - gtk_object_unref (GTK_OBJECT (menu_item->submenu)); - /* gtk_widget_destroy (menu_item->submenu); */ + gtk_widget_destroy (menu_item->submenu); + gtk_widget_unref (menu_item->submenu); + menu_item->submenu = NULL; } if (GTK_OBJECT_CLASS (parent_class)->destroy) @@ -217,11 +218,11 @@ gtk_menu_item_set_submenu (GtkMenuItem *menu_item, if (menu_item->submenu) { g_return_if_fail (!GTK_WIDGET_VISIBLE (menu_item->submenu)); - gtk_object_unref (GTK_OBJECT (menu_item->submenu)); + gtk_widget_unref (menu_item->submenu); } menu_item->submenu = submenu; if (menu_item->submenu) - gtk_object_ref (GTK_OBJECT (menu_item->submenu)); + gtk_widget_ref (menu_item->submenu); if (GTK_WIDGET (menu_item)->parent) gtk_widget_queue_resize (GTK_WIDGET (menu_item)); diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index cee765271..4c45ca759 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -33,7 +33,6 @@ enum { static void gtk_menu_shell_class_init (GtkMenuShellClass *klass); static void gtk_menu_shell_init (GtkMenuShell *menu_shell); -static void gtk_menu_shell_destroy (GtkObject *object); static void gtk_menu_shell_map (GtkWidget *widget); static void gtk_menu_shell_realize (GtkWidget *widget); static gint gtk_menu_shell_button_press (GtkWidget *widget, @@ -107,8 +106,6 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) gtk_object_class_add_signals (object_class, menu_shell_signals, LAST_SIGNAL); - object_class->destroy = gtk_menu_shell_destroy; - widget_class->map = gtk_menu_shell_map; widget_class->realize = gtk_menu_shell_realize; widget_class->button_press_event = gtk_menu_shell_button_press; @@ -218,35 +215,6 @@ gtk_menu_shell_deactivate (GtkMenuShell *menu_shell) } static void -gtk_menu_shell_destroy (GtkObject *object) -{ - GtkMenuShell *menu_shell; - GtkWidget *child; - GList *children; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_MENU_SHELL (object)); - - menu_shell = GTK_MENU_SHELL (object); - - children = menu_shell->children; - while (children) - { - child = children->data; - children = children->next; - - child->parent = NULL; - gtk_object_unref (GTK_OBJECT (child)); - gtk_widget_destroy (child); - } - - g_list_free (menu_shell->children); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_menu_shell_map (GtkWidget *widget) { GtkMenuShell *menu_shell; @@ -335,14 +303,15 @@ gtk_menu_shell_button_press (GtkWidget *widget, menu_shell->active = TRUE; menu_item = gtk_get_event_widget ((GdkEvent*) event); - if (GTK_IS_MENU_ITEM (menu_item) && gtk_menu_shell_is_item (menu_shell, menu_item)) + if (menu_item && GTK_IS_MENU_ITEM (menu_item) && + gtk_menu_shell_is_item (menu_shell, menu_item)) { if ((menu_item->parent == widget) && (menu_item != menu_shell->active_menu_item)) { if (menu_shell->active_menu_item) gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item)); - + menu_shell->active_menu_item = menu_item; gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_shell->active_menu_item), MENU_SHELL_CLASS (menu_shell)->submenu_placement); @@ -353,7 +322,7 @@ gtk_menu_shell_button_press (GtkWidget *widget, { gtk_menu_shell_deactivate (menu_shell); } - + if (menu_shell->active) menu_shell->button = event->button; } @@ -451,7 +420,7 @@ gtk_menu_shell_enter_notify (GtkWidget *widget, { menu_item = gtk_get_event_widget ((GdkEvent*) event); - if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) + if (!menu_item || !GTK_WIDGET_IS_SENSITIVE (menu_item)) return TRUE; if ((menu_item->parent == widget) && @@ -496,7 +465,7 @@ gtk_menu_shell_leave_notify (GtkWidget *widget, menu_shell = GTK_MENU_SHELL (widget); event_widget = gtk_get_event_widget ((GdkEvent*) event); - if (!GTK_IS_MENU_ITEM (event_widget)) + if (!event_widget || !GTK_IS_MENU_ITEM (event_widget)) return TRUE; menu_item = GTK_MENU_ITEM (event_widget); @@ -541,18 +510,20 @@ gtk_menu_shell_remove (GtkContainer *container, GtkWidget *widget) { GtkMenuShell *menu_shell; - + gint was_visible; + g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (container)); g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - - gtk_widget_unparent (widget); - + + was_visible = GTK_WIDGET_VISIBLE (widget); menu_shell = GTK_MENU_SHELL (container); menu_shell->children = g_list_remove (menu_shell->children, widget); - - if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container)) + + gtk_widget_unparent (widget); + + if (was_visible && GTK_WIDGET_VISIBLE (container)) gtk_widget_queue_resize (GTK_WIDGET (container)); } diff --git a/gtk/gtkmisc.c b/gtk/gtkmisc.c index 94cd48925..2791e6990 100644 --- a/gtk/gtkmisc.c +++ b/gtk/gtkmisc.c @@ -158,6 +158,7 @@ gtk_misc_realize (GtkWidget *widget) if (GTK_WIDGET_NO_WINDOW (widget)) { widget->window = gtk_widget_get_parent_window (widget); + gdk_window_ref (widget->window); widget->style = gtk_style_attach (widget->style, widget->window); } else diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index d5e099c1f..171c381fe 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -35,7 +35,6 @@ typedef void (*GtkNotebookSignal) (GtkObject *object, static void gtk_notebook_class_init (GtkNotebookClass *klass); static void gtk_notebook_init (GtkNotebook *notebook); -static void gtk_notebook_destroy (GtkObject *object); static void gtk_notebook_map (GtkWidget *widget); static void gtk_notebook_unmap (GtkWidget *widget); static void gtk_notebook_realize (GtkWidget *widget); @@ -129,8 +128,6 @@ gtk_notebook_class_init (GtkNotebookClass *class) gtk_object_class_add_signals (object_class, notebook_signals, LAST_SIGNAL); - object_class->destroy = gtk_notebook_destroy; - widget_class->map = gtk_notebook_map; widget_class->unmap = gtk_notebook_unmap; widget_class->realize = gtk_notebook_realize; @@ -270,7 +267,10 @@ gtk_notebook_remove_page (GtkNotebook *notebook, gtk_notebook_prev_page (notebook); if (notebook->cur_page == page) notebook->cur_page = NULL; - + + gtk_widget_unparent (page->child); + gtk_widget_unparent (page->tab_label); + notebook->children = g_list_remove_link (notebook->children, tmp_list); g_list_free (tmp_list); g_free (page); @@ -433,42 +433,6 @@ gtk_notebook_set_show_border (GtkNotebook *notebook, } static void -gtk_notebook_destroy (GtkObject *object) -{ - GtkNotebook *notebook; - GtkNotebookPage *page; - GList *children; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (object)); - - notebook = GTK_NOTEBOOK (object); - - children = notebook->children; - while (children) - { - page = children->data; - children = children->next; - - page->child->parent = NULL; - page->tab_label->parent = NULL; - - gtk_object_unref (GTK_OBJECT (page->child)); - gtk_object_unref (GTK_OBJECT (page->tab_label)); - - gtk_widget_destroy (page->child); - gtk_widget_destroy (page->tab_label); - - g_free (page); - } - - g_list_free (notebook->children); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_notebook_map (GtkWidget *widget) { GtkNotebook *notebook; @@ -552,6 +516,7 @@ gtk_notebook_unrealize (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); gtk_style_detach (widget->style); + gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); widget->window = NULL; } diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c index 8a28f9063..07d921f34 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -17,9 +17,11 @@ */ #include <stdarg.h> #include <string.h> +#include <stdio.h> #include "gtkobject.h" #include "gtksignal.h" +#define GTK_OBJECT_DEBUG 1 #define OBJECT_DATA_ID_CHUNK 1024 @@ -64,16 +66,18 @@ static void gtk_object_set_arg (GtkObject *object, static void gtk_object_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void gtk_real_object_destroy (GtkObject *object); +static void gtk_object_real_destroy (GtkObject *object); +static void gtk_object_finalize (GtkObject *object); +static void gtk_object_notify_weaks (GtkObject *object); static void gtk_object_data_init (void); static GtkObjectData* gtk_object_data_new (void); static void gtk_object_data_destroy (GtkObjectData *odata); static guint* gtk_object_data_id_alloc (void); + GtkArg* gtk_object_collect_args (guint *nargs, va_list args1, va_list args2); - static gint object_signals[LAST_SIGNAL] = { 0 }; static gint object_data_init = TRUE; @@ -88,13 +92,35 @@ static GHashTable *arg_info_ht = NULL; static const char *user_data_key = "user_data"; +#ifdef GTK_OBJECT_DEBUG +static int obj_count = 0; +static GSList *living_objs = NULL; + +static void +gtk_object_debug (void) +{ + GSList *node; + + printf ("%d living objects\n", obj_count); + for (node = living_objs; node; node = node->next) + { + GtkObject *obj = (GtkObject *)node->data; + /* + printf ("%p: %s %d %s\n", + obj, gtk_type_name (GTK_OBJECT_TYPE (obj)), + obj->ref_count, + GTK_OBJECT_FLOATING (obj)? "floating" : ""); + */ + } +} +#endif GTK_OBJECT_DEBUG + /***************************************** - * gtk_object_get_type: + * gtk_object_init_type: * * arguments: * * results: - * The type identifier for GtkObject's *****************************************/ void @@ -114,6 +140,10 @@ gtk_object_init_type () object_type = gtk_type_unique (0, &object_info); g_assert (object_type == GTK_TYPE_OBJECT); + +#ifdef GTK_OBJECT_DEBUG + ATEXIT (gtk_object_debug); +#endif GTK_OBJECT_DEBUG } GtkType @@ -151,7 +181,8 @@ gtk_object_class_init (GtkObjectClass *class) gtk_object_class_add_signals (class, object_signals, LAST_SIGNAL); - class->destroy = gtk_real_object_destroy; + class->destroy = gtk_object_real_destroy; + class->finalize = gtk_object_finalize; } /***************************************** @@ -165,13 +196,18 @@ gtk_object_class_init (GtkObjectClass *class) static void gtk_object_init (GtkObject *object) { - object->flags = 0; - object->ref_count = 0; + object->flags = GTK_FLOATING; + object->ref_count = 1; object->object_data = NULL; + +#ifdef GTK_OBJECT_DEBUG + obj_count++; + living_objs = g_slist_prepend (living_objs, object); +#endif GTK_OBJECT_DEBUG } /***************************************** - * gtk_object_arg: + * gtk_object_set_arg: * * arguments: * @@ -214,6 +250,14 @@ gtk_object_set_arg (GtkObject *object, } } +/***************************************** + * gtk_object_get_arg: + * + * arguments: + * + * results: + *****************************************/ + static void gtk_object_get_arg (GtkObject *object, GtkArg *arg, @@ -345,9 +389,201 @@ gtk_object_unref (GtkObject *object) { g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_OBJECT (object)); - + + if (object->ref_count == 1) + gtk_object_destroy (object); + if (object->ref_count > 0) object->ref_count -= 1; + + if (object->ref_count == 0) + { + obj_count--; + +#ifdef GTK_OBJECT_DEBUG + g_assert (g_slist_find (living_objs, object)); + living_objs = g_slist_remove (living_objs, object); + /* + fprintf (stderr, "finalizing %p %s\n", object, gtk_type_name (object->klass->type)); + */ +#endif GTK_OBJECT_DEBUG + + object->klass->finalize (object); + } +} + +/***************************************** + * gtk_object_finalize: + * + * arguments: + * + * results: + *****************************************/ + +static void +gtk_object_finalize (GtkObject *object) +{ + GtkObjectData *odata; + + gtk_object_notify_weaks (object); + + if (object->object_data) + { + odata = object->object_data; + while (odata->next) + odata = odata->next; + + odata->next = object_data_free_list; + object_data_free_list = object->object_data; + object->object_data = NULL; + } + + g_free (object); +} + +/***************************************** + * gtk_object_sink: + * + * arguments: + * + * results: + *****************************************/ + +void +gtk_object_sink (GtkObject *object) +{ + if (GTK_OBJECT_FLOATING (object)) + { + GTK_OBJECT_UNSET_FLAGS (object, GTK_FLOATING); + gtk_object_unref (object); + } +} + +/***************************************** + * gtk_object_destroy: + * + * arguments: + * + * results: + *****************************************/ + +void +gtk_object_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + gtk_signal_emit (object, object_signals[DESTROY]); +} + +/***************************************** + * gtk_object_real_destroy: + * + * arguments: + * + * results: + *****************************************/ + +static void +gtk_object_real_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + gtk_signal_handlers_destroy (object); + + /* object->klass = gtk_type_class (gtk_destroyed_get_type ()); */ +} + +/***************************************** + * Weak references. + * + * Weak refs are very similar to the old "destroy" signal. They allow + * one to register a callback that is called when the weakly + * referenced object is destroyed. + * + * They are not implemented as a signal because they really are + * special and need to be used with great care. Unlike signals, who + * should be able to execute any code whatsoever. + * + * A weakref callback is not allowed to retain a reference to the + * object. In fact, the object is no longer there at all when it is + * called. + * + * A weakref callback is called atmost once. + * + *****************************************/ + +typedef struct _GtkWeakRef GtkWeakRef; + +struct _GtkWeakRef +{ + GtkWeakRef *next; + GtkDestroyNotify notify; + gpointer data; +}; + +static const gchar *weakrefs_key = "weakrefs"; + +void +gtk_object_weakref (GtkObject *object, + GtkDestroyNotify notify, + gpointer data) +{ + GtkWeakRef *weak; + + g_return_if_fail (object != NULL); + g_return_if_fail (notify != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + weak = g_new (GtkWeakRef, 1); + weak->next = gtk_object_get_data (object, weakrefs_key); + weak->notify = notify; + weak->data = data; + gtk_object_set_data (object, weakrefs_key, weak); +} + +void +gtk_object_weakunref (GtkObject *object, + GtkDestroyNotify notify, + gpointer data) +{ + GtkWeakRef *weaks, *w, **wp; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + weaks = gtk_object_get_data (object, weakrefs_key); + for (wp = &weaks; *wp; wp = &(*wp)->next) + { + w = *wp; + if (w->notify == notify && w->data == data) + { + if (w == weaks) + gtk_object_set_data (object, weakrefs_key, w->next); + else + *wp = w->next; + g_free (w); + return; + } + } +} + +static void +gtk_object_notify_weaks (GtkObject *object) +{ + GtkWeakRef *w1, *w2; + + w1 = gtk_object_get_data (object, weakrefs_key); + gtk_object_set_data (object, weakrefs_key, NULL); + + while (w1) + { + w1->notify (w1->data); + w2 = w1->next; + g_free (w1); + w1 = w2; + } } /***************************************** @@ -743,33 +979,6 @@ gtk_object_get_arg_type (const char *arg_name) } /***************************************** - * gtk_object_destroy: - * - * arguments: - * - * results: - *****************************************/ - -void -gtk_object_destroy (GtkObject *object) -{ - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_OBJECT (object)); - - if ((object->ref_count > 0) || GTK_OBJECT_IN_CALL (object)) - { - GTK_OBJECT_SET_FLAGS (object, GTK_NEED_DESTROY); - } - else - { - GTK_OBJECT_UNSET_FLAGS (object, GTK_NEED_DESTROY); - GTK_OBJECT_SET_FLAGS (object, GTK_BEING_DESTROYED); - - gtk_signal_emit (object, object_signals[DESTROY]); - } -} - -/***************************************** * gtk_object_set_data: * * arguments: @@ -986,37 +1195,6 @@ gtk_object_check_class_cast (GtkObjectClass *klass, } /***************************************** - * gtk_real_object_destroy: - * - * arguments: - * - * results: - *****************************************/ - -static void -gtk_real_object_destroy (GtkObject *object) -{ - GtkObjectData *odata; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_OBJECT (object)); - - gtk_signal_handlers_destroy (object); - - if (object->object_data) - { - odata = object->object_data; - while (odata->next) - odata = odata->next; - - odata->next = object_data_free_list; - object_data_free_list = object->object_data; - } - - g_free (object); -} - -/***************************************** * gtk_object_data_init: * * arguments: diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index 97a77fc3f..b52083d4c 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -35,9 +35,9 @@ extern "C" { */ enum { - GTK_NEED_DESTROY = 1 << 0, - GTK_BEING_DESTROYED = 1 << 1, - GTK_IN_CALL = 1 << 2 + GTK_FLOATING = 1 << 0, + GTK_RESERVED_1 = 1 << 1, + GTK_RESERVED_2 = 1 << 2 }; @@ -75,9 +75,7 @@ enum */ #define GTK_OBJECT_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_object_get_type (), GtkObjectClass) #define GTK_OBJECT_FLAGS(obj) (GTK_OBJECT (obj)->flags) -#define GTK_OBJECT_NEED_DESTROY(obj) (GTK_OBJECT_FLAGS (obj) & GTK_NEED_DESTROY) -#define GTK_OBJECT_BEING_DESTROYED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_BEING_DESTROYED) -#define GTK_OBJECT_IN_CALL(obj) (GTK_OBJECT_FLAGS (obj) & GTK_IN_CALL) +#define GTK_OBJECT_FLOATING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_FLOATING) #define GTK_OBJECT_DESTROY(obj) (GTK_OBJECT (obj)->klass->destroy) #define GTK_OBJECT_TYPE(obj) (GTK_OBJECT (obj)->klass->type) #define GTK_OBJECT_SIGNALS(obj) (GTK_OBJECT (obj)->klass->signals) @@ -108,11 +106,10 @@ struct _GtkObject */ guint32 flags; - /* 16 bit reference count. "gtk_object_destroy" actually only - * destroys an object when its ref count is 0. (Decrementing - * a reference count of 0 is defined as a no-op). + /* reference count. + * refer to the file REFCOUNTING on this issue. */ - guint16 ref_count; + guint ref_count; /* A pointer to the objects class. This will actually point to * the derived objects class struct (which will be derived from @@ -146,6 +143,10 @@ struct _GtkObjectClass */ gint nsignals; + /* The number of arguments per class. + */ + guint n_args; + /* The destroy function for objects. In one way ore another * this is defined for all objects. If an object class overrides * this method in order to perform class specific destruction @@ -155,9 +156,7 @@ struct _GtkObjectClass */ void (* destroy) (GtkObject *object); - /* The number of arguments per class. - */ - guint n_args; + void (* finalize) (GtkObject *object); }; @@ -199,9 +198,18 @@ GtkObject* gtk_object_newv (guint type, guint nargs, GtkArg *args); -void gtk_object_ref (GtkObject *object); +void gtk_object_ref (GtkObject *object); +void gtk_object_unref (GtkObject *object); +void gtk_object_sink (GtkObject *object); + +void gtk_object_weakref (GtkObject *object, + GtkDestroyNotify notify, + gpointer data); +void gtk_object_weakunref (GtkObject *object, + GtkDestroyNotify notify, + gpointer data); -void gtk_object_unref (GtkObject *object); +void gtk_object_destroy (GtkObject *object); /* gtk_object_getv() sets an arguments type and value, or just * its type to GTK_TYPE_INVALID. @@ -239,17 +247,6 @@ void gtk_object_add_arg_type (const gchar *arg_name, GtkType gtk_object_get_arg_type (const gchar *arg_name); -/* Emit the "destroy" signal for "object". Normally it is - * permissible to emit a signal for an object instead of - * calling the corresponding convenience routine, however - * "gtk_object_destroy" should be called instead of emitting - * the signal manually as it checks to see if the object is - * currently handling another signal emittion (very likely) - * and sets the GTK_NEED_DESTROY flag which tells the object - * to be destroyed when it is done handling the signal emittion. - */ -void gtk_object_destroy (GtkObject *object); - /* Set 'data' to the "object_data" field of the object. The * data is indexed by the "key". If there is already data * associated with "key" then the new data will replace it. diff --git a/gtk/gtkoptionmenu.c b/gtk/gtkoptionmenu.c index c598f5e05..eca7660c4 100644 --- a/gtk/gtkoptionmenu.c +++ b/gtk/gtkoptionmenu.c @@ -145,21 +145,23 @@ gtk_option_menu_set_menu (GtkOptionMenu *option_menu, g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - gtk_option_menu_remove_menu (option_menu); - - option_menu->menu = menu; - gtk_object_ref (GTK_OBJECT (option_menu->menu)); + if (option_menu->menu != menu) + { + gtk_option_menu_remove_menu (option_menu); + option_menu->menu = menu; + gtk_widget_ref (option_menu->menu); - gtk_option_menu_calc_size (option_menu); + gtk_option_menu_calc_size (option_menu); - gtk_signal_connect (GTK_OBJECT (option_menu->menu), "deactivate", - (GtkSignalFunc) gtk_option_menu_deactivate, - option_menu); + gtk_signal_connect (GTK_OBJECT (option_menu->menu), "deactivate", + (GtkSignalFunc) gtk_option_menu_deactivate, + option_menu); - if (GTK_WIDGET (option_menu)->parent) - gtk_widget_queue_resize (GTK_WIDGET (option_menu)); + if (GTK_WIDGET (option_menu)->parent) + gtk_widget_queue_resize (GTK_WIDGET (option_menu)); - gtk_option_menu_update_contents (option_menu); + gtk_option_menu_update_contents (option_menu); + } } void @@ -174,7 +176,7 @@ gtk_option_menu_remove_menu (GtkOptionMenu *option_menu) gtk_signal_disconnect_by_data (GTK_OBJECT (option_menu->menu), option_menu); - gtk_object_unref (GTK_OBJECT (option_menu->menu)); + gtk_widget_unref (option_menu->menu); option_menu->menu = NULL; } } @@ -212,11 +214,13 @@ gtk_option_menu_destroy (GtkObject *object) option_menu = GTK_OPTION_MENU (object); - gtk_option_menu_remove_contents (option_menu); + /* gtk_option_menu_remove_contents (option_menu); + */ if (option_menu->menu) { - gtk_object_unref (GTK_OBJECT (option_menu->menu)); gtk_widget_destroy (option_menu->menu); + gtk_widget_unref (option_menu->menu); + option_menu->menu = NULL; } if (GTK_OBJECT_CLASS (parent_class)->destroy) diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c index cd4d3949a..d47082c45 100644 --- a/gtk/gtkpaned.c +++ b/gtk/gtkpaned.c @@ -20,7 +20,6 @@ static void gtk_paned_class_init (GtkPanedClass *klass); static void gtk_paned_init (GtkPaned *paned); -static void gtk_paned_destroy (GtkObject *object); static void gtk_paned_realize (GtkWidget *widget); static void gtk_paned_map (GtkWidget *widget); static void gtk_paned_unmap (GtkWidget *widget); @@ -76,8 +75,6 @@ gtk_paned_class_init (GtkPanedClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); - object_class->destroy = gtk_paned_destroy; - widget_class->realize = gtk_paned_realize; widget_class->map = gtk_paned_map; widget_class->unmap = gtk_paned_unmap; @@ -110,33 +107,6 @@ gtk_paned_init (GtkPaned *paned) static void -gtk_paned_destroy (GtkObject *object) -{ - GtkPaned *paned; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_PANED (object)); - - paned = GTK_PANED (object); - - if (paned->child1) - { - paned->child1->parent = NULL; - gtk_object_unref (GTK_OBJECT (paned->child1)); - gtk_widget_destroy (paned->child1); - } - if (paned->child2) - { - paned->child2->parent = NULL; - gtk_object_unref (GTK_OBJECT (paned->child2)); - gtk_widget_destroy (paned->child2); - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_paned_realize (GtkWidget *widget) { GtkPaned *paned; @@ -174,6 +144,7 @@ gtk_paned_realize (GtkWidget *widget) gdk_window_raise (paned->handle); widget->window = gtk_widget_get_parent_window (widget); + gdk_window_ref (widget->window); widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, paned->handle, GTK_STATE_NORMAL); @@ -249,13 +220,18 @@ gtk_paned_unrealize (GtkWidget *widget) if (paned->handle) { + gdk_window_set_user_data (paned->handle, NULL); gdk_window_destroy (paned->handle); + paned->handle = NULL; gdk_cursor_destroy (paned->cursor); + paned->cursor = NULL; } - paned->handle = NULL; - paned->cursor = NULL; - widget->window = NULL; + if (widget->window) + { + gdk_window_unref (widget->window); + widget->window = NULL; + } } static gint diff --git a/gtk/gtkpixmap.c b/gtk/gtkpixmap.c index 9505f598f..b6136c969 100644 --- a/gtk/gtkpixmap.c +++ b/gtk/gtkpixmap.c @@ -23,7 +23,7 @@ static void gtk_pixmap_class_init (GtkPixmapClass *klass); static void gtk_pixmap_init (GtkPixmap *pixmap); static gint gtk_pixmap_expose (GtkWidget *widget, GdkEventExpose *event); -static void gtk_pixmap_destroy (GtkObject *object); +static void gtk_pixmap_finalize (GtkObject *object); static GtkWidgetClass *parent_class; @@ -61,7 +61,7 @@ gtk_pixmap_class_init (GtkPixmapClass *class) widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (gtk_widget_get_type ()); - object_class->destroy = gtk_pixmap_destroy; + object_class->finalize = gtk_pixmap_finalize; widget_class->expose_event = gtk_pixmap_expose; } @@ -90,11 +90,10 @@ gtk_pixmap_new (GdkPixmap *val, } static void -gtk_pixmap_destroy (GtkObject *object) +gtk_pixmap_finalize (GtkObject *object) { gtk_pixmap_set (GTK_PIXMAP (object), NULL, NULL); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } void diff --git a/gtk/gtkpreview.c b/gtk/gtkpreview.c index 1f60d8624..8e73d277d 100644 --- a/gtk/gtkpreview.c +++ b/gtk/gtkpreview.c @@ -46,7 +46,7 @@ struct _GtkPreviewProp static void gtk_preview_class_init (GtkPreviewClass *klass); static void gtk_preview_init (GtkPreview *preview); -static void gtk_preview_destroy (GtkObject *object); +static void gtk_preview_finalize (GtkObject *object); static void gtk_preview_realize (GtkWidget *widget); static void gtk_preview_unrealize (GtkWidget *widget); static gint gtk_preview_expose (GtkWidget *widget, @@ -162,7 +162,7 @@ gtk_preview_class_init (GtkPreviewClass *klass) parent_class = gtk_type_class (gtk_widget_get_type ()); preview_class = klass; - object_class->destroy = gtk_preview_destroy; + object_class->finalize = gtk_preview_finalize; widget_class->realize = gtk_preview_realize; widget_class->unrealize = gtk_preview_unrealize; @@ -636,7 +636,7 @@ gtk_preview_get_info () static void -gtk_preview_destroy (GtkObject *object) +gtk_preview_finalize (GtkObject *object) { GtkPreview *preview; @@ -648,8 +648,7 @@ gtk_preview_destroy (GtkObject *object) g_free (preview->buffer); preview->type = (GtkPreviewType) -1; - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index 82d3c9783..43a95e898 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -30,7 +30,7 @@ static void gtk_range_class_init (GtkRangeClass *klass); static void gtk_range_init (GtkRange *range); -static void gtk_range_destroy (GtkObject *object); +static void gtk_range_finalize (GtkObject *object); static void gtk_range_draw (GtkWidget *widget, GdkRectangle *area); static void gtk_range_draw_focus (GtkWidget *widget); @@ -111,7 +111,7 @@ gtk_range_class_init (GtkRangeClass *class) parent_class = gtk_type_class (gtk_widget_get_type ()); - object_class->destroy = gtk_range_destroy; + object_class->finalize = gtk_range_finalize; widget_class->draw = gtk_range_draw; widget_class->draw_focus = gtk_range_draw_focus; @@ -208,6 +208,8 @@ gtk_range_set_adjustment (GtkRange *range, if (adjustment) { gtk_object_ref (GTK_OBJECT (adjustment)); + gtk_object_sink (GTK_OBJECT (adjustment)); + gtk_signal_connect (GTK_OBJECT (adjustment), "changed", (GtkSignalFunc) gtk_range_adjustment_changed, (gpointer) range); @@ -586,7 +588,7 @@ gtk_range_calc_value (GtkRange *range, static void -gtk_range_destroy (GtkObject *object) +gtk_range_finalize (GtkObject *object) { GtkRange *range; @@ -598,8 +600,7 @@ gtk_range_destroy (GtkObject *object) if (range->adjustment) gtk_object_unref (GTK_OBJECT (range->adjustment)); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void @@ -648,16 +649,31 @@ gtk_range_unrealize (GtkWidget *widget) gtk_style_detach (widget->style); if (range->slider) - gdk_window_destroy (range->slider); + { + gdk_window_set_user_data (range->slider, NULL); + gdk_window_destroy (range->slider); + } if (range->trough) - gdk_window_destroy (range->trough); + { + gdk_window_set_user_data (range->trough, NULL); + gdk_window_destroy (range->trough); + } if (range->step_forw) - gdk_window_destroy (range->step_forw); + { + gdk_window_set_user_data (range->step_forw, NULL); + gdk_window_destroy (range->step_forw); + } if (range->step_back) - gdk_window_destroy (range->step_back); + { + gdk_window_set_user_data (range->step_back, NULL); + gdk_window_destroy (range->step_back); + } if (widget->window) - gdk_window_destroy (widget->window); - + { + gdk_window_set_user_data (widget->window, NULL); + gdk_window_destroy (widget->window); + } + range->slider = NULL; range->trough = NULL; range->step_forw = NULL; diff --git a/gtk/gtkruler.c b/gtk/gtkruler.c index dc5d841db..5876ba9fa 100644 --- a/gtk/gtkruler.c +++ b/gtk/gtkruler.c @@ -197,6 +197,7 @@ gtk_ruler_unrealize (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); gtk_style_detach (widget->style); + gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); widget->window = NULL; diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index 073b6ef2a..b7f902ba6 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -25,7 +25,6 @@ static void gtk_scale_class_init (GtkScaleClass *klass); static void gtk_scale_init (GtkScale *scale); -static void gtk_scale_destroy (GtkObject *object); static void gtk_scale_draw_background (GtkRange *range); @@ -67,8 +66,6 @@ gtk_scale_class_init (GtkScaleClass *class) parent_class = gtk_type_class (gtk_range_get_type ()); - object_class->destroy = gtk_scale_destroy; - range_class->draw_background = gtk_scale_draw_background; class->slider_length = 31; @@ -207,20 +204,6 @@ gtk_scale_draw_value (GtkScale *scale) static void -gtk_scale_destroy (GtkObject *object) -{ - GtkRange *range; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_SCALE (object)); - - range = GTK_RANGE (object); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void gtk_scale_draw_background (GtkRange *range) { g_return_if_fail (range != NULL); diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index d637ce25e..2c5b841ae 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -25,6 +25,7 @@ static void gtk_scrolled_window_class_init (GtkScrolledWindowClass *klass); static void gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window); static void gtk_scrolled_window_destroy (GtkObject *object); +static void gtk_scrolled_window_finalize (GtkObject *object); static void gtk_scrolled_window_map (GtkWidget *widget); static void gtk_scrolled_window_unmap (GtkWidget *widget); static void gtk_scrolled_window_draw (GtkWidget *widget, @@ -87,6 +88,7 @@ gtk_scrolled_window_class_init (GtkScrolledWindowClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); object_class->destroy = gtk_scrolled_window_destroy; + object_class->finalize = gtk_scrolled_window_finalize; widget_class->map = gtk_scrolled_window_map; widget_class->unmap = gtk_scrolled_window_unmap; @@ -141,7 +143,11 @@ gtk_scrolled_window_new (GtkAdjustment *hadjustment, gtk_widget_show (scrolled_window->viewport); gtk_widget_show (scrolled_window->hscrollbar); gtk_widget_show (scrolled_window->vscrollbar); - + + gtk_widget_ref (scrolled_window->viewport); + gtk_widget_ref (scrolled_window->hscrollbar); + gtk_widget_ref (scrolled_window->vscrollbar); + return GTK_WIDGET (scrolled_window); } @@ -202,6 +208,17 @@ gtk_scrolled_window_destroy (GtkObject *object) } static void +gtk_scrolled_window_finalize (GtkObject *object) +{ + GtkScrolledWindow *scrolled_window; + + scrolled_window = GTK_SCROLLED_WINDOW (object); + gtk_widget_unref (scrolled_window->viewport); + gtk_widget_unref (scrolled_window->hscrollbar); + gtk_widget_unref (scrolled_window->vscrollbar); +} + +static void gtk_scrolled_window_map (GtkWidget *widget) { GtkScrolledWindow *scrolled_window; @@ -421,7 +438,16 @@ gtk_scrolled_window_remove (GtkContainer *container, g_return_if_fail (widget != NULL); scrolled_window = GTK_SCROLLED_WINDOW (container); - gtk_container_remove (GTK_CONTAINER (scrolled_window->viewport), widget); + + if (scrolled_window->viewport == widget || + scrolled_window->hscrollbar == widget || + scrolled_window->vscrollbar == widget) + { + /* this happens during destroy */ + gtk_widget_unparent (widget); + } + else + gtk_container_remove (GTK_CONTAINER (scrolled_window->viewport), widget); } static void diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c index e3d27de7a..e7309382f 100644 --- a/gtk/gtkselection.c +++ b/gtk/gtkselection.c @@ -401,6 +401,7 @@ gtk_selection_remove_all (GtkWidget *widget) selection_handlers = gtk_object_get_data (GTK_OBJECT (widget), gtk_selection_handler_key); + gtk_object_remove_data (GTK_OBJECT (widget), gtk_selection_handler_key); tmp_list = selection_handlers; while (tmp_list) diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c index 285726295..4996ebf15 100644 --- a/gtk/gtksignal.c +++ b/gtk/gtksignal.c @@ -56,7 +56,8 @@ struct _GtkSignal struct _GtkHandler { guint16 id; - guint signal_type : 13; + guint16 ref_count; + guint16 signal_type; guint object_signal : 1; guint blocked : 1; guint after : 1; @@ -94,10 +95,12 @@ static guint gtk_signal_info_hash (GtkSignalInfo *a); static gint gtk_signal_info_compare (GtkSignalInfo *a, GtkSignalInfo *b); static GtkHandler* gtk_signal_handler_new (void); -static void gtk_signal_handler_destroy (GtkHandler *handler); +static void gtk_signal_handler_ref (GtkHandler *handler); +static void gtk_signal_handler_unref (GtkHandler *handler, + GtkObject *object); static void gtk_signal_handler_insert (GtkObject *object, GtkHandler *handler); -static gint gtk_signal_real_emit (GtkObject *object, +static void gtk_signal_real_emit (GtkObject *object, gint signal_type, va_list args); static GtkHandler* gtk_signal_get_handlers (GtkObject *object, @@ -321,56 +324,48 @@ gtk_signal_name (gint signal_num) return NULL; } -gint +void gtk_signal_emit (GtkObject *object, gint signal_type, ...) { - gint return_val; - va_list args; - g_return_val_if_fail (object != NULL, FALSE); + g_return_if_fail (object != NULL); if (initialize) gtk_signal_init (); va_start (args, signal_type); - return_val = gtk_signal_real_emit (object, signal_type, args); + gtk_signal_real_emit (object, signal_type, args); va_end (args); - - return return_val; } -gint +void gtk_signal_emit_by_name (GtkObject *object, const gchar *name, ...) { - gint return_val; gint type; va_list args; - g_return_val_if_fail (object != NULL, FALSE); + g_return_if_fail (object != NULL); if (initialize) gtk_signal_init (); - return_val = TRUE; type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object)); if (type) { va_start (args, name); - return_val = gtk_signal_real_emit (object, type, args); + gtk_signal_real_emit (object, type, args); va_end (args); } - - return return_val; } void @@ -560,7 +555,7 @@ gtk_signal_disconnect (GtkObject *object, prev->next = tmp->next; else gtk_object_set_data (object, handler_key, tmp->next); - gtk_signal_handler_destroy (tmp); + gtk_signal_handler_unref (tmp, object); return; } @@ -575,53 +570,29 @@ void gtk_signal_disconnect_by_data (GtkObject *object, gpointer data) { - GtkHandler *start; GtkHandler *tmp; - GtkHandler *prev; + GtkHandler *next; gint found_one; - + g_return_if_fail (object != NULL); - + if (initialize) gtk_signal_init (); - - prev = NULL; - start = gtk_object_get_data (object, handler_key); - tmp = start; + + tmp = gtk_object_get_data (object, handler_key); found_one = FALSE; - + while (tmp) { + next = tmp->next; if (tmp->func_data == data) { found_one = TRUE; - - if (prev) - prev->next = tmp->next; - else - start = tmp->next; - - gtk_signal_handler_destroy (tmp); - - if (prev) - { - tmp = prev->next; - } - else - { - prev = NULL; - tmp = start; - } - } - else - { - prev = tmp; - tmp = tmp->next; + gtk_signal_handler_unref (tmp, object); } + tmp = next; } - gtk_object_set_data (object, handler_key, start); - if (!found_one) g_warning ("could not find handler containing data (0x%0lX)", (long) data); } @@ -752,11 +723,9 @@ gtk_signal_handlers_destroy (GtkObject *object) while (list) { handler = list->next; - gtk_signal_handler_destroy (list); + gtk_signal_handler_unref (list, object); list = handler; } - - gtk_object_remove_data (object, handler_key); } } @@ -834,6 +803,7 @@ gtk_signal_handler_new () handler = g_chunk_new (GtkHandler, handler_mem_chunk); handler->id = 0; + handler->ref_count = 1; handler->signal_type = 0; handler->object_signal = FALSE; handler->blocked = FALSE; @@ -848,13 +818,35 @@ gtk_signal_handler_new () } static void -gtk_signal_handler_destroy (GtkHandler *handler) +gtk_signal_handler_ref (GtkHandler *handler) { - if (!handler->func && destroy) - (* destroy) (handler->func_data); - else if (handler->destroy_func) - (* handler->destroy_func) (handler->func_data); - g_mem_chunk_free (handler_mem_chunk, handler); + handler->ref_count += 1; +} + +static void +gtk_signal_handler_unref (GtkHandler *handler, + GtkObject *object) +{ + GtkHandler *tmp; + + handler->ref_count -= 1; + if (handler->ref_count == 0) + { + if (!handler->func && destroy) + (* destroy) (handler->func_data); + else if (handler->destroy_func) + (* handler->destroy_func) (handler->func_data); + + tmp = gtk_object_get_data (object, handler_key); + while (tmp && tmp->next != handler) + tmp = tmp->next; + if (tmp) + tmp->next = handler->next; + else + gtk_object_set_data (object, handler_key, handler->next); + + g_mem_chunk_free (handler_mem_chunk, handler); + } } static void @@ -899,105 +891,92 @@ gtk_signal_handler_insert (GtkObject *object, } } -static gint +static void gtk_signal_real_emit (GtkObject *object, gint signal_type, va_list args) { - gint old_value; GtkSignal *signal; GtkHandler *handlers; GtkHandlerInfo info; guchar **signal_func_offset; - gint being_destroyed; GtkArg params[MAX_PARAMS]; - - g_return_val_if_fail (object != NULL, FALSE); - g_return_val_if_fail (signal_type >= 1, TRUE); - - being_destroyed = GTK_OBJECT_BEING_DESTROYED (object); - if (!GTK_OBJECT_NEED_DESTROY (object)) + + g_return_if_fail (object != NULL); + g_return_if_fail (signal_type >= 1); + + signal = g_hash_table_lookup (signal_hash_table, &signal_type); + g_return_if_fail (signal != NULL); + g_return_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object), + signal->info.object_type)); + + if ((signal->run_type & GTK_RUN_NO_RECURSE) && + gtk_emission_check (current_emissions, object, signal_type)) { - signal = g_hash_table_lookup (signal_hash_table, &signal_type); - g_return_val_if_fail (signal != NULL, TRUE); - g_return_val_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object), signal->info.object_type), TRUE); - - if ((signal->run_type & GTK_RUN_NO_RECURSE) && - gtk_emission_check (current_emissions, object, signal_type)) - { - gtk_emission_add (&restart_emissions, object, signal_type); - return TRUE; - } - - old_value = GTK_OBJECT_IN_CALL (object); - GTK_OBJECT_SET_FLAGS (object, GTK_IN_CALL); - - gtk_params_get (params, signal->nparams, signal->params, signal->return_val, args); - - gtk_emission_add (¤t_emissions, object, signal_type); - - restart: - if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST && signal->function_offset != 0) - { - signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset); - if (*signal_func_offset) - (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, NULL, params); - if (GTK_OBJECT_NEED_DESTROY (object)) - goto done; - } - - info.object = object; - info.marshaller = signal->marshaller; - info.params = params; - info.param_types = signal->params; - info.return_val = signal->return_val; - info.nparams = signal->nparams; - info.run_type = signal->run_type; - info.signal_type = signal_type; - - handlers = gtk_signal_get_handlers (object, signal_type); - switch (gtk_handlers_run (handlers, &info, FALSE)) - { - case DONE: - goto done; - case RESTART: - goto restart; - } - - if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST && signal->function_offset != 0) - { - signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset); - if (*signal_func_offset) - (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, NULL, params); - if (being_destroyed || GTK_OBJECT_NEED_DESTROY (object)) - goto done; - } - - switch (gtk_handlers_run (handlers, &info, TRUE)) - { - case DONE: - goto done; - case RESTART: - goto restart; - } - - done: - gtk_emission_remove (¤t_emissions, object, signal_type); - - if (signal->run_type & GTK_RUN_NO_RECURSE) - gtk_emission_remove (&restart_emissions, object, signal_type); - - if (!being_destroyed && !old_value) - GTK_OBJECT_UNSET_FLAGS (object, GTK_IN_CALL); + gtk_emission_add (&restart_emissions, object, signal_type); + return; } - - if (!being_destroyed && GTK_OBJECT_NEED_DESTROY (object) && !GTK_OBJECT_IN_CALL (object)) + + gtk_params_get (params, signal->nparams, signal->params, + signal->return_val, args); + + gtk_emission_add (¤t_emissions, object, signal_type); + + gtk_object_ref (object); + +restart: + if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST && signal->function_offset != 0) { - gtk_object_destroy (object); - return FALSE; + signal_func_offset = (guchar**) ((guchar*) object->klass + + signal->function_offset); + if (*signal_func_offset) + (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, + NULL, params); } - - return TRUE; + + info.object = object; + info.marshaller = signal->marshaller; + info.params = params; + info.param_types = signal->params; + info.return_val = signal->return_val; + info.nparams = signal->nparams; + info.run_type = signal->run_type; + info.signal_type = signal_type; + + handlers = gtk_signal_get_handlers (object, signal_type); + switch (gtk_handlers_run (handlers, &info, FALSE)) + { + case DONE: + goto done; + case RESTART: + goto restart; + } + + if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST && signal->function_offset != 0) + { + signal_func_offset = (guchar**) ((guchar*) object->klass + + signal->function_offset); + if (*signal_func_offset) + (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, + NULL, params); + } + + switch (gtk_handlers_run (handlers, &info, TRUE)) + { + case DONE: + goto done; + case RESTART: + goto restart; + } + +done: + + gtk_emission_remove (¤t_emissions, object, signal_type); + + if (signal->run_type & GTK_RUN_NO_RECURSE) + gtk_emission_remove (&restart_emissions, object, signal_type); + + gtk_object_unref (object); } static GtkHandler* @@ -1188,8 +1167,20 @@ gtk_handlers_run (GtkHandler *handlers, GtkHandlerInfo *info, gint after) { - while (handlers && (handlers->signal_type == info->signal_type)) + GtkHandler *handlers_next; + + while (handlers) { + if (!after) + gtk_signal_handler_ref (handlers); + + if (handlers->signal_type != info->signal_type) + { + if (after) + gtk_signal_handler_unref (handlers, info->object); + break; + } + if (!handlers->blocked && (handlers->after == after)) { if (handlers->func) @@ -1218,25 +1209,35 @@ gtk_handlers_run (GtkHandler *handlers, info->param_types, info->return_val); - if (GTK_OBJECT_NEED_DESTROY (info->object)) - return DONE; - else if (gtk_emission_check (stop_emissions, info->object, info->signal_type)) + if (gtk_emission_check (stop_emissions, info->object, + info->signal_type)) { - gtk_emission_remove (&stop_emissions, info->object, info->signal_type); + gtk_emission_remove (&stop_emissions, info->object, + info->signal_type); if (info->run_type & GTK_RUN_NO_RECURSE) - gtk_emission_remove (&restart_emissions, info->object, info->signal_type); + gtk_emission_remove (&restart_emissions, info->object, + info->signal_type); + if (after) + gtk_signal_handler_unref (handlers, info->object); return DONE; } else if ((info->run_type & GTK_RUN_NO_RECURSE) && - gtk_emission_check (restart_emissions, info->object, info->signal_type)) + gtk_emission_check (restart_emissions, info->object, + info->signal_type)) { - gtk_emission_remove (&restart_emissions, info->object, info->signal_type); + gtk_emission_remove (&restart_emissions, info->object, + info->signal_type); + if (after) + gtk_signal_handler_unref (handlers, info->object); return RESTART; } } - handlers = handlers->next; + handlers_next = handlers->next; + if (after) + gtk_signal_handler_unref (handlers, info->object); + handlers = handlers_next; } return 0; diff --git a/gtk/gtksignal.h b/gtk/gtksignal.h index 8519cf9da..ab5580795 100644 --- a/gtk/gtksignal.h +++ b/gtk/gtksignal.h @@ -76,10 +76,10 @@ gint gtk_signal_newv (const gchar *name, gint gtk_signal_lookup (const gchar *name, gint object_type); gchar* gtk_signal_name (gint signal_num); -gint gtk_signal_emit (GtkObject *object, +void gtk_signal_emit (GtkObject *object, gint signal_type, ...); -gint gtk_signal_emit_by_name (GtkObject *object, +void gtk_signal_emit_by_name (GtkObject *object, const gchar *name, ...); void gtk_signal_emit_stop (GtkObject *object, diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index 12652f652..c95131d72 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -165,7 +165,7 @@ gtk_style_new () GtkStyle *style; gint i; - style = g_new (GtkStyle, 1); + style = g_new0 (GtkStyle, 1); if (!default_font) default_font = @@ -721,7 +721,7 @@ gtk_style_new_from_key (GtkStyleKey *key) if (!style) { - style = g_new (GtkStyle, 1); + style = g_new0 (GtkStyle, 1); style->ref_count = 1; style->attach_count = 0; diff --git a/gtk/gtktable.c b/gtk/gtktable.c index 59a47c126..dd635f00b 100644 --- a/gtk/gtktable.c +++ b/gtk/gtktable.c @@ -20,7 +20,7 @@ static void gtk_table_class_init (GtkTableClass *klass); static void gtk_table_init (GtkTable *table); -static void gtk_table_destroy (GtkObject *object); +static void gtk_table_finalize (GtkObject *object); static void gtk_table_map (GtkWidget *widget); static void gtk_table_unmap (GtkWidget *widget); static void gtk_table_draw (GtkWidget *widget, @@ -89,7 +89,7 @@ gtk_table_class_init (GtkTableClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); - object_class->destroy = gtk_table_destroy; + object_class->finalize = gtk_table_finalize; widget_class->map = gtk_table_map; widget_class->unmap = gtk_table_unmap; @@ -179,8 +179,6 @@ gtk_table_new (gint rows, static void gtk_table_expand_cols (GtkTable *table, int new_max) { - int i; - table->cols = g_realloc (table->cols, new_max * sizeof (GtkTableRowCol)); gtk_table_init_cols (table, table->ncols, new_max); table->ncols = new_max; @@ -189,8 +187,6 @@ gtk_table_expand_cols (GtkTable *table, int new_max) static void gtk_table_expand_rows (GtkTable *table, int new_max) { - int i; - table->rows = g_realloc (table->rows, new_max * sizeof (GtkTableRowCol)); gtk_table_init_rows (table, table->nrows, new_max); table->nrows = new_max; @@ -209,7 +205,6 @@ gtk_table_attach (GtkTable *table, gint ypadding) { GtkTableChild *table_child; - int resize = 0; g_return_if_fail (table != NULL); g_return_if_fail (GTK_IS_TABLE (table)); @@ -348,35 +343,19 @@ gtk_table_set_col_spacings (GtkTable *table, static void -gtk_table_destroy (GtkObject *object) +gtk_table_finalize (GtkObject *object) { GtkTable *table; - GtkTableChild *child; - GList *children; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_TABLE (object)); table = GTK_TABLE (object); - children = table->children; - while (children) - { - child = children->data; - children = children->next; - - child->widget->parent = NULL; - gtk_object_unref (GTK_OBJECT (child->widget)); - gtk_widget_destroy (child->widget); - g_free (child); - } - - g_list_free (table->children); g_free (table->rows); g_free (table->cols); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); } static void diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 23709ce72..358ee9e1a 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -52,8 +52,8 @@ #define MARK_OFFSET(mark) ((mark)->offset) #define MARK_PROPERTY_LENGTH(mark) (MARK_CURRENT_PROPERTY(mark)->length) #define MARK_CURRENT_FONT(mark) (((TextProperty*)(mark)->property->data)->font->gdk_font) -#define MARK_CURRENT_FORE(mark) (((TextProperty*)(mark)->property->data)->fore_color) -#define MARK_CURRENT_BACK(mark) (((TextProperty*)(mark)->property->data)->back_color) +#define MARK_CURRENT_FORE(mark) (&((TextProperty*)(mark)->property->data)->fore_color) +#define MARK_CURRENT_BACK(mark) (&((TextProperty*)(mark)->property->data)->back_color) #define MARK_CURRENT_TEXT_FONT(m) (((TextProperty*)(m)->property->data)->font) #define TEXT_INDEX(t, index) ((index) < (t)->gap_position ? (t)->text[index] : \ (t)->text[(index) + (t)->gap_size]) @@ -104,10 +104,10 @@ struct _TextProperty TextFont* font; /* Background Color. */ - GdkColor* back_color; + GdkColor back_color; /* Foreground Color. */ - GdkColor* fore_color; + GdkColor fore_color; /* Length of this property. */ guint length; @@ -152,7 +152,7 @@ struct _LineParams static void gtk_text_class_init (GtkTextClass *klass); static void gtk_text_init (GtkText *text); -static void gtk_text_destroy (GtkObject *object); +static void gtk_text_finalize (GtkObject *object); static void gtk_text_realize (GtkWidget *widget); static void gtk_text_unrealize (GtkWidget *widget); static void gtk_text_draw_focus (GtkWidget *widget); @@ -346,7 +346,7 @@ gtk_text_class_init (GtkTextClass *class) parent_class = gtk_type_class (gtk_widget_get_type ()); - object_class->destroy = gtk_text_destroy; + object_class->finalize = gtk_text_finalize; widget_class->realize = gtk_text_realize; widget_class->unrealize = gtk_text_unrealize; @@ -443,7 +443,8 @@ gtk_text_set_adjustments (GtkText *text, { text->hadj = hadj; gtk_object_ref (GTK_OBJECT (text->hadj)); - + gtk_object_sink (GTK_OBJECT (text->hadj)); + gtk_signal_connect (GTK_OBJECT (text->hadj), "changed", (GtkSignalFunc) gtk_text_adjustment, text); @@ -459,7 +460,8 @@ gtk_text_set_adjustments (GtkText *text, { text->vadj = vadj; gtk_object_ref (GTK_OBJECT (text->vadj)); - + gtk_object_sink (GTK_OBJECT (text->vadj)); + gtk_signal_connect (GTK_OBJECT (text->vadj), "changed", (GtkSignalFunc) gtk_text_adjustment, text); @@ -538,10 +540,11 @@ gtk_text_insert (GtkText *text, g_assert (GTK_WIDGET_REALIZED (text)); - /* back may be NULL, fore may not. */ if (fore == NULL) fore = &text->widget.style->fg[GTK_STATE_NORMAL]; - + if (back == NULL) + back = &text->widget.style->bg[GTK_STATE_NORMAL]; + /* This must be because we need to have the style set up. */ g_assert (GTK_WIDGET_REALIZED(text)); @@ -603,13 +606,20 @@ gtk_text_forward_delete (GtkText *text, } static void -gtk_text_destroy (GtkObject *object) +gtk_text_finalize (GtkObject *object) { + GtkText *text; + g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_TEXT (object)); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + text = (GtkText *)object; + if (text->hadj) + gtk_object_unref (GTK_OBJECT (text->hadj)); + if (text->vadj) + gtk_object_unref (GTK_OBJECT (text->vadj)); + + GTK_OBJECT_CLASS(parent_class)->finalize (object); } static void @@ -694,7 +704,9 @@ gtk_text_unrealize (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); gtk_style_detach (widget->style); + gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); + gdk_window_set_user_data (text->text_area, NULL); gdk_window_destroy (text->text_area); gdk_gc_destroy (text->gc); @@ -1723,8 +1735,8 @@ static gint text_properties_equal (TextProperty* prop, GdkFont* font, GdkColor *fore, GdkColor *back) { return prop->font == get_text_font(font) && - (fore == prop->fore_color || gdk_color_equal(prop->fore_color, fore)) && - (back == prop->back_color || (back && prop->back_color && gdk_color_equal(prop->back_color, back))); + gdk_color_equal(&prop->fore_color, fore) && + gdk_color_equal(&prop->back_color, back); } static TextProperty* @@ -1743,8 +1755,9 @@ new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length) prop = g_chunk_new(TextProperty, text_property_chunk); prop->font = get_text_font (font); - prop->fore_color = fore; - prop->back_color = back; + prop->fore_color = *fore; + if (back) + prop->back_color = *back; prop->length = length; return prop; diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index c9c9977a1..11c664a87 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -189,7 +189,7 @@ gtk_toolbar_destroy (GtkObject *object) toolbar = GTK_TOOLBAR (object); - gtk_tooltips_unref (toolbar->tooltips); + gtk_object_unref (GTK_OBJECT (toolbar->tooltips)); for (children = toolbar->children; children; children = children->next) { diff --git a/gtk/gtktooltips.c b/gtk/gtktooltips.c index 774258036..272eadc70 100644 --- a/gtk/gtktooltips.c +++ b/gtk/gtktooltips.c @@ -29,6 +29,9 @@ #define DEFAULT_DELAY 500 /* Default delay in ms */ +static void gtk_tooltips_class_init (GtkTooltipsClass *klass); +static void gtk_tooltips_init (GtkTooltips *tooltips); +static void gtk_tooltips_destroy (GtkObject *object); static gint gtk_tooltips_event_handler (GtkWidget *widget, GdkEvent *event); @@ -42,47 +45,61 @@ static gint gtk_tooltips_widget_visible (GtkWidget *widget); static gint gtk_tooltips_timeout (gpointer data); static void gtk_tooltips_create_window (GtkTooltips *tooltips); static void gtk_tooltips_draw_tips (GtkTooltips *tooltips); -static void gtk_tooltips_real_destroy (GtkTooltips *tooltips); -GtkTooltips * -gtk_tooltips_new () -{ - GtkTooltips *tooltips; +static GtkDataClass *parent_class; - tooltips = g_new0 (GtkTooltips, 1); +guint +gtk_tooltips_get_type () +{ + static guint tooltips_type = 0; - if (tooltips != NULL) + if (!tooltips_type) { - tooltips->ref_count = 1; - - tooltips->enabled = TRUE; - tooltips->numwidgets = 0; - tooltips->delay = DEFAULT_DELAY; - tooltips->widget_list = NULL; - tooltips->gc = NULL; - tooltips->foreground = NULL; - tooltips->background = NULL; - tooltips->tip_window = NULL; + GtkTypeInfo tooltips_info = + { + "GtkTooltips", + sizeof (GtkTooltips), + sizeof (GtkTooltipsClass), + (GtkClassInitFunc) gtk_tooltips_class_init, + (GtkObjectInitFunc) gtk_tooltips_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL, + }; + + tooltips_type = gtk_type_unique (gtk_data_get_type (), &tooltips_info); } - return tooltips; + return tooltips_type; } -GtkTooltips* -gtk_tooltips_ref (GtkTooltips *tooltips) +static void +gtk_tooltips_class_init (GtkTooltipsClass *class) { - g_return_val_if_fail (tooltips != NULL, NULL); - tooltips->ref_count += 1; - return tooltips; + GtkObjectClass *object_class; + + object_class = (GtkObjectClass*) class; + parent_class = gtk_type_class (gtk_data_get_type ()); + + object_class->destroy = gtk_tooltips_destroy; } -void -gtk_tooltips_unref (GtkTooltips *tooltips) +static void +gtk_tooltips_init (GtkTooltips *tooltips) { - g_return_if_fail (tooltips != NULL); - tooltips->ref_count -= 1; - if (tooltips->ref_count == 0) - gtk_tooltips_real_destroy (tooltips); + tooltips->enabled = TRUE; + tooltips->numwidgets = 0; + tooltips->delay = DEFAULT_DELAY; + tooltips->widget_list = NULL; + tooltips->gc = NULL; + tooltips->foreground = NULL; + tooltips->background = NULL; + tooltips->tip_window = NULL; +} + +GtkTooltips * +gtk_tooltips_new () +{ + return gtk_type_new (gtk_tooltips_get_type ()); } void @@ -93,21 +110,22 @@ gtk_tooltips_free_string (gpointer data, gpointer user_data) } static void -gtk_tooltips_destroy_data (GtkTooltips *tooltips, - GtkTooltipsData *tooltipsdata) +gtk_tooltips_destroy_data (GtkTooltipsData *tooltipsdata) { g_free (tooltipsdata->tips_text); g_list_foreach (tooltipsdata->row, gtk_tooltips_free_string, 0); if (tooltipsdata->row) g_list_free (tooltipsdata->row); gtk_signal_disconnect_by_data (GTK_OBJECT (tooltipsdata->widget), - (gpointer) tooltips); + (gpointer) tooltipsdata); + gtk_widget_unref (tooltipsdata->widget); g_free (tooltipsdata); } static void -gtk_tooltips_real_destroy (GtkTooltips *tooltips) +gtk_tooltips_destroy (GtkObject *object) { + GtkTooltips *tooltips = GTK_TOOLTIPS (object); GList *current; GtkTooltipsData *tooltipsdata; @@ -125,25 +143,30 @@ gtk_tooltips_real_destroy (GtkTooltips *tooltips) while (current != NULL) { tooltipsdata = (GtkTooltipsData*) current->data; - gtk_tooltips_destroy_data (tooltips, tooltipsdata); current = current->next; + gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata); } - g_list_free (tooltips->widget_list); } if (tooltips->tip_window != NULL) - gtk_widget_destroy (tooltips->tip_window); + { + gtk_widget_destroy (tooltips->tip_window); + gtk_widget_unref (tooltips->tip_window); + tooltips->tip_window = NULL; + } if (tooltips->gc != NULL) - gdk_gc_destroy (tooltips->gc); - - g_free (tooltips); + { + gdk_gc_destroy (tooltips->gc); + tooltips->gc = NULL; + } } static void gtk_tooltips_create_window (GtkTooltips *tooltips) { tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_widget_ref (tooltips->tip_window); gtk_window_set_policy (GTK_WINDOW (tooltips->tip_window), FALSE, FALSE, TRUE); gtk_widget_realize (tooltips->tip_window); } @@ -291,18 +314,19 @@ gtk_tooltips_set_tips (GtkTooltips *tooltips, g_return_if_fail (tooltips != NULL); g_return_if_fail (widget != NULL); - if (gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips") != NULL) - gtk_tooltips_widget_remove (widget, NULL); + tooltipsdata = (GtkTooltipsData *) + gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips"); + if (tooltipsdata) + gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata); - if (gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips") != NULL) - gtk_tooltips_widget_remove (widget, NULL); - tooltipsdata = g_new(GtkTooltipsData, 1); if (tooltipsdata != NULL) { memset (tooltipsdata, 0, sizeof (*tooltipsdata)); + tooltipsdata->tooltips = tooltips; tooltipsdata->widget = widget; + gtk_widget_ref (widget); tooltipsdata->tips_text = g_strdup (tips_text); if (!tooltipsdata->tips_text) @@ -318,22 +342,22 @@ gtk_tooltips_set_tips (GtkTooltips *tooltips, gtk_signal_connect_after(GTK_OBJECT (widget), "event", (GtkSignalFunc) gtk_tooltips_event_handler, - (gpointer) tooltips); + (gpointer) tooltipsdata); gtk_object_set_data (GTK_OBJECT (widget), "_GtkTooltips", - (gpointer) tooltips); - - gtk_signal_connect (GTK_OBJECT (widget), "destroy", - (GtkSignalFunc) gtk_tooltips_widget_remove, - (gpointer) tooltips); + (gpointer) tooltipsdata); gtk_signal_connect (GTK_OBJECT (widget), "unmap", (GtkSignalFunc) gtk_tooltips_widget_unmap, - (gpointer) tooltips); + (gpointer) tooltipsdata); gtk_signal_connect (GTK_OBJECT (widget), "unrealize", (GtkSignalFunc) gtk_tooltips_widget_unmap, - (gpointer) tooltips); + (gpointer) tooltipsdata); + + gtk_signal_connect (GTK_OBJECT (widget), "destroy", + (GtkSignalFunc) gtk_tooltips_widget_remove, + (gpointer) tooltipsdata); } } @@ -515,7 +539,9 @@ gtk_tooltips_event_handler (GtkWidget *widget, GtkTooltipsData *old_widget; gint returnval = FALSE; - tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget),"_GtkTooltips"); + old_widget = (GtkTooltipsData*) + gtk_object_get_data (GTK_OBJECT (widget),"_GtkTooltips"); + tooltips = old_widget->tooltips; if (tooltips->enabled == FALSE) return returnval; @@ -582,9 +608,8 @@ static void gtk_tooltips_widget_unmap (GtkWidget *widget, gpointer data) { - GtkTooltips *tooltips; - - tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips"); + GtkTooltipsData *tooltipsdata = (GtkTooltipsData *)data; + GtkTooltips *tooltips = tooltipsdata->tooltips; if (tooltips->active_widget && (tooltips->active_widget->widget == widget)) @@ -599,32 +624,11 @@ static void gtk_tooltips_widget_remove (GtkWidget *widget, gpointer data) { - GtkTooltips *tooltips; - GtkTooltipsData *tooltipsdata; - GList *list; - - tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips"); + GtkTooltipsData *tooltipsdata = (GtkTooltipsData *)data; + GtkTooltips *tooltips = tooltipsdata->tooltips; gtk_tooltips_widget_unmap (widget, data); - - list = g_list_first (tooltips->widget_list); - while (list) - { - tooltipsdata = (GtkTooltipsData*) list->data; - - if (tooltipsdata->widget == widget) - break; - - list = list->next; - } - - if (list) - { - tooltipsdata = (GtkTooltipsData*) list->data; - tooltips->widget_list = g_list_remove (tooltips->widget_list, - tooltipsdata); - gtk_tooltips_destroy_data (tooltips, tooltipsdata); - } - - gtk_object_set_data (GTK_OBJECT (widget), "_GtkTooltips", NULL); + tooltips->widget_list = g_list_remove (tooltips->widget_list, + tooltipsdata); + gtk_tooltips_destroy_data (tooltipsdata); } diff --git a/gtk/gtktooltips.h b/gtk/gtktooltips.h index 5625aa59b..3bbd09dfd 100644 --- a/gtk/gtktooltips.h +++ b/gtk/gtktooltips.h @@ -19,24 +19,35 @@ #define __GTK_TOOLTIPS_H__ #include <gdk/gdk.h> +#include <gtk/gtkdata.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#define GTK_TOOLTIPS(obj) GTK_CHECK_CAST (obj, gtk_tooltips_get_type (), GtkTooltips) +#define GTK_TOOLTIPS_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_tooltips_get_type (), GtkTooltipsClass) +#define GTK_IS_TOOLTIPS(obj) GTK_CHECK_TYPE (obj, gtk_tooltips_get_type ()) -typedef struct +typedef struct _GtkTooltips GtkTooltips; +typedef struct _GtkTooltipsClass GtkTooltipsClass; +typedef struct _GtkTooltipsData GtkTooltipsData; + +struct _GtkTooltipsData { + GtkTooltips *tooltips; GtkWidget *widget; gchar *tips_text; GdkFont *font; gint width; GList *row; -} GtkTooltipsData; +}; -typedef struct +struct _GtkTooltips { + GtkData data; + GtkWidget *tip_window; GtkTooltipsData *active_widget; GList *widget_list; @@ -51,31 +62,27 @@ typedef struct gint delay; gint timer_tag; gint timer_active; +}; - gint ref_count; -} GtkTooltips; - +struct _GtkTooltipsClass +{ + GtkDataClass parent_class; +}; +GtkType gtk_tooltips_get_type (void); GtkTooltips* gtk_tooltips_new (void); -GtkTooltips* gtk_tooltips_ref (GtkTooltips *tooltips); -void gtk_tooltips_unref (GtkTooltips *tooltips); void gtk_tooltips_enable (GtkTooltips *tooltips); - void gtk_tooltips_disable (GtkTooltips *tooltips); - void gtk_tooltips_set_delay (GtkTooltips *tooltips, gint delay); - void gtk_tooltips_set_tips (GtkTooltips *tooltips, GtkWidget *widget, const gchar *tips_text); - void gtk_tooltips_set_colors (GtkTooltips *tooltips, GdkColor *background, GdkColor *foreground); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtktree.c b/gtk/gtktree.c index c0f994398..bf6daded7 100644 --- a/gtk/gtktree.c +++ b/gtk/gtktree.c @@ -33,8 +33,8 @@ typedef void (*GtkTreeSignal) (GtkObject *object, gpointer data); -static void gtk_tree_class_init (GtkTreeClass *klass); -static void gtk_tree_init (GtkTree *tree); +static void gtk_tree_class_init (GtkTreeClass *klass); +static void gtk_tree_init (GtkTree *tree); static void gtk_tree_destroy (GtkObject *object); static void gtk_tree_map (GtkWidget *widget); static void gtk_tree_unmap (GtkWidget *widget); @@ -388,16 +388,24 @@ gtk_tree_destroy (GtkObject *object) { child = children->data; children = children->next; - - child->parent = NULL; - gtk_object_unref (GTK_OBJECT (child)); + + gtk_widget_ref (child); + gtk_widget_unparent (child); gtk_widget_destroy (child); + gtk_widget_unref (child); } g_list_free (tree->children); + tree->children = NULL; - if(tree->root_tree == NULL) - g_list_free (tree->selection); + if (tree->root_tree == tree) + { + GList *node; + for (node = tree->selection; node; node = node->next) + gtk_widget_unref ((GtkWidget *)node->data); + g_list_free (tree->selection); + tree->selection = NULL; + } if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -626,7 +634,7 @@ gtk_tree_remove (GtkContainer *container, item_list->data = widget; gtk_tree_remove_items (GTK_TREE (container), item_list); - + g_list_free (item_list); } @@ -675,6 +683,7 @@ gtk_tree_remove_items (GtkTree *tree, gtk_widget_unmap (GTK_TREE_ITEM(widget)->subtree); gtk_widget_unparent (GTK_TREE_ITEM(widget)->subtree); + GTK_TREE_ITEM(widget)->subtree = NULL; } /* remove really widget for this item */ @@ -891,7 +900,7 @@ gtk_real_tree_select_child (GtkTree *tree, g_return_if_fail (GTK_IS_TREE_ITEM (child)); root_selection = tree->root_tree->selection; - + switch (tree->root_tree->selection_mode) { case GTK_SELECTION_SINGLE: @@ -911,7 +920,8 @@ gtk_real_tree_select_child (GtkTree *tree, selection = selection->next; root_selection = g_list_remove_link (root_selection, tmp_list); - + gtk_widget_unref (tmp_item); + g_list_free (tmp_list); } else @@ -922,14 +932,16 @@ gtk_real_tree_select_child (GtkTree *tree, { gtk_tree_item_select (GTK_TREE_ITEM (child)); root_selection = g_list_prepend (root_selection, child); + gtk_widget_ref (child); } else if (child->state == GTK_STATE_SELECTED) { gtk_tree_item_deselect (GTK_TREE_ITEM (child)); root_selection = g_list_remove (root_selection, child); + gtk_widget_unref (child); } - tree->root_tree->selection= root_selection; + tree->root_tree->selection = root_selection; gtk_signal_emit (GTK_OBJECT (tree->root_tree), tree_signals[SELECTION_CHANGED]); @@ -949,6 +961,7 @@ gtk_real_tree_select_child (GtkTree *tree, selection = selection->next; root_selection = g_list_remove_link (root_selection, tmp_list); + gtk_widget_unref (tmp_item); g_list_free (tmp_list); } @@ -956,13 +969,14 @@ gtk_real_tree_select_child (GtkTree *tree, selection = selection->next; } - tree->root_tree->selection= root_selection; + tree->root_tree->selection = root_selection; if (child->state == GTK_STATE_NORMAL) { gtk_tree_item_select (GTK_TREE_ITEM (child)); root_selection = g_list_prepend (root_selection, child); - tree->root_tree->selection= root_selection; + gtk_widget_ref (child); + tree->root_tree->selection = root_selection; gtk_signal_emit (GTK_OBJECT (tree->root_tree), tree_signals[SELECTION_CHANGED]); } @@ -973,7 +987,8 @@ gtk_real_tree_select_child (GtkTree *tree, { gtk_tree_item_select (GTK_TREE_ITEM (child)); root_selection = g_list_prepend (root_selection, child); - tree->root_tree->selection= root_selection; + gtk_widget_ref (child); + tree->root_tree->selection = root_selection; gtk_signal_emit (GTK_OBJECT (tree->root_tree), tree_signals[SELECTION_CHANGED]); } @@ -981,7 +996,8 @@ gtk_real_tree_select_child (GtkTree *tree, { gtk_tree_item_deselect (GTK_TREE_ITEM (child)); root_selection = g_list_remove (root_selection, child); - tree->root_tree->selection= root_selection; + gtk_widget_unref (child); + tree->root_tree->selection = root_selection; gtk_signal_emit (GTK_OBJECT (tree->root_tree), tree_signals[SELECTION_CHANGED]); } @@ -1012,6 +1028,7 @@ gtk_real_tree_unselect_child (GtkTree *tree, GtkTree* root_tree = GTK_TREE_ROOT_TREE(tree); gtk_tree_item_deselect (GTK_TREE_ITEM (child)); root_tree->selection = g_list_remove (root_tree->selection, child); + gtk_widget_unref (child); gtk_signal_emit (GTK_OBJECT (tree->root_tree), tree_signals[SELECTION_CHANGED]); } diff --git a/gtk/gtktreeitem.c b/gtk/gtktreeitem.c index c9f2753f3..56fc7e3b4 100644 --- a/gtk/gtktreeitem.c +++ b/gtk/gtktreeitem.c @@ -273,7 +273,9 @@ gtk_tree_item_init (GtkTreeItem *tree_item) gtk_container_add(GTK_CONTAINER(eventbox), pixmapwid); gtk_widget_show(pixmapwid); tree_item->plus_pix_widget = pixmapwid; - + gtk_widget_ref (tree_item->plus_pix_widget); + gtk_object_sink (GTK_OBJECT (tree_item->plus_pix_widget)); + /* create pixmap for button '-' */ #ifndef WITH_BITMAP pixmapwid = gtk_pixmap_new (pixmap_minus, mask); @@ -284,7 +286,9 @@ gtk_tree_item_init (GtkTreeItem *tree_item) gtk_container_add(GTK_CONTAINER(eventbox), pixmapwid); gtk_widget_show(pixmapwid); tree_item->minus_pix_widget = pixmapwid; - + gtk_widget_ref (tree_item->minus_pix_widget); + gtk_object_sink (GTK_OBJECT (tree_item->minus_pix_widget)); + gtk_widget_set_parent(eventbox, GTK_WIDGET(tree_item)); } else tree_item->pixmaps_box = NULL; @@ -887,19 +891,39 @@ gtk_tree_item_destroy (GtkObject *object) /* free sub tree if it exist */ if((child = item->subtree)) { - child->parent = NULL; - gtk_object_unref (GTK_OBJECT (child)); + gtk_widget_ref (child); + gtk_widget_unparent (child); gtk_widget_destroy (child); + gtk_widget_unref (child); + item->subtree = NULL; } /* free pixmaps box */ if((child = item->pixmaps_box)) { - child->parent = NULL; - gtk_object_unref (GTK_OBJECT (child)); + gtk_widget_ref (child); + gtk_widget_unparent (child); gtk_widget_destroy (child); + gtk_widget_unref (child); + item->pixmaps_box = NULL; + } + + /* destroy plus pixmap */ + if (item->plus_pix_widget) + { + gtk_widget_destroy (item->plus_pix_widget); + gtk_widget_unref (item->plus_pix_widget); + item->plus_pix_widget = NULL; } + /* destroy minus pixmap */ + if (item->minus_pix_widget) + { + gtk_widget_destroy (item->minus_pix_widget); + gtk_widget_unref (item->minus_pix_widget); + item->minus_pix_widget = NULL; + } + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c index 599a6f3b6..2891e7c30 100644 --- a/gtk/gtktypeutils.c +++ b/gtk/gtktypeutils.c @@ -311,6 +311,27 @@ gtk_type_set_arg (GtkObject *object, (* node->type_info.arg_set_func) (object, arg, arg_id); } +GtkArg* +gtk_arg_copy (GtkArg *src_arg, + GtkArg *dest_arg) +{ + g_return_val_if_fail (src_arg != NULL, NULL); + + if (!dest_arg) + { + dest_arg = g_new0 (GtkArg, 1); + dest_arg->name = src_arg->name; + } + + dest_arg->type = src_arg->type; + dest_arg->d = src_arg->d; + + if (src_arg->type == GTK_TYPE_STRING) + dest_arg->d.string_data = g_strdup (src_arg->d.string_data); + + return dest_arg; +} + static void gtk_type_insert (GtkType parent_type, GtkType type, diff --git a/gtk/gtktypeutils.h b/gtk/gtktypeutils.h index 0cac9b0a1..836593519 100644 --- a/gtk/gtktypeutils.h +++ b/gtk/gtktypeutils.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -69,10 +69,10 @@ extern GtkType gtk_type_builtins[]; /* General Types */ #define GTK_TYPE_MAKE(ft, seqno) (((seqno)<<8)|ft) -#define GTK_FUNDAMENTAL_TYPE(t) ((GtkFundamentalType)((t)&0xFF)) -#define GTK_TYPE_SEQNO(t) ((t)>0xFF? (t)>>8:(t)) +#define GTK_FUNDAMENTAL_TYPE(t) ((GtkFundamentalType)((t)&0xFF)) +#define GTK_TYPE_SEQNO(t) ((t)>0xFF? (t)>>8:(t)) -typedef struct _GtkArg GtkArg; +typedef struct _GtkArg GtkArg; typedef struct _GtkObject GtkObject; /* forward declaration of object type */ typedef struct _GtkTypeInfo GtkTypeInfo; @@ -129,40 +129,40 @@ struct _GtkArg } d; }; -#define GTK_VALUE_CHAR(a) ((a).d.char_data) -#define GTK_VALUE_BOOL(a) ((a).d.bool_data) -#define GTK_VALUE_INT(a) ((a).d.int_data) -#define GTK_VALUE_UINT(a) ((a).d.uint_data) -#define GTK_VALUE_LONG(a) ((a).d.long_data) -#define GTK_VALUE_ULONG(a) ((a).d.ulong_data) -#define GTK_VALUE_FLOAT(a) ((a).d.float_data) -#define GTK_VALUE_DOUBLE(a) ((a).d.double_data) -#define GTK_VALUE_STRING(a) ((a).d.string_data) -#define GTK_VALUE_ENUM(a) ((a).d.int_data) -#define GTK_VALUE_FLAGS(a) ((a).d.int_data) -#define GTK_VALUE_BOXED(a) ((a).d.pointer_data) -#define GTK_VALUE_FOREIGN(a) ((a).d.foreign_data) -#define GTK_VALUE_CALLBACK(a) ((a).d.callback_data) -#define GTK_VALUE_ARGS(a) ((a).d.args_data) -#define GTK_VALUE_OBJECT(a) ((a).d.object_data) -#define GTK_VALUE_POINTER(a) ((a).d.pointer_data) -#define GTK_VALUE_SIGNAL(a) ((a).d.signal_data) +#define GTK_VALUE_CHAR(a) ((a).d.char_data) +#define GTK_VALUE_BOOL(a) ((a).d.bool_data) +#define GTK_VALUE_INT(a) ((a).d.int_data) +#define GTK_VALUE_UINT(a) ((a).d.uint_data) +#define GTK_VALUE_LONG(a) ((a).d.long_data) +#define GTK_VALUE_ULONG(a) ((a).d.ulong_data) +#define GTK_VALUE_FLOAT(a) ((a).d.float_data) +#define GTK_VALUE_DOUBLE(a) ((a).d.double_data) +#define GTK_VALUE_STRING(a) ((a).d.string_data) +#define GTK_VALUE_ENUM(a) ((a).d.int_data) +#define GTK_VALUE_FLAGS(a) ((a).d.int_data) +#define GTK_VALUE_BOXED(a) ((a).d.pointer_data) +#define GTK_VALUE_FOREIGN(a) ((a).d.foreign_data) +#define GTK_VALUE_CALLBACK(a) ((a).d.callback_data) +#define GTK_VALUE_ARGS(a) ((a).d.args_data) +#define GTK_VALUE_OBJECT(a) ((a).d.object_data) +#define GTK_VALUE_POINTER(a) ((a).d.pointer_data) +#define GTK_VALUE_SIGNAL(a) ((a).d.signal_data) #define GTK_VALUE_C_CALLBACK(a) ((a).d.c_callback_data) -#define GTK_RETLOC_CHAR(a) ((gchar*)(a).d.pointer_data) -#define GTK_RETLOC_BOOL(a) ((gint*)(a).d.pointer_data) -#define GTK_RETLOC_INT(a) ((gint*)(a).d.pointer_data) -#define GTK_RETLOC_UINT(a) ((guint*)(a).d.pointer_data) -#define GTK_RETLOC_LONG(a) ((glong*)(a).d.pointer_data) -#define GTK_RETLOC_ULONG(a) ((gulong*)(a).d.pointer_data) -#define GTK_RETLOC_FLOAT(a) ((gfloat*)(a).d.pointer_data) -#define GTK_RETLOC_DOUBLE(a) ((gdouble*)(a).d.pointer_data) -#define GTK_RETLOC_STRING(a) ((gchar**)(a).d.pointer_data) -#define GTK_RETLOC_ENUM(a) ((gint*)(a).d.pointer_data) -#define GTK_RETLOC_FLAGS(a) ((gint*)(a).d.pointer_data) -#define GTK_RETLOC_BOXED(a) ((gpointer*)(a).d.pointer_data) -#define GTK_RETLOC_OBJECT(a) ((GtkObject**)(a).d.pointer_data) -#define GTK_RETLOC_POINTER(a) ((gpointer*)(a).d.pointer_data) +#define GTK_RETLOC_CHAR(a) ((gchar*)(a).d.pointer_data) +#define GTK_RETLOC_BOOL(a) ((gint*)(a).d.pointer_data) +#define GTK_RETLOC_INT(a) ((gint*)(a).d.pointer_data) +#define GTK_RETLOC_UINT(a) ((guint*)(a).d.pointer_data) +#define GTK_RETLOC_LONG(a) ((glong*)(a).d.pointer_data) +#define GTK_RETLOC_ULONG(a) ((gulong*)(a).d.pointer_data) +#define GTK_RETLOC_FLOAT(a) ((gfloat*)(a).d.pointer_data) +#define GTK_RETLOC_DOUBLE(a) ((gdouble*)(a).d.pointer_data) +#define GTK_RETLOC_STRING(a) ((gchar**)(a).d.pointer_data) +#define GTK_RETLOC_ENUM(a) ((gint*)(a).d.pointer_data) +#define GTK_RETLOC_FLAGS(a) ((gint*)(a).d.pointer_data) +#define GTK_RETLOC_BOXED(a) ((gpointer*)(a).d.pointer_data) +#define GTK_RETLOC_OBJECT(a) ((GtkObject**)(a).d.pointer_data) +#define GTK_RETLOC_POINTER(a) ((gpointer*)(a).d.pointer_data) struct _GtkTypeInfo { @@ -176,27 +176,30 @@ struct _GtkTypeInfo }; -void gtk_type_init (void); -GtkType gtk_type_unique (guint parent_type, +void gtk_type_init (void); +GtkType gtk_type_unique (guint parent_type, GtkTypeInfo *type_info); -gchar* gtk_type_name (guint type); -GtkType gtk_type_from_name (const gchar *name); -GtkType gtk_type_parent (GtkType type); -gpointer gtk_type_class (GtkType type); -gpointer gtk_type_new (GtkType type); -void gtk_type_describe_heritage (GtkType type); -void gtk_type_describe_tree (GtkType type, - gint show_size); -gint gtk_type_is_a (GtkType type, - GtkType is_a_type); -void gtk_type_get_arg (GtkObject *object, - GtkType type, - GtkArg *arg, +gchar* gtk_type_name (guint type); +GtkType gtk_type_from_name (const gchar *name); +GtkType gtk_type_parent (GtkType type); +gpointer gtk_type_class (GtkType type); +gpointer gtk_type_new (GtkType type); +void gtk_type_describe_heritage (GtkType type); +void gtk_type_describe_tree (GtkType type, + gint show_size); +gint gtk_type_is_a (GtkType type, + GtkType is_a_type); +void gtk_type_get_arg (GtkObject *object, + GtkType type, + GtkArg *arg, guint arg_id); -void gtk_type_set_arg (GtkObject *object, - GtkType type, - GtkArg *arg, +void gtk_type_set_arg (GtkObject *object, + GtkType type, + GtkArg *arg, guint arg_id); +GtkArg* gtk_arg_copy (GtkArg *src_arg, + GtkArg *dest_arg); + #ifdef __cplusplus diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c index dbb07c002..da20db43d 100644 --- a/gtk/gtkviewport.c +++ b/gtk/gtkviewport.c @@ -21,6 +21,7 @@ static void gtk_viewport_class_init (GtkViewportClass *klass); static void gtk_viewport_init (GtkViewport *viewport); +static void gtk_viewport_finalize (GtkObject *object); static void gtk_viewport_map (GtkWidget *widget); static void gtk_viewport_unmap (GtkWidget *widget); static void gtk_viewport_realize (GtkWidget *widget); @@ -43,6 +44,8 @@ static void gtk_viewport_adjustment_changed (GtkAdjustment *adjustment, static void gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data); +static GtkBinClass *parent_class; + guint gtk_viewport_get_type () { @@ -70,12 +73,17 @@ gtk_viewport_get_type () static void gtk_viewport_class_init (GtkViewportClass *class) { + GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; + object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; + parent_class = (GtkBinClass*) gtk_type_class (gtk_bin_get_type ()); + object_class->finalize = gtk_viewport_finalize; + widget_class->map = gtk_viewport_map; widget_class->unmap = gtk_viewport_unmap; widget_class->realize = gtk_viewport_realize; @@ -122,6 +130,17 @@ gtk_viewport_new (GtkAdjustment *hadjustment, return GTK_WIDGET (viewport); } +static void +gtk_viewport_finalize (GtkObject *object) +{ + GtkViewport *viewport = GTK_VIEWPORT (object); + + gtk_object_unref (GTK_OBJECT (viewport->hadjustment)); + gtk_object_unref (GTK_OBJECT (viewport->vadjustment)); + + GTK_OBJECT_CLASS(parent_class)->finalize (object); +} + GtkAdjustment* gtk_viewport_get_hadjustment (GtkViewport *viewport) { @@ -159,7 +178,8 @@ gtk_viewport_set_hadjustment (GtkViewport *viewport, viewport->hadjustment = adjustment; gtk_object_ref (GTK_OBJECT (viewport->hadjustment)); - + gtk_object_sink (GTK_OBJECT (viewport->hadjustment)); + gtk_signal_connect (GTK_OBJECT (adjustment), "changed", (GtkSignalFunc) gtk_viewport_adjustment_changed, (gpointer) viewport); @@ -190,6 +210,7 @@ gtk_viewport_set_vadjustment (GtkViewport *viewport, viewport->vadjustment = adjustment; gtk_object_ref (GTK_OBJECT (viewport->vadjustment)); + gtk_object_sink (GTK_OBJECT (viewport->vadjustment)); gtk_signal_connect (GTK_OBJECT (adjustment), "changed", (GtkSignalFunc) gtk_viewport_adjustment_changed, @@ -328,8 +349,11 @@ gtk_viewport_unrealize (GtkWidget *widget) gtk_style_detach (widget->style); + gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); + gdk_window_set_user_data (viewport->view_window, NULL); gdk_window_destroy (viewport->view_window); + gdk_window_set_user_data (viewport->bin_window, NULL); gdk_window_destroy (viewport->bin_window); widget->window = NULL; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 992a145ae..7ddc7e990 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -76,7 +76,7 @@ enum { DROP_DATA_AVAILABLE_EVENT, OTHER_EVENT, CLIENT_EVENT, - VISIBILITY_NOTIFY_EVENT, + NO_EXPOSE_EVENT, LAST_SIGNAL }; @@ -156,18 +156,19 @@ static void gtk_widget_set_arg (GtkWidget *widget, static void gtk_widget_get_arg (GtkWidget *widget, GtkArg *arg, guint arg_id); -static void gtk_real_widget_destroy (GtkObject *object); -static void gtk_real_widget_show (GtkWidget *widget); -static void gtk_real_widget_hide (GtkWidget *widget); -static void gtk_real_widget_map (GtkWidget *widget); -static void gtk_real_widget_unmap (GtkWidget *widget); -static void gtk_real_widget_realize (GtkWidget *widget); -static void gtk_real_widget_unrealize (GtkWidget *widget); -static void gtk_real_widget_draw (GtkWidget *widget, +static void gtk_widget_real_destroy (GtkObject *object); +static void gtk_widget_real_finalize (GtkObject *object); +static void gtk_widget_real_show (GtkWidget *widget); +static void gtk_widget_real_hide (GtkWidget *widget); +static void gtk_widget_real_map (GtkWidget *widget); +static void gtk_widget_real_unmap (GtkWidget *widget); +static void gtk_widget_real_realize (GtkWidget *widget); +static void gtk_widget_real_unrealize (GtkWidget *widget); +static void gtk_widget_real_draw (GtkWidget *widget, GdkRectangle *area); -static gint gtk_real_widget_queue_draw (GtkWidget *widget); -static gint gtk_real_widget_queue_resize (GtkWidget *widget); -static void gtk_real_widget_size_allocate (GtkWidget *widget, +static gint gtk_widget_real_queue_draw (GtkWidget *widget); +static gint gtk_widget_real_queue_resize (GtkWidget *widget); +static void gtk_widget_real_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static GdkColormap* gtk_widget_peek_colormap (void); @@ -205,16 +206,16 @@ static GSList *colormap_stack = NULL; static GSList *visual_stack = NULL; static GSList *style_stack = NULL; -static const char *aux_info_key = "aux_info"; -static const char *colormap_key = "colormap"; -static const char *visual_key = "visual"; -static const char *event_key = "event_mask"; -static const char *resize_widgets_key = "resize_widgets"; -static const char *extension_event_key = "extension_event_mode"; -static const char *parent_window_key = "parent_window"; -static const char *redraw_handler_key = "redraw_handler_tag"; -static const char *resize_handler_key = "resize_handler_tag"; -static const char *shape_info_key = "shape_info"; +static GSList *gtk_widget_redraw_queue = NULL; +static GSList *gtk_widget_resize_queue = NULL; + +static const gchar *aux_info_key = "aux_info"; +static const gchar *colormap_key = "colormap"; +static const gchar *visual_key = "visual"; +static const gchar *event_key = "event_mask"; +static const gchar *extension_event_key = "extension_event_mode"; +static const gchar *parent_window_key = "parent_window"; +static const gchar *shape_info_key = "shape_info"; @@ -630,32 +631,33 @@ gtk_widget_class_init (GtkWidgetClass *klass) gtk_widget_marshal_signal_4, GTK_TYPE_BOOL, 1, GTK_TYPE_GDK_EVENT); - widget_signals[VISIBILITY_NOTIFY_EVENT] = - gtk_signal_new ("visibility_notify_event", + widget_signals[NO_EXPOSE_EVENT] = + gtk_signal_new ("no_expose_event", GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (GtkWidgetClass, visibility_notify_event), + GTK_SIGNAL_OFFSET (GtkWidgetClass, no_expose_event), gtk_widget_marshal_signal_4, GTK_TYPE_BOOL, 1, GTK_TYPE_GDK_EVENT); gtk_object_class_add_signals (object_class, widget_signals, LAST_SIGNAL); - object_class->destroy = gtk_real_widget_destroy; + object_class->destroy = gtk_widget_real_destroy; + object_class->finalize = gtk_widget_real_finalize; klass->activate_signal = 0; - klass->show = gtk_real_widget_show; - klass->hide = gtk_real_widget_hide; - klass->show_all = gtk_real_widget_show; - klass->hide_all = gtk_real_widget_hide; - klass->map = gtk_real_widget_map; - klass->unmap = gtk_real_widget_unmap; - klass->realize = gtk_real_widget_realize; - klass->unrealize = gtk_real_widget_unrealize; - klass->draw = gtk_real_widget_draw; + klass->show = gtk_widget_real_show; + klass->hide = gtk_widget_real_hide; + klass->show_all = gtk_widget_real_show; + klass->hide_all = gtk_widget_real_hide; + klass->map = gtk_widget_real_map; + klass->unmap = gtk_widget_real_unmap; + klass->realize = gtk_widget_real_realize; + klass->unrealize = gtk_widget_real_unrealize; + klass->draw = gtk_widget_real_draw; klass->draw_focus = NULL; klass->size_request = NULL; - klass->size_allocate = gtk_real_widget_size_allocate; + klass->size_allocate = gtk_widget_real_size_allocate; klass->state_changed = NULL; klass->install_accelerator = NULL; klass->remove_accelerator = NULL; @@ -688,7 +690,7 @@ gtk_widget_class_init (GtkWidgetClass *klass) klass->drop_leave_event = NULL; klass->drop_data_available_event = NULL; klass->other_event = NULL; - klass->visibility_notify_event = NULL; + klass->no_expose_event = NULL; } /***************************************** @@ -891,7 +893,7 @@ gtk_widget_init (GtkWidget *widget) widget->allocation.height = 1; widget->window = NULL; widget->parent = NULL; - + widget->style = gtk_widget_peek_style (); gtk_style_ref (widget->style); @@ -948,6 +950,18 @@ gtk_widget_new (guint type, return GTK_WIDGET (obj); } +void +gtk_widget_ref (GtkWidget *widget) +{ + gtk_object_ref (GTK_OBJECT (widget)); +} + +void +gtk_widget_unref (GtkWidget *widget) +{ + gtk_object_unref (GTK_OBJECT (widget)); +} + /***************************************** * gtk_widget_newv: * @@ -1047,93 +1061,6 @@ gtk_widget_setv (GtkWidget *widget, } /***************************************** - * gtk_widget_destroy: - * - * arguments: - * - * results: - *****************************************/ - -void -gtk_widget_destroy (GtkWidget *widget) -{ - GSList *resize_widgets; - GSList *tmp_list; - gint tag; - - g_return_if_fail (widget != NULL); - - if (GTK_WIDGET_REDRAW_PENDING (widget)) - { - GTK_WIDGET_UNSET_FLAGS (widget, GTK_REDRAW_PENDING); - gtk_object_unref (GTK_OBJECT (widget)); - tag = (gint) gtk_object_get_data (GTK_OBJECT (widget), redraw_handler_key); - gtk_idle_remove (tag); - gtk_object_remove_data (GTK_OBJECT (widget), redraw_handler_key); - } - - if (GTK_WIDGET_ANCHORED (widget) && - GTK_WIDGET_RESIZE_PENDING (widget)) - { - GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_PENDING); - gtk_object_unref (GTK_OBJECT (widget)); - tag = (gint) gtk_object_get_data (GTK_OBJECT (widget), resize_handler_key); - gtk_idle_remove (tag); - gtk_object_remove_data (GTK_OBJECT (widget), resize_handler_key); - - resize_widgets = gtk_object_get_data (GTK_OBJECT (widget), resize_widgets_key); - - tmp_list = resize_widgets; - while (tmp_list) - { - GtkWidget *child; - - child = tmp_list->data; - tmp_list = tmp_list->next; - - /* referencing needed? */ - GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED); - gtk_object_unref (GTK_OBJECT (child)); - } - - if (resize_widgets) - { - gtk_object_set_data (GTK_OBJECT (widget), resize_widgets_key, NULL); - g_slist_free (resize_widgets); - } - } - - if (GTK_WIDGET_RESIZE_NEEDED (widget)) - { - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (widget); - resize_widgets = gtk_object_get_data (GTK_OBJECT (toplevel), resize_widgets_key); - - if (resize_widgets) - { - resize_widgets = g_slist_remove (resize_widgets, widget); - GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED); - gtk_object_unref (GTK_OBJECT (widget)); - - gtk_object_set_data (GTK_OBJECT (toplevel), resize_widgets_key, resize_widgets); - } - } - - - gtk_grab_remove (widget); - - if (widget->parent) - { - if (!GTK_OBJECT_BEING_DESTROYED (widget->parent)) - gtk_container_remove (GTK_CONTAINER (widget->parent), widget); - else - gtk_object_unref (GTK_OBJECT (widget)); - } - gtk_object_destroy (GTK_OBJECT (widget)); -} - -/***************************************** * gtk_widget_unparent: * do any cleanup necessary necessary * before setting parent = NULL. @@ -1152,6 +1079,8 @@ gtk_widget_unparent (GtkWidget *widget) GtkWidget *child; g_return_if_fail (widget != NULL); + if (widget->parent == NULL) + return; toplevel = gtk_widget_get_toplevel (widget); if (GTK_IS_WINDOW (toplevel)) @@ -1174,9 +1103,35 @@ gtk_widget_unparent (GtkWidget *widget) widget->allocation.width, widget->allocation.height); + gtk_widget_unrealize (widget); widget->parent = NULL; - gtk_object_unref (GTK_OBJECT (widget)); + gtk_widget_unref (widget); +} + +/***************************************** + * gtk_widget_destroy: + * + * arguments: + * + * results: + *****************************************/ + +void +gtk_widget_destroy (GtkWidget *widget) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + gtk_object_destroy (GTK_OBJECT (widget)); +} + +void +gtk_widget_destroyed (GtkWidget *widget, + GtkWidget **widget_pointer) +{ + if (widget_pointer) + *widget_pointer = NULL; } /***************************************** @@ -1260,7 +1215,19 @@ gtk_widget_hide_all (GtkWidget *widget) GtkWidgetClass *widget_class; g_return_if_fail (widget != NULL); + g_assert (widget->parent); + if (GTK_WIDGET_RESIZE_NEEDED (widget)) + { + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (widget); + if (toplevel != widget) + GTK_CONTAINER (toplevel)->resize_widgets = + g_slist_remove (GTK_CONTAINER (toplevel)->resize_widgets, widget); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED); + } + widget_class = GTK_WIDGET_CLASS(GTK_OBJECT(widget)->klass); widget_class->hide_all (widget); } @@ -1390,11 +1357,26 @@ gtk_widget_unrealize (GtkWidget *widget) * results: *****************************************/ +static gint +gtk_widget_idle_draw (void *data) +{ + GSList *node; + + node = gtk_widget_redraw_queue; + gtk_widget_redraw_queue = NULL; + while (node) + { + gtk_widget_real_queue_draw ((GtkWidget*) node->data); + node = node->next; + } + + return gtk_widget_redraw_queue != NULL; +} + void gtk_widget_queue_draw (GtkWidget *widget) { GtkWidget *parent; - gint tag; g_return_if_fail (widget != NULL); @@ -1413,9 +1395,10 @@ gtk_widget_queue_draw (GtkWidget *widget) } GTK_WIDGET_SET_FLAGS (widget, GTK_REDRAW_PENDING); - gtk_object_ref (GTK_OBJECT (widget)); - tag = gtk_idle_add ((GtkFunction) gtk_real_widget_queue_draw, widget); - gtk_object_set_data (GTK_OBJECT (widget), redraw_handler_key, (gpointer) tag); + if (gtk_widget_redraw_queue == NULL) + gtk_idle_add ((GtkFunction) gtk_widget_idle_draw, NULL); + + gtk_widget_redraw_queue = g_slist_prepend (gtk_widget_redraw_queue, widget); } } @@ -1427,12 +1410,26 @@ gtk_widget_queue_draw (GtkWidget *widget) * results: *****************************************/ +static gint +gtk_widget_idle_sizer (void *data) +{ + GSList *node; + + node = gtk_widget_resize_queue; + gtk_widget_resize_queue = NULL; + while (node) + { + gtk_widget_real_queue_resize ((GtkWidget *)node->data); + node = node->next; + } + + return gtk_widget_resize_queue != NULL; +} + void gtk_widget_queue_resize (GtkWidget *widget) { GtkWidget *toplevel; - GSList *resize_widgets; - gint tag; g_return_if_fail (widget != NULL); @@ -1444,26 +1441,22 @@ gtk_widget_queue_resize (GtkWidget *widget) if (!GTK_WIDGET_RESIZE_PENDING (toplevel)) { GTK_WIDGET_SET_FLAGS (toplevel, GTK_RESIZE_PENDING); - gtk_object_ref (GTK_OBJECT (toplevel)); - tag = gtk_idle_add ((GtkFunction) gtk_real_widget_queue_resize, toplevel); - gtk_object_set_data (GTK_OBJECT (toplevel), resize_handler_key, (gpointer) tag); + if (gtk_widget_resize_queue == NULL) + gtk_idle_add ((GtkFunction) gtk_widget_idle_sizer, NULL); + gtk_widget_resize_queue = g_slist_prepend (gtk_widget_resize_queue, toplevel); } - resize_widgets = gtk_object_get_data (GTK_OBJECT (toplevel), resize_widgets_key); - if (g_slist_find (resize_widgets, widget) == NULL) + if (!GTK_WIDGET_RESIZE_NEEDED (widget)) { - /* referencing needed? */ GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED); - gtk_object_ref (GTK_OBJECT (widget)); - resize_widgets = g_slist_prepend (resize_widgets, widget); - - gtk_object_set_data (GTK_OBJECT (toplevel), resize_widgets_key, resize_widgets); + GTK_CONTAINER (toplevel)->resize_widgets = + g_slist_prepend (GTK_CONTAINER (toplevel)->resize_widgets, widget); } + else + g_assert (g_slist_find (GTK_CONTAINER (toplevel)->resize_widgets, widget)); /* paranoid */ } else - { - gtk_container_need_resize (GTK_CONTAINER (toplevel)); - } + gtk_container_need_resize (GTK_CONTAINER (toplevel)); } } @@ -1572,20 +1565,21 @@ gtk_widget_size_request (GtkWidget *widget, GtkRequisition *requisition) { GtkWidgetAuxInfo *aux_info; - + g_return_if_fail (widget != NULL); - - if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], requisition)) + + gtk_widget_ref (widget); + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], + requisition); + aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key); + if (aux_info) { - aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key); - if (aux_info) - { - if (aux_info->width > 0) - requisition->width = aux_info->width; - if (aux_info->height > 0) - requisition->height = aux_info->height; - } + if (aux_info->width > 0) + requisition->width = aux_info->width; + if (aux_info->height > 0) + requisition->height = aux_info->height; } + gtk_widget_unref (widget); } /***************************************** @@ -1635,13 +1629,20 @@ gtk_widget_install_accelerator (GtkWidget *widget, guint8 modifiers) { gint return_val; - + g_return_if_fail (widget != NULL); - + + gtk_widget_ref (widget); return_val = TRUE; - if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[INSTALL_ACCELERATOR], - signal_name, key, modifiers, &return_val) && return_val) - gtk_accelerator_table_install (table, GTK_OBJECT (widget), signal_name, key, modifiers); + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[INSTALL_ACCELERATOR], + signal_name, key, modifiers, &return_val); + if (return_val) + gtk_accelerator_table_install (table, + GTK_OBJECT (widget), + signal_name, + key, + modifiers); + gtk_widget_unref (widget); } /***************************************** @@ -1658,9 +1659,12 @@ gtk_widget_remove_accelerator (GtkWidget *widget, const gchar *signal_name) { g_return_if_fail (widget != NULL); - - if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR], signal_name)) - gtk_accelerator_table_remove (table, GTK_OBJECT (widget), signal_name); + + gtk_widget_ref (widget); + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR], + signal_name); + gtk_accelerator_table_remove (table, GTK_OBJECT (widget), signal_name); + gtk_widget_unref (widget); } /***************************************** @@ -1677,118 +1681,123 @@ gtk_widget_event (GtkWidget *widget, { gint return_val; gint signal_num; - + g_return_val_if_fail (widget != NULL, FALSE); - + + gtk_widget_ref (widget); return_val = FALSE; - if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event, &return_val)) + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event, + &return_val); + if (return_val) { - if (return_val) - return TRUE; - - switch (event->type) - { - case GDK_NOTHING: - signal_num = -1; - break; - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - signal_num = BUTTON_PRESS_EVENT; - break; - case GDK_BUTTON_RELEASE: - signal_num = BUTTON_RELEASE_EVENT; - break; - case GDK_MOTION_NOTIFY: - signal_num = MOTION_NOTIFY_EVENT; - break; - case GDK_DELETE: - signal_num = DELETE_EVENT; - break; - case GDK_DESTROY: - signal_num = DESTROY_EVENT; - break; - case GDK_EXPOSE: - signal_num = EXPOSE_EVENT; - break; - case GDK_KEY_PRESS: - signal_num = KEY_PRESS_EVENT; - break; - case GDK_KEY_RELEASE: - signal_num = KEY_RELEASE_EVENT; - break; - case GDK_ENTER_NOTIFY: - signal_num = ENTER_NOTIFY_EVENT; - break; - case GDK_LEAVE_NOTIFY: - signal_num = LEAVE_NOTIFY_EVENT; - break; - case GDK_FOCUS_CHANGE: - if (event->focus_change.in) - signal_num = FOCUS_IN_EVENT; - else - signal_num = FOCUS_OUT_EVENT; - break; - case GDK_CONFIGURE: - signal_num = CONFIGURE_EVENT; - break; - case GDK_MAP: - signal_num = MAP_EVENT; - break; - case GDK_UNMAP: - signal_num = UNMAP_EVENT; - break; - case GDK_PROPERTY_NOTIFY: - signal_num = PROPERTY_NOTIFY_EVENT; - break; - case GDK_SELECTION_CLEAR: - signal_num = SELECTION_CLEAR_EVENT; - break; - case GDK_SELECTION_REQUEST: - signal_num = SELECTION_REQUEST_EVENT; - break; - case GDK_SELECTION_NOTIFY: - signal_num = SELECTION_NOTIFY_EVENT; - break; - case GDK_PROXIMITY_IN: - signal_num = PROXIMITY_IN_EVENT; - break; - case GDK_PROXIMITY_OUT: - signal_num = PROXIMITY_OUT_EVENT; - break; - case GDK_DRAG_BEGIN: - signal_num = DRAG_BEGIN_EVENT; - break; - case GDK_DRAG_REQUEST: - signal_num = DRAG_REQUEST_EVENT; - break; - case GDK_DROP_ENTER: - signal_num = DROP_ENTER_EVENT; - break; - case GDK_DROP_LEAVE: - signal_num = DROP_LEAVE_EVENT; - break; - case GDK_DROP_DATA_AVAIL: - signal_num = DROP_DATA_AVAILABLE_EVENT; - break; - case GDK_OTHER_EVENT: - signal_num = OTHER_EVENT; - break; - case GDK_VISIBILITY_NOTIFY: - signal_num = VISIBILITY_NOTIFY_EVENT; - break; - case GDK_CLIENT_EVENT: - signal_num = CLIENT_EVENT; - break; - default: - g_warning ("could not determine signal number for event: %d", event->type); - return return_val; - } - - if (signal_num != -1) - gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val); + gtk_widget_unref (widget); + return TRUE; + } + + switch (event->type) + { + case GDK_NOTHING: + signal_num = -1; + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + signal_num = BUTTON_PRESS_EVENT; + break; + case GDK_BUTTON_RELEASE: + signal_num = BUTTON_RELEASE_EVENT; + break; + case GDK_MOTION_NOTIFY: + signal_num = MOTION_NOTIFY_EVENT; + break; + case GDK_DELETE: + signal_num = DELETE_EVENT; + break; + case GDK_DESTROY: + signal_num = DESTROY_EVENT; + break; + case GDK_EXPOSE: + signal_num = EXPOSE_EVENT; + break; + case GDK_KEY_PRESS: + signal_num = KEY_PRESS_EVENT; + break; + case GDK_KEY_RELEASE: + signal_num = KEY_RELEASE_EVENT; + break; + case GDK_ENTER_NOTIFY: + signal_num = ENTER_NOTIFY_EVENT; + break; + case GDK_LEAVE_NOTIFY: + signal_num = LEAVE_NOTIFY_EVENT; + break; + case GDK_FOCUS_CHANGE: + if (event->focus_change.in) + signal_num = FOCUS_IN_EVENT; + else + signal_num = FOCUS_OUT_EVENT; + break; + case GDK_CONFIGURE: + signal_num = CONFIGURE_EVENT; + break; + case GDK_MAP: + signal_num = MAP_EVENT; + break; + case GDK_UNMAP: + signal_num = UNMAP_EVENT; + break; + case GDK_PROPERTY_NOTIFY: + signal_num = PROPERTY_NOTIFY_EVENT; + break; + case GDK_SELECTION_CLEAR: + signal_num = SELECTION_CLEAR_EVENT; + break; + case GDK_SELECTION_REQUEST: + signal_num = SELECTION_REQUEST_EVENT; + break; + case GDK_SELECTION_NOTIFY: + signal_num = SELECTION_NOTIFY_EVENT; + break; + case GDK_PROXIMITY_IN: + signal_num = PROXIMITY_IN_EVENT; + break; + case GDK_PROXIMITY_OUT: + signal_num = PROXIMITY_OUT_EVENT; + break; + case GDK_DRAG_BEGIN: + signal_num = DRAG_BEGIN_EVENT; + break; + case GDK_DRAG_REQUEST: + signal_num = DRAG_REQUEST_EVENT; + break; + case GDK_DROP_ENTER: + signal_num = DROP_ENTER_EVENT; + break; + case GDK_DROP_LEAVE: + signal_num = DROP_LEAVE_EVENT; + break; + case GDK_DROP_DATA_AVAIL: + signal_num = DROP_DATA_AVAILABLE_EVENT; + break; + case GDK_OTHER_EVENT: + signal_num = OTHER_EVENT; + break; + case GDK_NO_EXPOSE: + signal_num = NO_EXPOSE_EVENT; + break; + case GDK_CLIENT_EVENT: + signal_num = CLIENT_EVENT; + break; + default: + g_warning ("could not determine signal number for event: %d", event->type); + gtk_widget_unref (widget); + return return_val; } + if (signal_num != -1) + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val); + + gtk_widget_unref (widget); return return_val; } @@ -1825,16 +1834,23 @@ gtk_widget_reparent_container_child(GtkWidget *widget, { g_return_if_fail (widget != NULL); g_return_if_fail (client_data != NULL); + + if (GTK_WIDGET_NO_WINDOW (widget)) + { + if (widget->window) + gdk_window_unref (widget->window); + widget->window = (GdkWindow*) client_data; + if (widget->window) + gdk_window_ref (widget->window); - if (!GTK_WIDGET_NO_WINDOW (widget)) - gdk_window_reparent (widget->window, - (GdkWindow *)client_data, 0, 0); - else if (GTK_IS_CONTAINER (widget)) - gtk_container_foreach (GTK_CONTAINER (widget), - gtk_widget_reparent_container_child, - client_data); + if (GTK_IS_CONTAINER (widget)) + gtk_container_foreach (GTK_CONTAINER (widget), + gtk_widget_reparent_container_child, + client_data); + } else - widget->window = (GdkWindow *)client_data; + gdk_window_reparent (widget->window, + (GdkWindow*) client_data, 0, 0); } /***************************************** @@ -1855,11 +1871,11 @@ gtk_widget_reparent (GtkWidget *widget, if (widget->parent != new_parent) { - gtk_object_ref (GTK_OBJECT (widget)); + gtk_widget_ref (widget); gtk_container_remove (GTK_CONTAINER (widget->parent), widget); gtk_container_add (GTK_CONTAINER (new_parent), widget); - gtk_object_unref (GTK_OBJECT (widget)); - + gtk_widget_unref (widget); + if (GTK_WIDGET_REALIZED (widget)) { if (GTK_WIDGET_REALIZED (new_parent)) @@ -1871,7 +1887,19 @@ gtk_widget_reparent (GtkWidget *widget, gtk_widget_reparent_container_child, gtk_widget_get_parent_window (widget)); else - widget->window = gtk_widget_get_parent_window (widget); + { + GdkWindow *parent_window; + + parent_window = gtk_widget_get_parent_window (widget); + if (parent_window != widget->window) + { + if (widget->window) + gdk_window_unref (widget->window); + widget->window = parent_window; + if (widget->window) + gdk_window_ref (widget->window); + } + } } else gdk_window_reparent (widget->window, gtk_widget_get_parent_window (widget), 0, 0); @@ -2131,6 +2159,7 @@ gtk_widget_set_state (GtkWidget *widget, data.parent_sensitive = GTK_PARENT_SENSITIVE; old_state = GTK_WIDGET_STATE (widget); + gtk_widget_propagate_state (widget, &data); if (old_state != GTK_WIDGET_STATE (widget)) gtk_widget_queue_draw (widget); @@ -2197,10 +2226,23 @@ gtk_widget_set_parent (GtkWidget *widget, GtkStateData data; g_return_if_fail (widget != NULL); - g_return_if_fail (parent != NULL); - - gtk_object_ref (GTK_OBJECT (widget)); + g_assert (widget->parent == NULL); + if (GTK_WIDGET_TOPLEVEL (widget)) + { + g_assert (parent == NULL); + g_assert (!GTK_WIDGET_TOPLEVEL_ONSCREEN (widget)); + + gtk_widget_ref (widget); + gtk_object_sink (GTK_OBJECT (widget)); + GTK_WIDGET_SET_FLAGS (widget, GTK_TOPLEVEL_ONSCREEN); + return; + } + + g_return_if_fail (parent != NULL); + + gtk_widget_ref (widget); + gtk_object_sink (GTK_OBJECT(widget)); widget->parent = parent; if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL) @@ -3030,16 +3072,58 @@ gtk_widget_marshal_signal_5 (GtkObject *object, (* rfunc) (object, GTK_VALUE_UINT (args[0]), func_data); } -/***************************************** - * gtk_real_widget_destroy: - * - * arguments: - * - * results: - *****************************************/ +static void +gtk_widget_real_destroy (GtkObject *object) +{ + GtkWidget *widget = GTK_WIDGET (object); + + gtk_widget_ref (widget); + + if (GTK_WIDGET_REDRAW_PENDING (widget)) + { + gtk_widget_redraw_queue = g_slist_remove (gtk_widget_redraw_queue, widget); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_REDRAW_PENDING); + } + + if (GTK_WIDGET_RESIZE_PENDING (widget)) + { + gtk_widget_resize_queue = g_slist_remove (gtk_widget_resize_queue, widget); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_PENDING); + } + + if (GTK_WIDGET_RESIZE_NEEDED (widget)) + { + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (widget); + GTK_CONTAINER (toplevel)->resize_widgets = + g_slist_remove (GTK_CONTAINER (toplevel)->resize_widgets, widget); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED); + } + + gtk_grab_remove (widget); + gtk_selection_remove_all (widget); + gtk_widget_unrealize (widget); + + if (widget->parent) + gtk_container_remove (GTK_CONTAINER (widget->parent), widget); + else if (GTK_WIDGET_TOPLEVEL (widget) && + GTK_WIDGET_TOPLEVEL_ONSCREEN (widget)) + { + /* printf ("special toplevel case %p %s\n", widget, gtk_type_name (GTK_WIDGET_TYPE (widget))); + */ + GTK_WIDGET_UNSET_FLAGS (widget, GTK_TOPLEVEL_ONSCREEN); + gtk_widget_unref (widget); + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + + gtk_widget_unref (widget); +} static void -gtk_real_widget_destroy (GtkObject *object) +gtk_widget_real_finalize (GtkObject *object) { GtkWidget *widget; GtkWidgetAuxInfo *aux_info; @@ -3051,17 +3135,11 @@ gtk_real_widget_destroy (GtkObject *object) widget = GTK_WIDGET (object); - if (GTK_WIDGET_REDRAW_PENDING (widget)) - g_warning ("redraw pending\n"); - if (GTK_WIDGET_RESIZE_PENDING (widget)) - g_warning ("resize pending\n"); - if (GTK_WIDGET_RESIZE_NEEDED (widget)) - g_warning ("resize needed\n"); - - gtk_selection_remove_all (widget); - if (widget->name) - g_free (widget->name); + { + g_free (widget->name); + widget->name = NULL; + } aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key); if (aux_info) @@ -3070,24 +3148,28 @@ gtk_real_widget_destroy (GtkObject *object) gtk_object_remove_data (GTK_OBJECT (widget), aux_info_key); } - events = gtk_object_get_data (GTK_OBJECT (object), event_key); + events = gtk_object_get_data (GTK_OBJECT (widget), event_key); if (events) - g_free (events); + { + g_free (events); + gtk_object_remove_data (GTK_OBJECT (widget), event_key); + } - mode = gtk_object_get_data (GTK_OBJECT (object), extension_event_key); + mode = gtk_object_get_data (GTK_OBJECT (widget), extension_event_key); if (mode) - g_free (mode); - - if (GTK_WIDGET_REALIZED (widget)) - gtk_widget_unrealize (widget); + { + g_free (mode); + gtk_object_remove_data (GTK_OBJECT (widget), extension_event_key); + } + gtk_style_unref (widget->style); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + widget->style = NULL; + + parent_class->finalize (object); } /***************************************** - * gtk_real_widget_show: + * gtk_widget_real_show: * * arguments: * @@ -3095,7 +3177,7 @@ gtk_real_widget_destroy (GtkObject *object) *****************************************/ static void -gtk_real_widget_show (GtkWidget *widget) +gtk_widget_real_show (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -3115,7 +3197,7 @@ gtk_real_widget_show (GtkWidget *widget) } /***************************************** - * gtk_real_widget_hide: + * gtk_widget_real_hide: * * arguments: * @@ -3123,7 +3205,7 @@ gtk_real_widget_show (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_hide (GtkWidget *widget) +gtk_widget_real_hide (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -3141,7 +3223,7 @@ gtk_real_widget_hide (GtkWidget *widget) } /***************************************** - * gtk_real_widget_map: + * gtk_widget_real_map: * * arguments: * @@ -3149,7 +3231,7 @@ gtk_real_widget_hide (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_map (GtkWidget *widget) +gtk_widget_real_map (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -3166,7 +3248,7 @@ gtk_real_widget_map (GtkWidget *widget) } /***************************************** - * gtk_real_widget_unmap: + * gtk_widget_real_unmap: * * arguments: * @@ -3174,7 +3256,7 @@ gtk_real_widget_map (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_unmap (GtkWidget *widget) +gtk_widget_real_unmap (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -3195,7 +3277,7 @@ gtk_real_widget_unmap (GtkWidget *widget) } /***************************************** - * gtk_real_widget_realize: + * gtk_widget_real_realize: * * arguments: * @@ -3203,19 +3285,22 @@ gtk_real_widget_unmap (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_realize (GtkWidget *widget) +gtk_widget_real_realize (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - if(widget->parent) - widget->window = gtk_widget_get_parent_window (widget); + if (widget->parent) + { + widget->window = gtk_widget_get_parent_window (widget); + gdk_window_ref (widget->window); + } widget->style = gtk_style_attach (widget->style, widget->window); } /***************************************** - * gtk_real_widget_unrealize: + * gtk_widget_real_unrealize: * * arguments: * @@ -3223,24 +3308,29 @@ gtk_real_widget_realize (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_unrealize (GtkWidget *widget) +gtk_widget_real_unrealize (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED); + /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT(widget)->klass->type)); + */ + gtk_style_detach (widget->style); if (!GTK_WIDGET_NO_WINDOW (widget)) { gdk_window_set_user_data (widget->window, NULL); gdk_window_destroy (widget->window); } + else + gdk_window_unref (widget->window); widget->window = NULL; } /***************************************** - * gtk_real_widget_draw: + * gtk_widget_real_draw: * * arguments: * @@ -3248,7 +3338,7 @@ gtk_real_widget_unrealize (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_draw (GtkWidget *widget, +gtk_widget_real_draw (GtkWidget *widget, GdkRectangle *area) { GdkEventExpose event; @@ -3262,13 +3352,15 @@ gtk_real_widget_draw (GtkWidget *widget, event.type = GDK_EXPOSE; event.window = widget->window; event.area = *area; - + + gdk_window_ref (event.window); gtk_widget_event (widget, (GdkEvent*) &event); + gdk_window_unref (event.window); } } /***************************************** - * gtk_real_widget_queue_draw: + * gtk_widget_real_queue_draw: * * arguments: * @@ -3276,25 +3368,19 @@ gtk_real_widget_draw (GtkWidget *widget, *****************************************/ static gint -gtk_real_widget_queue_draw (GtkWidget *widget) +gtk_widget_real_queue_draw (GtkWidget *widget) { g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); GTK_WIDGET_UNSET_FLAGS (widget, GTK_REDRAW_PENDING); - - gtk_object_unref (GTK_OBJECT (widget)); - if (GTK_OBJECT_NEED_DESTROY (widget) && - (GTK_OBJECT (widget)->ref_count == 0)) - gtk_widget_destroy (widget); - else - gtk_widget_draw (widget, NULL); + gtk_widget_draw (widget, NULL); return FALSE; } /***************************************** - * gtk_real_widget_queue_resize: + * gtk_widget_real_queue_resize: * * arguments: * @@ -3302,56 +3388,19 @@ gtk_real_widget_queue_draw (GtkWidget *widget) *****************************************/ static gint -gtk_real_widget_queue_resize (GtkWidget *widget) +gtk_widget_real_queue_resize (GtkWidget *widget) { - GSList *resize_widgets; - GSList *tmp_list; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); - + GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_PENDING); - - gtk_object_unref (GTK_OBJECT (widget)); - if (GTK_OBJECT_NEED_DESTROY (widget) && - (GTK_OBJECT (widget)->ref_count == 0)) - { - gtk_widget_destroy (widget); - } - else - { - gtk_container_need_resize (GTK_CONTAINER (widget)); - - if (!GTK_WIDGET_RESIZE_PENDING (widget)) - { - resize_widgets = gtk_object_get_data (GTK_OBJECT (widget), resize_widgets_key); - - tmp_list = resize_widgets; - while (tmp_list) - { - GtkWidget *child; - - child = tmp_list->data; - tmp_list = tmp_list->next; - - /* referencing needed? */ - GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED); - gtk_object_unref (GTK_OBJECT (child)); - } - - if (resize_widgets) - { - gtk_object_set_data (GTK_OBJECT (widget), resize_widgets_key, NULL); - g_slist_free (resize_widgets); - } - } - } - + gtk_container_need_resize (GTK_CONTAINER (widget)); + return FALSE; } /***************************************** - * gtk_real_widget_size_allocate: + * gtk_widget_real_size_allocate: * * arguments: * @@ -3359,7 +3408,7 @@ gtk_real_widget_queue_resize (GtkWidget *widget) *****************************************/ static void -gtk_real_widget_size_allocate (GtkWidget *widget, +gtk_widget_real_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { g_return_if_fail (widget != NULL); @@ -3492,9 +3541,9 @@ gtk_widget_propagate_state (GtkWidget *widget, if (old_state != GTK_WIDGET_STATE (widget)) { - if (!gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state)) - return; - + gtk_widget_ref (widget); + gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state); + if (GTK_IS_CONTAINER (widget)) { data->parent_sensitive = GTK_WIDGET_IS_SENSITIVE (widget); @@ -3503,6 +3552,7 @@ gtk_widget_propagate_state (GtkWidget *widget, (GtkCallback) gtk_widget_propagate_state, data); } + gtk_widget_unref (widget); } } diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 2428a0c66..83a91b7da 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -35,95 +35,99 @@ extern "C" { */ enum { - GTK_VISIBLE = 1 << 3, - GTK_MAPPED = 1 << 4, - GTK_UNMAPPED = 1 << 5, - GTK_REALIZED = 1 << 6, - GTK_SENSITIVE = 1 << 7, - GTK_PARENT_SENSITIVE = 1 << 8, - GTK_NO_WINDOW = 1 << 9, - GTK_HAS_FOCUS = 1 << 10, - GTK_CAN_FOCUS = 1 << 11, - GTK_HAS_DEFAULT = 1 << 12, - GTK_CAN_DEFAULT = 1 << 13, - GTK_PROPAGATE_STATE = 1 << 14, - GTK_ANCHORED = 1 << 15, - GTK_BASIC = 1 << 16, - GTK_USER_STYLE = 1 << 17, - GTK_HAS_GRAB = 1 << 18, - GTK_REDRAW_PENDING = 1 << 19, - GTK_RESIZE_PENDING = 1 << 20, - GTK_RESIZE_NEEDED = 1 << 21, - GTK_HAS_SHAPE_MASK = 1 << 22, - GTK_LEAVE_PENDING = 1 << 23 + GTK_VISIBLE = 1 << 3, + GTK_MAPPED = 1 << 4, + GTK_UNMAPPED = 1 << 5, + GTK_REALIZED = 1 << 6, + GTK_SENSITIVE = 1 << 7, + GTK_PARENT_SENSITIVE = 1 << 8, + GTK_NO_WINDOW = 1 << 9, + GTK_HAS_FOCUS = 1 << 10, + GTK_CAN_FOCUS = 1 << 11, + GTK_HAS_DEFAULT = 1 << 12, + GTK_CAN_DEFAULT = 1 << 13, + GTK_PROPAGATE_STATE = 1 << 14, + GTK_ANCHORED = 1 << 15, + GTK_BASIC = 1 << 16, + GTK_USER_STYLE = 1 << 17, + GTK_HAS_GRAB = 1 << 18, + GTK_REDRAW_PENDING = 1 << 19, + GTK_RESIZE_PENDING = 1 << 20, + GTK_RESIZE_NEEDED = 1 << 21, + GTK_HAS_SHAPE_MASK = 1 << 22, + GTK_LEAVE_PENDING = 1 << 23, + GTK_TOPLEVEL = 1 << 24, + GTK_TOPLEVEL_ONSCREEN = 1 << 25 }; /* Macro for casting a pointer to a GtkWidget pointer. */ -#define GTK_WIDGET(obj) GTK_CHECK_CAST (obj, gtk_widget_get_type (), GtkWidget) +#define GTK_WIDGET(obj) GTK_CHECK_CAST (obj, gtk_widget_get_type (), GtkWidget) /* Macro for casting the "class" field of an object to * a GtkWidgetClass pointer. */ -#define GTK_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_widget_get_type (), GtkWidgetClass) +#define GTK_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_widget_get_type (), GtkWidgetClass) /* Macros for extracting various fields from GtkWidget and * GtkWidgetClass structures. */ -#define GTK_WIDGET_TYPE(obj) (GTK_OBJECT_TYPE (obj)) -#define GTK_WIDGET_STATE(obj) (GTK_WIDGET (obj)->state) -#define GTK_WIDGET_SAVED_STATE(obj) (GTK_WIDGET (obj)->saved_state) -#define GTK_WIDGET_VISIBLE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_VISIBLE) -#define GTK_WIDGET_MAPPED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_MAPPED) -#define GTK_WIDGET_UNMAPPED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_UNMAPPED) -#define GTK_WIDGET_REALIZED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_REALIZED) -#define GTK_WIDGET_SENSITIVE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_SENSITIVE) +#define GTK_WIDGET_TYPE(obj) (GTK_OBJECT_TYPE (obj)) +#define GTK_WIDGET_STATE(obj) (GTK_WIDGET (obj)->state) +#define GTK_WIDGET_SAVED_STATE(obj) (GTK_WIDGET (obj)->saved_state) +#define GTK_WIDGET_VISIBLE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_VISIBLE) +#define GTK_WIDGET_MAPPED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_MAPPED) +#define GTK_WIDGET_UNMAPPED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_UNMAPPED) +#define GTK_WIDGET_REALIZED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_REALIZED) +#define GTK_WIDGET_SENSITIVE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_SENSITIVE) #define GTK_WIDGET_PARENT_SENSITIVE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_PARENT_SENSITIVE) -#define GTK_WIDGET_IS_SENSITIVE(obj) ((GTK_WIDGET_SENSITIVE (obj) && \ - GTK_WIDGET_PARENT_SENSITIVE (obj)) != 0) -#define GTK_WIDGET_NO_WINDOW(obj) (GTK_OBJECT_FLAGS (obj) & GTK_NO_WINDOW) -#define GTK_WIDGET_HAS_FOCUS(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_FOCUS) -#define GTK_WIDGET_CAN_FOCUS(obj) (GTK_OBJECT_FLAGS (obj) & GTK_CAN_FOCUS) -#define GTK_WIDGET_HAS_DEFAULT(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_DEFAULT) -#define GTK_WIDGET_CAN_DEFAULT(obj) (GTK_OBJECT_FLAGS (obj) & GTK_CAN_DEFAULT) -#define GTK_WIDGET_PROPAGATE_STATE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_PROPAGATE_STATE) -#define GTK_WIDGET_DRAWABLE(obj) (GTK_WIDGET_VISIBLE (obj) && GTK_WIDGET_MAPPED (obj)) -#define GTK_WIDGET_ANCHORED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_ANCHORED) -#define GTK_WIDGET_BASIC(obj) (GTK_OBJECT_FLAGS (obj) & GTK_BASIC) -#define GTK_WIDGET_USER_STYLE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_USER_STYLE) -#define GTK_WIDGET_HAS_GRAB(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_GRAB) -#define GTK_WIDGET_REDRAW_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_REDRAW_PENDING) -#define GTK_WIDGET_RESIZE_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_PENDING) -#define GTK_WIDGET_RESIZE_NEEDED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_NEEDED) -#define GTK_WIDGET_HAS_SHAPE_MASK(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_SHAPE_MASK) -#define GTK_WIDGET_LEAVE_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_LEAVE_PENDING) - -#define GTK_TYPE_WIDGET (gtk_widget_get_type ()) +#define GTK_WIDGET_IS_SENSITIVE(obj) ((GTK_WIDGET_SENSITIVE (obj) && \ + GTK_WIDGET_PARENT_SENSITIVE (obj)) != 0) +#define GTK_WIDGET_NO_WINDOW(obj) (GTK_OBJECT_FLAGS (obj) & GTK_NO_WINDOW) +#define GTK_WIDGET_HAS_FOCUS(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_FOCUS) +#define GTK_WIDGET_CAN_FOCUS(obj) (GTK_OBJECT_FLAGS (obj) & GTK_CAN_FOCUS) +#define GTK_WIDGET_HAS_DEFAULT(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_DEFAULT) +#define GTK_WIDGET_CAN_DEFAULT(obj) (GTK_OBJECT_FLAGS (obj) & GTK_CAN_DEFAULT) +#define GTK_WIDGET_PROPAGATE_STATE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_PROPAGATE_STATE) +#define GTK_WIDGET_DRAWABLE(obj) (GTK_WIDGET_VISIBLE (obj) && GTK_WIDGET_MAPPED (obj)) +#define GTK_WIDGET_ANCHORED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_ANCHORED) +#define GTK_WIDGET_BASIC(obj) (GTK_OBJECT_FLAGS (obj) & GTK_BASIC) +#define GTK_WIDGET_USER_STYLE(obj) (GTK_OBJECT_FLAGS (obj) & GTK_USER_STYLE) +#define GTK_WIDGET_HAS_GRAB(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_GRAB) +#define GTK_WIDGET_REDRAW_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_REDRAW_PENDING) +#define GTK_WIDGET_RESIZE_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_PENDING) +#define GTK_WIDGET_RESIZE_NEEDED(obj) (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_NEEDED) +#define GTK_WIDGET_HAS_SHAPE_MASK(obj) (GTK_OBJECT_FLAGS (obj) & GTK_HAS_SHAPE_MASK) +#define GTK_WIDGET_LEAVE_PENDING(obj) (GTK_OBJECT_FLAGS (obj) & GTK_LEAVE_PENDING) +#define GTK_WIDGET_TOPLEVEL(obj) (GTK_OBJECT_FLAGS (obj) & GTK_TOPLEVEL) +#define GTK_WIDGET_TOPLEVEL_ONSCREEN(obj) (GTK_OBJECT_FLAGS (obj) & GTK_TOPLEVEL_ONSCREEN) + +#define GTK_TYPE_WIDGET (gtk_widget_get_type ()) /* Macro for testing whether "obj" is of type GtkWidget. */ -#define GTK_IS_WIDGET(obj) GTK_CHECK_TYPE (obj, GTK_TYPE_WIDGET) +#define GTK_IS_WIDGET(obj) GTK_CHECK_TYPE (obj, GTK_TYPE_WIDGET) /* Macros for setting and clearing widget flags. Notice * that these are only wrappers for the macros which * set and clear the flags in the GtkObject structure. */ -#define GTK_WIDGET_SET_FLAGS(obj,flag) (GTK_OBJECT_SET_FLAGS (obj, flag)) +#define GTK_WIDGET_SET_FLAGS(obj,flag) (GTK_OBJECT_SET_FLAGS (obj, flag)) #define GTK_WIDGET_UNSET_FLAGS(obj,flag) (GTK_OBJECT_UNSET_FLAGS (obj, flag)) -typedef struct _GtkRequisition GtkRequisition; -typedef struct _GtkAllocation GtkAllocation; +typedef struct _GtkRequisition GtkRequisition; +typedef struct _GtkAllocation GtkAllocation; typedef struct _GtkSelectionData GtkSelectionData; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWidgetClass GtkWidgetClass; +typedef struct _GtkWidget GtkWidget; +typedef struct _GtkWidgetClass GtkWidgetClass; typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo; typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo; typedef void (*GtkCallback) (GtkWidget *widget, - gpointer data); + gpointer data); /* A requisition is a desired amount of space which a * widget may request. @@ -160,9 +164,9 @@ struct _GtkSelectionData GdkAtom selection; GdkAtom target; GdkAtom type; - gint format; + gint format; guchar *data; - gint length; + gint length; }; /* The widget is the base of the tree for displayable objects. @@ -244,99 +248,99 @@ struct _GtkWidgetClass gint activate_signal; /* basics */ - void (* show) (GtkWidget *widget); - void (* hide) (GtkWidget *widget); - void (* show_all) (GtkWidget *widget); - void (* hide_all) (GtkWidget *widget); - void (* map) (GtkWidget *widget); - void (* unmap) (GtkWidget *widget); - void (* realize) (GtkWidget *widget); - void (* unrealize) (GtkWidget *widget); - void (* draw) (GtkWidget *widget, + void (* show) (GtkWidget *widget); + void (* hide) (GtkWidget *widget); + void (* show_all) (GtkWidget *widget); + void (* hide_all) (GtkWidget *widget); + void (* map) (GtkWidget *widget); + void (* unmap) (GtkWidget *widget); + void (* realize) (GtkWidget *widget); + void (* unrealize) (GtkWidget *widget); + void (* draw) (GtkWidget *widget, GdkRectangle *area); - void (* draw_focus) (GtkWidget *widget); - void (* draw_default) (GtkWidget *widget); - void (* size_request) (GtkWidget *widget, + void (* draw_focus) (GtkWidget *widget); + void (* draw_default) (GtkWidget *widget); + void (* size_request) (GtkWidget *widget, GtkRequisition *requisition); void (* size_allocate) (GtkWidget *widget, GtkAllocation *allocation); void (* state_changed) (GtkWidget *widget, - guint previous_state); + guint previous_state); /* accelerators */ gint (* install_accelerator) (GtkWidget *widget, const gchar *signal_name, - gchar key, - guint8 modifiers); + gchar key, + guint8 modifiers); void (* remove_accelerator) (GtkWidget *widget, const gchar *signal_name); /* events */ - gint (* event) (GtkWidget *widget, - GdkEvent *event); - gint (* button_press_event) (GtkWidget *widget, + gint (* event) (GtkWidget *widget, + GdkEvent *event); + gint (* button_press_event) (GtkWidget *widget, GdkEventButton *event); - gint (* button_release_event) (GtkWidget *widget, + gint (* button_release_event) (GtkWidget *widget, GdkEventButton *event); - gint (* motion_notify_event) (GtkWidget *widget, + gint (* motion_notify_event) (GtkWidget *widget, GdkEventMotion *event); - gint (* delete_event) (GtkWidget *widget, - GdkEventAny *event); - gint (* destroy_event) (GtkWidget *widget, - GdkEventAny *event); - gint (* expose_event) (GtkWidget *widget, + gint (* delete_event) (GtkWidget *widget, + GdkEventAny *event); + gint (* destroy_event) (GtkWidget *widget, + GdkEventAny *event); + gint (* expose_event) (GtkWidget *widget, GdkEventExpose *event); - gint (* key_press_event) (GtkWidget *widget, - GdkEventKey *event); - gint (* key_release_event) (GtkWidget *widget, - GdkEventKey *event); - gint (* enter_notify_event) (GtkWidget *widget, + gint (* key_press_event) (GtkWidget *widget, + GdkEventKey *event); + gint (* key_release_event) (GtkWidget *widget, + GdkEventKey *event); + gint (* enter_notify_event) (GtkWidget *widget, GdkEventCrossing *event); - gint (* leave_notify_event) (GtkWidget *widget, + gint (* leave_notify_event) (GtkWidget *widget, GdkEventCrossing *event); - gint (* configure_event) (GtkWidget *widget, + gint (* configure_event) (GtkWidget *widget, GdkEventConfigure *event); - gint (* focus_in_event) (GtkWidget *widget, + gint (* focus_in_event) (GtkWidget *widget, GdkEventFocus *event); - gint (* focus_out_event) (GtkWidget *widget, + gint (* focus_out_event) (GtkWidget *widget, GdkEventFocus *event); - gint (* map_event) (GtkWidget *widget, - GdkEventAny *event); - gint (* unmap_event) (GtkWidget *widget, - GdkEventAny *event); - gint (* property_notify_event) (GtkWidget *widget, + gint (* map_event) (GtkWidget *widget, + GdkEventAny *event); + gint (* unmap_event) (GtkWidget *widget, + GdkEventAny *event); + gint (* property_notify_event) (GtkWidget *widget, GdkEventProperty *event); - gint (* selection_clear_event) (GtkWidget *widget, + gint (* selection_clear_event) (GtkWidget *widget, GdkEventSelection *event); - gint (* selection_request_event) (GtkWidget *widget, + gint (* selection_request_event) (GtkWidget *widget, GdkEventSelection *event); - gint (* selection_notify_event) (GtkWidget *widget, + gint (* selection_notify_event) (GtkWidget *widget, GdkEventSelection *event); - gint (* proximity_in_event) (GtkWidget *widget, + gint (* proximity_in_event) (GtkWidget *widget, GdkEventProximity *event); - gint (* proximity_out_event) (GtkWidget *widget, + gint (* proximity_out_event) (GtkWidget *widget, GdkEventProximity *event); - gint (* drag_begin_event) (GtkWidget *widget, + gint (* drag_begin_event) (GtkWidget *widget, GdkEventDragBegin *event); - gint (* drag_request_event) (GtkWidget *widget, + gint (* drag_request_event) (GtkWidget *widget, GdkEventDragRequest *event); - gint (* drop_enter_event) (GtkWidget *widget, + gint (* drop_enter_event) (GtkWidget *widget, GdkEventDropEnter *event); - gint (* drop_leave_event) (GtkWidget *widget, + gint (* drop_leave_event) (GtkWidget *widget, GdkEventDropLeave *event); - gint (* drop_data_available_event) (GtkWidget *widget, + gint (* drop_data_available_event) (GtkWidget *widget, GdkEventDropDataAvailable *event); - gint (* other_event) (GtkWidget *widget, + gint (* other_event) (GtkWidget *widget, GdkEventOther *event); - gint (* visibility_notify_event) (GtkWidget *widget, - GdkEventVisibility *event); /* selection */ void (* selection_received) (GtkWidget *widget, GtkSelectionData *selection_data); - gint (* client_event) (GtkWidget *widget, - GdkEventClient *event); + gint (* client_event) (GtkWidget *widget, + GdkEventClient *event); + gint (* no_expose_event) (GtkWidget *widget, + GdkEventAny *event); }; struct _GtkWidgetAuxInfo @@ -355,123 +359,128 @@ struct _GtkWidgetShapeInfo }; -guint gtk_widget_get_type (void); -GtkWidget* gtk_widget_new (guint type, +guint gtk_widget_get_type (void); +GtkWidget* gtk_widget_new (guint type, ...); -GtkWidget* gtk_widget_newv (guint type, - guint nargs, - GtkArg *args); -void gtk_widget_get (GtkWidget *widget, +GtkWidget* gtk_widget_newv (guint type, + guint nargs, + GtkArg *args); +void gtk_widget_ref (GtkWidget *widget); +void gtk_widget_unref (GtkWidget *widget); +void gtk_widget_sink (GtkWidget *widget); +void gtk_widget_destroy (GtkWidget *widget); +void gtk_widget_destroyed (GtkWidget *widget, + GtkWidget **widget_pointer); +void gtk_widget_get (GtkWidget *widget, GtkArg *arg); -void gtk_widget_getv (GtkWidget *widget, - guint nargs, - GtkArg *args); -void gtk_widget_set (GtkWidget *widget, +void gtk_widget_getv (GtkWidget *widget, + guint nargs, + GtkArg *args); +void gtk_widget_set (GtkWidget *widget, ...); -void gtk_widget_setv (GtkWidget *widget, - guint nargs, - GtkArg *args); -void gtk_widget_destroy (GtkWidget *widget); -void gtk_widget_unparent (GtkWidget *widget); -void gtk_widget_show (GtkWidget *widget); -void gtk_widget_hide (GtkWidget *widget); -void gtk_widget_show_all (GtkWidget *widget); -void gtk_widget_hide_all (GtkWidget *widget); -void gtk_widget_map (GtkWidget *widget); -void gtk_widget_unmap (GtkWidget *widget); -void gtk_widget_realize (GtkWidget *widget); -void gtk_widget_unrealize (GtkWidget *widget); -void gtk_widget_queue_draw (GtkWidget *widget); -void gtk_widget_queue_resize (GtkWidget *widget); -void gtk_widget_draw (GtkWidget *widget, - GdkRectangle *area); -void gtk_widget_draw_focus (GtkWidget *widget); -void gtk_widget_draw_default (GtkWidget *widget); -void gtk_widget_draw_children (GtkWidget *widget); -void gtk_widget_size_request (GtkWidget *widget, +void gtk_widget_setv (GtkWidget *widget, + guint nargs, + GtkArg *args); +void gtk_widget_unparent (GtkWidget *widget); +void gtk_widget_show (GtkWidget *widget); +void gtk_widget_hide (GtkWidget *widget); +void gtk_widget_show_all (GtkWidget *widget); +void gtk_widget_hide_all (GtkWidget *widget); +void gtk_widget_map (GtkWidget *widget); +void gtk_widget_unmap (GtkWidget *widget); +void gtk_widget_realize (GtkWidget *widget); +void gtk_widget_unrealize (GtkWidget *widget); +void gtk_widget_queue_draw (GtkWidget *widget); +void gtk_widget_queue_resize (GtkWidget *widget); +void gtk_widget_draw (GtkWidget *widget, + GdkRectangle *area); +void gtk_widget_draw_focus (GtkWidget *widget); +void gtk_widget_draw_default (GtkWidget *widget); +void gtk_widget_draw_children (GtkWidget *widget); +void gtk_widget_size_request (GtkWidget *widget, GtkRequisition *requisition); -void gtk_widget_size_allocate (GtkWidget *widget, +void gtk_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -void gtk_widget_install_accelerator (GtkWidget *widget, +void gtk_widget_install_accelerator (GtkWidget *widget, GtkAcceleratorTable *table, - const gchar *signal_name, - gchar key, - guint8 modifiers); -void gtk_widget_remove_accelerator (GtkWidget *widget, + const gchar *signal_name, + gchar key, + guint8 modifiers); +void gtk_widget_remove_accelerator (GtkWidget *widget, GtkAcceleratorTable *table, - const gchar *signal_name); -gint gtk_widget_event (GtkWidget *widget, - GdkEvent *event); - -void gtk_widget_activate (GtkWidget *widget); -void gtk_widget_reparent (GtkWidget *widget, - GtkWidget *new_parent); -void gtk_widget_popup (GtkWidget *widget, - gint x, - gint y); -gint gtk_widget_intersect (GtkWidget *widget, - GdkRectangle *area, - GdkRectangle *intersection); -gint gtk_widget_basic (GtkWidget *widget); - -void gtk_widget_grab_focus (GtkWidget *widget); -void gtk_widget_grab_default (GtkWidget *widget); - -void gtk_widget_set_name (GtkWidget *widget, - const gchar *name); -gchar* gtk_widget_get_name (GtkWidget *widget); -void gtk_widget_set_state (GtkWidget *widget, - GtkStateType state); -void gtk_widget_set_sensitive (GtkWidget *widget, - gint sensitive); -void gtk_widget_set_parent (GtkWidget *widget, - GtkWidget *parent); -void gtk_widget_set_parent_window (GtkWidget *widget, - GdkWindow *parent_window); -GdkWindow *gtk_widget_get_parent_window (GtkWidget *widget); -void gtk_widget_set_style (GtkWidget *widget, - GtkStyle *style); -void gtk_widget_set_uposition (GtkWidget *widget, - gint x, - gint y); -void gtk_widget_set_usize (GtkWidget *widget, - gint width, - gint height); -void gtk_widget_set_events (GtkWidget *widget, - gint events); -void gtk_widget_set_extension_events (GtkWidget *widget, - GdkExtensionMode mode); + const gchar *signal_name); +gint gtk_widget_event (GtkWidget *widget, + GdkEvent *event); + +void gtk_widget_activate (GtkWidget *widget); +void gtk_widget_reparent (GtkWidget *widget, + GtkWidget *new_parent); +void gtk_widget_popup (GtkWidget *widget, + gint x, + gint y); +gint gtk_widget_intersect (GtkWidget *widget, + GdkRectangle *area, + GdkRectangle *intersection); +gint gtk_widget_basic (GtkWidget *widget); + +void gtk_widget_grab_focus (GtkWidget *widget); +void gtk_widget_grab_default (GtkWidget *widget); + +void gtk_widget_set_name (GtkWidget *widget, + const gchar *name); +gchar* gtk_widget_get_name (GtkWidget *widget); +void gtk_widget_set_state (GtkWidget *widget, + GtkStateType state); +void gtk_widget_set_sensitive (GtkWidget *widget, + gint sensitive); +void gtk_widget_set_parent (GtkWidget *widget, + GtkWidget *parent); +void gtk_widget_set_parent_window (GtkWidget *widget, + GdkWindow *parent_window); +GdkWindow *gtk_widget_get_parent_window (GtkWidget *widget); +void gtk_widget_set_style (GtkWidget *widget, + GtkStyle *style); +void gtk_widget_set_uposition (GtkWidget *widget, + gint x, + gint y); +void gtk_widget_set_usize (GtkWidget *widget, + gint width, + gint height); +void gtk_widget_set_events (GtkWidget *widget, + gint events); +void gtk_widget_set_extension_events (GtkWidget *widget, + GdkExtensionMode mode); GtkWidget* gtk_widget_get_toplevel (GtkWidget *widget); GtkWidget* gtk_widget_get_ancestor (GtkWidget *widget, - gint type); + gint type); GdkColormap* gtk_widget_get_colormap (GtkWidget *widget); GdkVisual* gtk_widget_get_visual (GtkWidget *widget); GtkStyle* gtk_widget_get_style (GtkWidget *widget); -gint gtk_widget_get_events (GtkWidget *widget); +gint gtk_widget_get_events (GtkWidget *widget); GdkExtensionMode gtk_widget_get_extension_events (GtkWidget *widget); -void gtk_widget_get_pointer (GtkWidget *widget, - gint *x, - gint *y); +void gtk_widget_get_pointer (GtkWidget *widget, + gint *x, + gint *y); -gint gtk_widget_is_ancestor (GtkWidget *widget, +gint gtk_widget_is_ancestor (GtkWidget *widget, GtkWidget *ancestor); -gint gtk_widget_is_child (GtkWidget *widget, +gint gtk_widget_is_child (GtkWidget *widget, GtkWidget *child); -void gtk_widget_push_colormap (GdkColormap *cmap); -void gtk_widget_push_visual (GdkVisual *visual); -void gtk_widget_push_style (GtkStyle *style); +void gtk_widget_push_colormap (GdkColormap *cmap); +void gtk_widget_push_visual (GdkVisual *visual); +void gtk_widget_push_style (GtkStyle *style); -void gtk_widget_pop_colormap (void); -void gtk_widget_pop_visual (void); -void gtk_widget_pop_style (void); +void gtk_widget_pop_colormap (void); +void gtk_widget_pop_visual (void); +void gtk_widget_pop_style (void); -void gtk_widget_set_default_colormap (GdkColormap *colormap); -void gtk_widget_set_default_visual (GdkVisual *visual); -void gtk_widget_set_default_style (GtkStyle *style); +void gtk_widget_set_default_colormap (GdkColormap *colormap); +void gtk_widget_set_default_visual (GdkVisual *visual); +void gtk_widget_set_default_style (GtkStyle *style); /* Tells other Gtk applications to use the same default style */ -void gtk_widget_propagate_default_style(void); +void gtk_widget_propagate_default_style(void); GdkColormap* gtk_widget_get_default_colormap (void); GdkVisual* gtk_widget_get_default_visual (void); GtkStyle* gtk_widget_get_default_style (void); @@ -479,7 +488,7 @@ GtkStyle* gtk_widget_get_default_style (void); /* * see gdk_window_shape_combine_mask */ -void gtk_widget_shape_combine_mask (GtkWidget *widget, +void gtk_widget_shape_combine_mask (GtkWidget *widget, GdkBitmap *shape_mask, gint offset_x, gint offset_y); @@ -488,31 +497,31 @@ void gtk_widget_shape_combine_mask (GtkWidget *widget, * When you get a drag_enter event, you can use this to tell Gtk of other * items that are to be dragged as well... */ -void gtk_widget_dnd_drag_add (GtkWidget *widget); +void gtk_widget_dnd_drag_add (GtkWidget *widget); /* * These two functions enable drag and/or drop on a widget, * and also let Gtk know what data types will be accepted (use MIME type * naming, plus tacking "URL:" on the front for link dragging) */ -void gtk_widget_dnd_drag_set (GtkWidget *widget, - guint8 drag_enable, - gchar **type_accept_list, - guint numtypes); -void gtk_widget_dnd_drop_set (GtkWidget *widget, - guint8 drop_enable, - gchar **type_accept_list, - guint numtypes, - guint8 is_destructive_operation); +void gtk_widget_dnd_drag_set (GtkWidget *widget, + guint8 drag_enable, + gchar **type_accept_list, + guint numtypes); +void gtk_widget_dnd_drop_set (GtkWidget *widget, + guint8 drop_enable, + gchar **type_accept_list, + guint numtypes, + guint8 is_destructive_operation); /* * used to reply to a DRAG_REQUEST event - if you don't want to * give the data then pass in NULL for it */ -void gtk_widget_dnd_data_set (GtkWidget *widget, - GdkEvent *event, - gpointer data, - gulong data_numbytes); +void gtk_widget_dnd_data_set (GtkWidget *widget, + GdkEvent *event, + gpointer data, + gulong data_numbytes); #ifdef __cplusplus } diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 6657d8009..79a8ace50 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -64,7 +64,7 @@ static void gtk_window_set_arg (GtkWindow *window, static void gtk_window_get_arg (GtkWindow *window, GtkArg *arg, guint arg_id); -static void gtk_window_destroy (GtkObject *object); +static void gtk_window_finalize (GtkObject *object); static void gtk_window_show (GtkWidget *widget); static void gtk_window_hide (GtkWidget *widget); static void gtk_window_map (GtkWidget *widget); @@ -177,7 +177,7 @@ gtk_window_class_init (GtkWindowClass *klass) gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); - object_class->destroy = gtk_window_destroy; + object_class->finalize = gtk_window_finalize; widget_class->show = gtk_window_show; widget_class->hide = gtk_window_hide; @@ -206,7 +206,7 @@ static void gtk_window_init (GtkWindow *window) { GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW); - GTK_WIDGET_SET_FLAGS (window, GTK_ANCHORED); + GTK_WIDGET_SET_FLAGS (window, GTK_ANCHORED | GTK_TOPLEVEL); window->title = NULL; window->wmclass_name = NULL; @@ -223,6 +223,9 @@ gtk_window_init (GtkWindow *window) window->handling_resize = FALSE; window->position = GTK_WIN_POS_NONE; window->use_uposition = TRUE; + + /* gtk_container_add (gtk_root, GTK_WIDGET (window)); */ + gtk_widget_set_parent (GTK_WIDGET (window), NULL); } static void @@ -415,6 +418,36 @@ gtk_window_position (GtkWindow *window, window->position = position; } +gint +gtk_window_activate_focus (GtkWindow *window) +{ + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + + if (window->focus_widget) + { + gtk_widget_activate (window->focus_widget); + return TRUE; + } + + return FALSE; +} + +gint +gtk_window_activate_default (GtkWindow *window) +{ + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + + if (window->default_widget) + { + gtk_widget_activate (window->default_widget); + return TRUE; + } + + return FALSE; +} + static void gtk_window_marshal_signal_1 (GtkObject *object, GtkSignalFunc func, @@ -449,7 +482,7 @@ gtk_window_marshal_signal_2 (GtkObject *object, } static void -gtk_window_destroy (GtkObject *object) +gtk_window_finalize (GtkObject *object) { GtkWindow *window; @@ -459,8 +492,7 @@ gtk_window_destroy (GtkObject *object) window = GTK_WINDOW (object); g_free (window->title); - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + GTK_OBJECT_CLASS(parent_class)->finalize (object); } static void @@ -981,8 +1013,7 @@ gtk_real_window_move_resize (GtkWindow *window, gint height) { GtkWidget *widget; - GtkWidget *resize_container; - GSList *resize_widgets; + GtkWidget *resize_container, *child; GSList *resize_containers; GSList *tmp_list; gint return_val; @@ -1006,7 +1037,7 @@ gtk_real_window_move_resize (GtkWindow *window, } gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL); - + resize_containers = NULL; if ((window->auto_shrink && @@ -1035,60 +1066,56 @@ gtk_real_window_move_resize (GtkWindow *window, * for a widget who also has a parent in the resize widgets * list. */ - resize_widgets = gtk_object_get_data (GTK_OBJECT (window), "resize_widgets"); - gtk_object_set_data (GTK_OBJECT (window), "resize_widgets", NULL); + GSList *resize_widgets, *node; - tmp_list = resize_widgets; - while (tmp_list) - { - widget = tmp_list->data; - tmp_list = tmp_list->next; - - /* referencing needed? */ - GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED); - gtk_object_unref (GTK_OBJECT (widget)); - - widget = widget->parent; - - while (widget && - ((widget->allocation.width < widget->requisition.width) || - (widget->allocation.height < widget->requisition.height))) - widget = widget->parent; - - if (widget) - GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED); - } + resize_widgets = GTK_CONTAINER (window)->resize_widgets; + GTK_CONTAINER (window)->resize_widgets = NULL; - tmp_list = resize_widgets; - while (tmp_list) - { - widget = tmp_list->data; - tmp_list = tmp_list->next; + for (node = resize_widgets; node; node = node->next) + { + child = (GtkWidget *)node->data; - resize_container = widget->parent; - while (resize_container && - !GTK_WIDGET_RESIZE_NEEDED (resize_container)) - resize_container = resize_container->parent; - - if (resize_container) - widget = resize_container->parent; - else - widget = NULL; - - while (widget) - { - if (GTK_WIDGET_RESIZE_NEEDED (widget)) - { - GTK_WIDGET_UNSET_FLAGS (resize_container, GTK_RESIZE_NEEDED); - resize_container = widget; - } - widget = widget->parent; - } - - if (resize_container && - !g_slist_find (resize_containers, resize_container)) - resize_containers = g_slist_prepend (resize_containers, resize_container); - } + GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED); + + widget = child->parent; + while (widget && + ((widget->allocation.width < widget->requisition.width) || + (widget->allocation.height < widget->requisition.height))) + widget = widget->parent; + + if (widget) + GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED); + } + + for (node = resize_widgets; node; node = node->next) + { + child = (GtkWidget *)node->data; + + resize_container = child->parent; + while (resize_container && + !GTK_WIDGET_RESIZE_NEEDED (resize_container)) + resize_container = resize_container->parent; + + if (resize_container) + widget = resize_container->parent; + else + widget = NULL; + + while (widget) + { + if (GTK_WIDGET_RESIZE_NEEDED (widget)) + { + GTK_WIDGET_UNSET_FLAGS (resize_container, GTK_RESIZE_NEEDED); + resize_container = widget; + } + widget = widget->parent; + } + + if (resize_container && + !g_slist_find (resize_containers, resize_container)) + resize_containers = g_slist_prepend (resize_containers, + resize_container); + } g_slist_free (resize_widgets); diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h index 755b9340c..30d8509ae 100644 --- a/gtk/gtkwindow.h +++ b/gtk/gtkwindow.h @@ -97,6 +97,8 @@ void gtk_window_remove_accelerator_table (GtkWindow *window, GtkAcceleratorTable *table); void gtk_window_position (GtkWindow *window, GtkWindowPosition position); +gint gtk_window_activate_focus (GtkWindow *window); +gint gtk_window_activate_default (GtkWindow *window); #ifdef __cplusplus diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 835e360c7..e9f72751c 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -29,6 +29,15 @@ destroy_window (GtkWidget *widget, } void +destroy_tooltips (GtkWidget *widget, GtkWindow **window) +{ + GtkTooltips *tt = gtk_object_get_data (GTK_OBJECT (*window), "tooltips"); + gtk_object_unref (GTK_OBJECT (tt)); + + *window = NULL; +} + +void button_window (GtkWidget *widget, GtkWidget *button) { @@ -53,10 +62,10 @@ create_buttons () window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (destroy_window), &window); gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (gtk_true), &window); gtk_window_set_title (GTK_WINDOW (window), "buttons"); @@ -1028,17 +1037,18 @@ create_tooltips () window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (destroy_tooltips), &window); gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (gtk_true), &window); gtk_window_set_title (GTK_WINDOW (window), "tooltips"); gtk_container_border_width (GTK_CONTAINER (window), 0); tooltips=gtk_tooltips_new(); - + gtk_object_set_data (GTK_OBJECT (window), "tooltips", tooltips); + box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); gtk_widget_show (box1); @@ -1439,14 +1449,6 @@ list_remove (GtkWidget *widget, gtk_list_remove_items (GTK_LIST (list), clear_list); - tmp_list = clear_list; - - while (tmp_list) - { - gtk_widget_destroy (GTK_WIDGET (tmp_list->data)); - tmp_list = tmp_list->next; - } - g_list_free (clear_list); } @@ -3829,9 +3831,10 @@ create_test () * Main Window and Exit */ void -do_exit () +do_exit (GtkWidget *widget, GtkWidget *window) { - gtk_exit (0); + gtk_widget_destroy (window); + gtk_main_quit (); } void @@ -3942,7 +3945,8 @@ create_main_window () button = gtk_button_new_with_label ("close"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC(do_exit), NULL); + GTK_SIGNAL_FUNC (do_exit), + window); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); diff --git a/tests/testgtk.c b/tests/testgtk.c index 835e360c7..e9f72751c 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -29,6 +29,15 @@ destroy_window (GtkWidget *widget, } void +destroy_tooltips (GtkWidget *widget, GtkWindow **window) +{ + GtkTooltips *tt = gtk_object_get_data (GTK_OBJECT (*window), "tooltips"); + gtk_object_unref (GTK_OBJECT (tt)); + + *window = NULL; +} + +void button_window (GtkWidget *widget, GtkWidget *button) { @@ -53,10 +62,10 @@ create_buttons () window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (destroy_window), &window); gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (gtk_true), &window); gtk_window_set_title (GTK_WINDOW (window), "buttons"); @@ -1028,17 +1037,18 @@ create_tooltips () window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (destroy_tooltips), &window); gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC(destroy_window), + GTK_SIGNAL_FUNC (gtk_true), &window); gtk_window_set_title (GTK_WINDOW (window), "tooltips"); gtk_container_border_width (GTK_CONTAINER (window), 0); tooltips=gtk_tooltips_new(); - + gtk_object_set_data (GTK_OBJECT (window), "tooltips", tooltips); + box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); gtk_widget_show (box1); @@ -1439,14 +1449,6 @@ list_remove (GtkWidget *widget, gtk_list_remove_items (GTK_LIST (list), clear_list); - tmp_list = clear_list; - - while (tmp_list) - { - gtk_widget_destroy (GTK_WIDGET (tmp_list->data)); - tmp_list = tmp_list->next; - } - g_list_free (clear_list); } @@ -3829,9 +3831,10 @@ create_test () * Main Window and Exit */ void -do_exit () +do_exit (GtkWidget *widget, GtkWidget *window) { - gtk_exit (0); + gtk_widget_destroy (window); + gtk_main_quit (); } void @@ -3942,7 +3945,8 @@ create_main_window () button = gtk_button_new_with_label ("close"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC(do_exit), NULL); + GTK_SIGNAL_FUNC (do_exit), + window); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); |