diff --git a/ChangeLog b/ChangeLog index 55dc375a98..ae818ce58f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Dec 22 16:01:27 2005 Tim Janik + + * gtk/gtkobject.c: derive GtkObject from GUnowned, + so it initially has a floating reference count. + gtk_object_class_init(): installa floating flag handler with + libgobject, so for GtkObjects the flag is stored as GTK_FLOATING + in the ->flags member. + + * tests/floatingtest.c: test floating flag uses. + 2005-12-21 Matthias Clasen * gdk/gdkregion-generic.c: Use the slice allocator diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 55dc375a98..ae818ce58f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,13 @@ +Thu Dec 22 16:01:27 2005 Tim Janik + + * gtk/gtkobject.c: derive GtkObject from GUnowned, + so it initially has a floating reference count. + gtk_object_class_init(): installa floating flag handler with + libgobject, so for GtkObjects the flag is stored as GTK_FLOATING + in the ->flags member. + + * tests/floatingtest.c: test floating flag uses. + 2005-12-21 Matthias Clasen * gdk/gdkregion-generic.c: Use the slice allocator diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c index 953670d408..406e93e5c5 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -96,7 +96,7 @@ gtk_object_get_type (void) NULL, /* value_table */ }; - object_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkObject"), + object_type = g_type_register_static (G_TYPE_UNOWNED, I_("GtkObject"), &object_info, G_TYPE_FLAG_ABSTRACT); } @@ -314,6 +314,29 @@ gtk_object_add_arg_type (const gchar *arg_name, g_object_class_install_property (oclass, arg_id, pspec); } +static guint +gtk_object_floating_flag_handler (GtkObject *object, + gint job) +{ + /* FIXME: remove this whole thing once GTK+ breaks ABI */ + switch (job) + { + guint32 oldvalue; + case +1: /* force floating if possible */ + do + oldvalue = g_atomic_int_get (&object->flags); + while (!g_atomic_int_compare_and_exchange (&object->flags, oldvalue, oldvalue | GTK_FLOATING)); + return oldvalue & GTK_FLOATING; + case -1: /* sink if possible */ + do + oldvalue = g_atomic_int_get (&object->flags); + while (!g_atomic_int_compare_and_exchange (&object->flags, oldvalue, oldvalue & ~(guint32) GTK_FLOATING)); + return oldvalue & GTK_FLOATING; + default: /* check floating */ + return 0 != (g_atomic_int_get (&object->flags) & GTK_FLOATING); + } +} + static void gtk_object_class_init (GtkObjectClass *class) { @@ -321,6 +344,8 @@ gtk_object_class_init (GtkObjectClass *class) parent_class = g_type_class_ref (G_TYPE_OBJECT); + g_object_compat_control (2, gtk_object_floating_flag_handler); + gobject_class->set_property = gtk_object_set_property; gobject_class->get_property = gtk_object_get_property; gobject_class->dispose = gtk_object_dispose; diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index 26c5e11507..2fbea5b44c 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -58,7 +58,7 @@ G_BEGIN_DECLS typedef enum { GTK_IN_DESTRUCTION = 1 << 0, /* Used internally during dispose */ -#ifndef GTK_DISABLE_DEPRECATED +#if !defined (GTK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) GTK_FLOATING = 1 << 1, #endif GTK_RESERVED_1 = 1 << 2, diff --git a/tests/Makefile.am b/tests/Makefile.am index f963b1a6e2..580fe0bda3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,9 +25,11 @@ if USE_X11 testsocket_programs = testsocket testsocket_child endif +TESTS = floatingtest noinst_PROGRAMS = \ autotestfilechooser \ + floatingtest \ simple \ testaccel \ testcairo \ @@ -77,6 +79,7 @@ noinst_PROGRAMS = \ autotestfilechooser_DEPENDENCIES = $(TEST_DEPS) simple_DEPENDENCIES = $(TEST_DEPS) +floatingtest_DEPENDENCIES = $(TEST_DEPS) testicontheme_DEPENDENCIES = $(TEST_DEPS) testiconview_DEPENDENCIES = $(TEST_DEPS) testaccel_DEPENDENCIES = $(TEST_DEPS) @@ -118,7 +121,7 @@ testmerge_DEPENDENCIES = $(TEST_DEPS) testactions_DEPENDENCIES = $(TEST_DEPS) autotestfilechooser_LDADD = $(LDADDS) -simple_LDADD = $(LDADDS) +floatingtest_LDADD = $(LDADDS) testaccel_LDADD = $(LDADDS) testcairo_LDADD = $(LDADDS) testcalendar_LDADD = $(LDADDS) diff --git a/tests/floatingtest.c b/tests/floatingtest.c new file mode 100644 index 0000000000..458acd887b --- /dev/null +++ b/tests/floatingtest.c @@ -0,0 +1,64 @@ +/* floatingtest.c - test floating flag uses + * Copyright (C) 2005 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#undef GTK_DISABLE_DEPRECATED +#include "../gtk/gtk.h" + +static gboolean destroyed = FALSE; +static void destroy (void) { destroyed = TRUE; } + +int +main (int argc, + char *argv[]) +{ + GtkWidget *widget; + gtk_init (&argc, &argv); + + widget = g_object_new (GTK_TYPE_LABEL, NULL); + g_object_connect (widget, "signal::destroy", destroy, NULL, NULL); + + g_assert (GTK_OBJECT_FLOATING (widget)); + g_assert (g_object_is_floating (widget)); + + GTK_OBJECT_UNSET_FLAGS (widget, GTK_FLOATING); + g_assert (!GTK_OBJECT_FLOATING (widget)); + g_assert (!g_object_is_floating (widget)); + + GTK_OBJECT_SET_FLAGS (widget, GTK_FLOATING); + g_assert (GTK_OBJECT_FLOATING (widget)); + g_assert (g_object_is_floating (widget)); + + g_object_ref_sink (widget); + g_assert (!GTK_OBJECT_FLOATING (widget)); + g_assert (!g_object_is_floating (widget)); + + g_object_force_floating (G_OBJECT (widget)); + g_assert (GTK_OBJECT_FLOATING (widget)); + g_assert (g_object_is_floating (widget)); + + g_object_ref (widget); + gtk_object_sink (GTK_OBJECT (widget)); + g_assert (!GTK_OBJECT_FLOATING (widget)); + g_assert (!g_object_is_floating (widget)); + + g_assert (!destroyed); + g_object_unref (widget); + g_assert (destroyed); + + return 0; +}