X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcontainer.c;h=ce16fe4df42e224471754b0886415b08b200e474;hb=3c8e1c92a85b2e41161698f141747ced2c574f32;hp=cd400b3e0267ccc696a0503514f012bfef0f3215;hpb=920e8b434367f9aa8aab306721cc024e66892e2e;p=~andy%2Fgtk diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index cd400b3e0..ce16fe4df 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -12,9 +12,7 @@ * 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. + * License along with this library. If not, see . */ /* @@ -27,6 +25,7 @@ #include "config.h" #include "gtkcontainer.h" +#include "gtkcontainerprivate.h" #include #include @@ -35,6 +34,7 @@ #include #include +#include "gtkadjustment.h" #include "gtkbuildable.h" #include "gtkbuilderprivate.h" #include "gtktypebuiltins.h" @@ -42,11 +42,14 @@ #include "gtkmain.h" #include "gtkmarshalers.h" #include "gtksizerequest.h" +#include "gtksizerequestcacheprivate.h" #include "gtkwidgetprivate.h" #include "gtkwindow.h" +#include "gtkassistant.h" #include "gtkintl.h" -#include "gtktoolbar.h" - +#include "gtkstylecontextprivate.h" +#include "gtkwidgetpath.h" +#include "a11y/gtkcontaineraccessible.h" /** * SECTION:gtkcontainer @@ -72,7 +75,7 @@ * The second type of container can have more than one child; its purpose is to * manage layout. This means that these containers assign * sizes and positions to their children. For example, a #GtkHBox arranges its - * children in a horizontal row, and a #GtkTable arranges the widgets it contains + * children in a horizontal row, and a #GtkGrid arranges the widgets it contains * in a two-dimensional grid. * * @@ -233,12 +236,17 @@ struct _GtkContainerPrivate { GtkWidget *focus_child; + guint resize_handler; + GdkFrameClock *resize_clock; + guint border_width : 16; guint has_focus_chain : 1; - guint need_resize : 1; guint reallocate_redraws : 1; + guint resize_pending : 1; + guint restyle_pending : 1; guint resize_mode : 2; + guint request_mode : 2; }; enum { @@ -267,31 +275,31 @@ static void gtk_container_class_init (GtkContainerClass *klass); static void gtk_container_init (GtkContainer *container); static void gtk_container_destroy (GtkWidget *widget); static void gtk_container_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void gtk_container_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); + guint prop_id, + GValue *value, + GParamSpec *pspec); static void gtk_container_add_unimplemented (GtkContainer *container, - GtkWidget *widget); + GtkWidget *widget); static void gtk_container_remove_unimplemented (GtkContainer *container, - GtkWidget *widget); + GtkWidget *widget); static void gtk_container_real_check_resize (GtkContainer *container); static void gtk_container_compute_expand (GtkWidget *widget, gboolean *hexpand_p, gboolean *vexpand_p); static gboolean gtk_container_focus (GtkWidget *widget, - GtkDirectionType direction); + GtkDirectionType direction); static void gtk_container_real_set_focus_child (GtkContainer *container, - GtkWidget *widget); + GtkWidget *widget); static gboolean gtk_container_focus_move (GtkContainer *container, - GList *children, - GtkDirectionType direction); + GList *children, + GtkDirectionType direction); static void gtk_container_children_callback (GtkWidget *widget, - gpointer client_data); + gpointer client_data); static void gtk_container_show_all (GtkWidget *widget); static gint gtk_container_draw (GtkWidget *widget, cairo_t *cr); @@ -307,9 +315,10 @@ static void gtk_container_adjust_size_allocation (GtkWidget *widget, gint *natural_size, gint *allocated_pos, gint *allocated_size); +static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget); static gchar* gtk_container_child_default_composite_name (GtkContainer *container, - GtkWidget *child); + GtkWidget *child); static GtkWidgetPath * gtk_container_real_get_path_for_child (GtkContainer *container, GtkWidget *child); @@ -317,20 +326,20 @@ static GtkWidgetPath * gtk_container_real_get_path_for_child (GtkContainer *cont /* GtkBuildable */ static void gtk_container_buildable_init (GtkBuildableIface *iface); static void gtk_container_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type); + GtkBuilder *builder, + GObject *child, + const gchar *type); static gboolean gtk_container_buildable_custom_tag_start (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - GMarkupParser *parser, - gpointer *data); + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + GMarkupParser *parser, + gpointer *data); static void gtk_container_buildable_custom_tag_end (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer *data); + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + gpointer *data); /* --- variables --- */ @@ -338,7 +347,6 @@ static const gchar vadjustment_key[] = "gtk-vadjustment"; static guint vadjustment_key_id = 0; static const gchar hadjustment_key[] = "gtk-hadjustment"; static guint hadjustment_key_id = 0; -static GSList *container_resize_queue = NULL; static guint container_signals[LAST_SIGNAL] = { 0 }; static GtkWidgetClass *parent_class = NULL; extern GParamSpecPool *_gtk_widget_child_property_pool; @@ -356,32 +364,32 @@ gtk_container_get_type (void) { const GTypeInfo container_info = { - sizeof (GtkContainerClass), - (GBaseInitFunc) gtk_container_base_class_init, - (GBaseFinalizeFunc) gtk_container_base_class_finalize, - (GClassInitFunc) gtk_container_class_init, - NULL /* class_finalize */, - NULL /* class_data */, - sizeof (GtkContainer), - 0 /* n_preallocs */, - (GInstanceInitFunc) gtk_container_init, - NULL, /* value_table */ + sizeof (GtkContainerClass), + (GBaseInitFunc) gtk_container_base_class_init, + (GBaseFinalizeFunc) gtk_container_base_class_finalize, + (GClassInitFunc) gtk_container_class_init, + NULL /* class_finalize */, + NULL /* class_data */, + sizeof (GtkContainer), + 0 /* n_preallocs */, + (GInstanceInitFunc) gtk_container_init, + NULL, /* value_table */ }; const GInterfaceInfo buildable_info = { - (GInterfaceInitFunc) gtk_container_buildable_init, - NULL, - NULL + (GInterfaceInitFunc) gtk_container_buildable_init, + NULL, + NULL }; container_type = - g_type_register_static (GTK_TYPE_WIDGET, I_("GtkContainer"), - &container_info, G_TYPE_FLAG_ABSTRACT); + g_type_register_static (GTK_TYPE_WIDGET, I_("GtkContainer"), + &container_info, G_TYPE_FLAG_ABSTRACT); g_type_add_interface_static (container_type, - GTK_TYPE_BUILDABLE, - &buildable_info); + GTK_TYPE_BUILDABLE, + &buildable_info); } @@ -437,6 +445,7 @@ gtk_container_class_init (GtkContainerClass *class) widget_class->adjust_size_request = gtk_container_adjust_size_request; widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation; + widget_class->get_request_mode = gtk_container_get_request_mode; class->add = gtk_container_add_unimplemented; class->remove = gtk_container_remove_unimplemented; @@ -460,9 +469,9 @@ gtk_container_class_init (GtkContainerClass *class) g_param_spec_uint ("border-width", P_("Border width"), P_("The width of the empty border outside the containers children"), - 0, - 65535, - 0, + 0, + 65535, + 0, GTK_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_CHILD, @@ -470,44 +479,46 @@ gtk_container_class_init (GtkContainerClass *class) P_("Child"), P_("Can be used to add a new child to the container"), GTK_TYPE_WIDGET, - GTK_PARAM_WRITABLE)); + GTK_PARAM_WRITABLE)); container_signals[ADD] = g_signal_new (I_("add"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkContainerClass, add), - NULL, NULL, - _gtk_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkContainerClass, add), + NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_WIDGET); container_signals[REMOVE] = g_signal_new (I_("remove"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkContainerClass, remove), - NULL, NULL, - _gtk_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkContainerClass, remove), + NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_WIDGET); container_signals[CHECK_RESIZE] = g_signal_new (I_("check-resize"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkContainerClass, check_resize), - NULL, NULL, - _gtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkContainerClass, check_resize), + NULL, NULL, + _gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); container_signals[SET_FOCUS_CHILD] = g_signal_new (I_("set-focus-child"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkContainerClass, set_focus_child), - NULL, NULL, - _gtk_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - GTK_TYPE_WIDGET); + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkContainerClass, set_focus_child), + NULL, NULL, + _gtk_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_WIDGET); g_type_class_add_private (class, sizeof (GtkContainerPrivate)); + + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_CONTAINER_ACCESSIBLE); } static void @@ -521,9 +532,9 @@ gtk_container_buildable_init (GtkBuildableIface *iface) static void gtk_container_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type) + GtkBuilder *builder, + GObject *child, + const gchar *type) { if (type) { @@ -536,18 +547,18 @@ gtk_container_buildable_add_child (GtkBuildable *buildable, } else g_warning ("Cannot add an object of type %s to a container of type %s", - g_type_name (G_OBJECT_TYPE (child)), g_type_name (G_OBJECT_TYPE (buildable))); + g_type_name (G_OBJECT_TYPE (child)), g_type_name (G_OBJECT_TYPE (buildable))); } static void gtk_container_buildable_set_child_property (GtkContainer *container, - GtkBuilder *builder, - GtkWidget *child, - gchar *name, - const gchar *value) + GtkBuilder *builder, + GtkWidget *child, + gchar *name, + const gchar *value) { GParamSpec *pspec; - GValue gvalue = { 0, }; + GValue gvalue = G_VALUE_INIT; GError *error = NULL; pspec = gtk_container_class_find_child_property @@ -555,18 +566,18 @@ gtk_container_buildable_set_child_property (GtkContainer *container, if (!pspec) { g_warning ("%s does not have a property called %s", - g_type_name (G_OBJECT_TYPE (container)), name); + g_type_name (G_OBJECT_TYPE (container)), name); return; } if (!gtk_builder_value_from_string (builder, pspec, value, &gvalue, &error)) { g_warning ("Could not read property %s:%s with value %s of type %s: %s", - g_type_name (G_OBJECT_TYPE (container)), - name, - value, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - error->message); + g_type_name (G_OBJECT_TYPE (container)), + name, + value, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + error->message); g_error_free (error); return; } @@ -579,18 +590,19 @@ typedef struct { GtkBuilder *builder; GtkContainer *container; GtkWidget *child; + GString *string; gchar *child_prop_name; gchar *context; - gboolean translatable; + gboolean translatable; } PackingPropertiesData; static void attributes_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **names, - const gchar **values, - gpointer user_data, - GError **error) + const gchar *element_name, + const gchar **names, + const gchar **values, + gpointer user_data, + GError **error) { PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data; guint i; @@ -598,22 +610,22 @@ attributes_start_element (GMarkupParseContext *context, if (strcmp (element_name, "property") == 0) { for (i = 0; names[i]; i++) - if (strcmp (names[i], "name") == 0) - parser_data->child_prop_name = g_strdup (values[i]); - else if (strcmp (names[i], "translatable") == 0) - { - if (!_gtk_builder_boolean_from_string (values[1], - &parser_data->translatable, - error)) - return; - } - else if (strcmp (names[i], "comments") == 0) - ; /* for translators */ - else if (strcmp (names[i], "context") == 0) - parser_data->context = g_strdup (values[1]); - else - g_warning ("Unsupported attribute for GtkContainer Child " - "property: %s\n", names[i]); + if (strcmp (names[i], "name") == 0) + parser_data->child_prop_name = g_strdup (values[i]); + else if (strcmp (names[i], "translatable") == 0) + { + if (!_gtk_builder_boolean_from_string (values[1], + &parser_data->translatable, + error)) + return; + } + else if (strcmp (names[i], "comments") == 0) + ; /* for translators */ + else if (strcmp (names[i], "context") == 0) + parser_data->context = g_strdup (values[1]); + else + g_warning ("Unsupported attribute for GtkContainer Child " + "property: %s\n", names[i]); } else if (strcmp (element_name, "packing") == 0) return; @@ -623,40 +635,50 @@ attributes_start_element (GMarkupParseContext *context, static void attributes_text_element (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) { PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data; - gchar* value; - if (!parser_data->child_prop_name) - return; + if (parser_data->child_prop_name) + g_string_append_len (parser_data->string, text, text_len); +} + +static void +attributes_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data; - if (parser_data->translatable && text_len) + /* translate the string */ + if (parser_data->string->len && parser_data->translatable) { + gchar *translated; const gchar* domain; + domain = gtk_builder_get_translation_domain (parser_data->builder); - value = _gtk_builder_parser_translate (domain, - parser_data->context, - text); - } - else - { - value = g_strdup (text); + translated = _gtk_builder_parser_translate (domain, + parser_data->context, + parser_data->string->str); + g_string_set_size (parser_data->string, 0); + g_string_append (parser_data->string, translated); } - gtk_container_buildable_set_child_property (parser_data->container, - parser_data->builder, - parser_data->child, - parser_data->child_prop_name, - value); + if (parser_data->child_prop_name) + gtk_container_buildable_set_child_property (parser_data->container, + parser_data->builder, + parser_data->child, + parser_data->child_prop_name, + parser_data->string->str); + g_string_set_size (parser_data->string, 0); g_free (parser_data->child_prop_name); g_free (parser_data->context); - g_free (value); parser_data->child_prop_name = NULL; parser_data->context = NULL; parser_data->translatable = FALSE; @@ -665,27 +687,28 @@ attributes_text_element (GMarkupParseContext *context, static const GMarkupParser attributes_parser = { attributes_start_element, - NULL, + attributes_end_element, attributes_text_element, }; static gboolean gtk_container_buildable_custom_tag_start (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - GMarkupParser *parser, - gpointer *data) + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + GMarkupParser *parser, + gpointer *data) { PackingPropertiesData *parser_data; if (parent_buildable_iface->custom_tag_start (buildable, builder, child, - tagname, parser, data)) + tagname, parser, data)) return TRUE; if (child && strcmp (tagname, "packing") == 0) { parser_data = g_slice_new0 (PackingPropertiesData); + parser_data->string = g_string_new (""); parser_data->builder = builder; parser_data->container = GTK_CONTAINER (buildable); parser_data->child = GTK_WIDGET (child); @@ -701,22 +724,22 @@ gtk_container_buildable_custom_tag_start (GtkBuildable *buildable, static void gtk_container_buildable_custom_tag_end (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer *data) + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + gpointer *data) { if (strcmp (tagname, "packing") == 0) { - g_slice_free (PackingPropertiesData, (gpointer)data); + PackingPropertiesData *parser_data = (PackingPropertiesData*)data; + g_string_free (parser_data->string, TRUE); + g_slice_free (PackingPropertiesData, parser_data); return; - } if (parent_buildable_iface->custom_tag_end) parent_buildable_iface->custom_tag_end (buildable, builder, - child, tagname, data); - + child, tagname, data); } /** @@ -749,11 +772,73 @@ gtk_container_child_type (GtkContainer *container) } /* --- GtkContainer child property mechanism --- */ + +/** + * gtk_container_child_notify: + * @container: the #GtkContainer + * @child: the child widget + * @child_property: the name of a child property installed on + * the class of @container + * + * Emits a #GtkWidget::child-notify signal for the + * child property + * @child_property on widget. + * + * This is an analogue of g_object_notify() for child properties. + * + * Also see gtk_widget_child_notify(). + * + * Since: 3.2 + */ +void +gtk_container_child_notify (GtkContainer *container, + GtkWidget *child, + const gchar *child_property) +{ + GObject *obj; + GParamSpec *pspec; + + g_return_if_fail (GTK_IS_CONTAINER (container)); + g_return_if_fail (GTK_IS_WIDGET (child)); + g_return_if_fail (child_property != NULL); + + obj = G_OBJECT (child); + + if (obj->ref_count == 0) + return; + + g_object_ref (obj); + + pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool, + child_property, + G_OBJECT_TYPE (container), + TRUE); + + if (pspec == NULL) + { + g_warning ("%s: container class `%s' has no child property named `%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (container), + child_property); + } + else + { + GObjectNotifyQueue *nqueue; + + nqueue = g_object_notify_queue_freeze (obj, _gtk_widget_child_property_notify_context); + + g_object_notify_queue_add (obj, nqueue, pspec); + g_object_notify_queue_thaw (obj, nqueue); + } + + g_object_unref (obj); +} + static inline void container_get_child_property (GtkContainer *container, - GtkWidget *child, - GParamSpec *pspec, - GValue *value) + GtkWidget *child, + GParamSpec *pspec, + GValue *value) { GtkContainerClass *class = g_type_class_peek (pspec->owner_type); @@ -762,30 +847,30 @@ container_get_child_property (GtkContainer *container, static inline void container_set_child_property (GtkContainer *container, - GtkWidget *child, - GParamSpec *pspec, - const GValue *value, - GObjectNotifyQueue *nqueue) + GtkWidget *child, + GParamSpec *pspec, + const GValue *value, + GObjectNotifyQueue *nqueue) { - GValue tmp_value = { 0, }; + GValue tmp_value = G_VALUE_INIT; GtkContainerClass *class = g_type_class_peek (pspec->owner_type); /* provide a copy to work from, convert (if necessary) and validate */ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); if (!g_value_transform (value, &tmp_value)) g_warning ("unable to set child property `%s' of type `%s' from value of type `%s'", - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - G_VALUE_TYPE_NAME (value)); + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + G_VALUE_TYPE_NAME (value)); else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION)) { gchar *contents = g_strdup_value_contents (value); g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'", - contents, - G_VALUE_TYPE_NAME (value), - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); + contents, + G_VALUE_TYPE_NAME (value), + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); g_free (contents); } else @@ -808,15 +893,14 @@ container_set_child_property (GtkContainer *container, **/ void gtk_container_child_get_valist (GtkContainer *container, - GtkWidget *child, - const gchar *first_property_name, - va_list var_args) + GtkWidget *child, + const gchar *first_property_name, + va_list var_args) { const gchar *name; g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); g_object_ref (container); g_object_ref (child); @@ -824,40 +908,40 @@ gtk_container_child_get_valist (GtkContainer *container, name = first_property_name; while (name) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; GParamSpec *pspec; gchar *error; pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool, - name, - G_OBJECT_TYPE (container), - TRUE); + name, + G_OBJECT_TYPE (container), + TRUE); if (!pspec) - { - g_warning ("%s: container class `%s' has no child property named `%s'", - G_STRLOC, - G_OBJECT_TYPE_NAME (container), - name); - break; - } + { + g_warning ("%s: container class `%s' has no child property named `%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (container), + name); + break; + } if (!(pspec->flags & G_PARAM_READABLE)) - { - g_warning ("%s: child property `%s' of container class `%s' is not readable", - G_STRLOC, - pspec->name, - G_OBJECT_TYPE_NAME (container)); - break; - } + { + g_warning ("%s: child property `%s' of container class `%s' is not readable", + G_STRLOC, + pspec->name, + G_OBJECT_TYPE_NAME (container)); + break; + } g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); container_get_child_property (container, child, pspec, &value); G_VALUE_LCOPY (&value, var_args, 0, &error); if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - break; - } + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + g_value_unset (&value); + break; + } g_value_unset (&value); name = va_arg (var_args, gchar*); } @@ -877,64 +961,63 @@ gtk_container_child_get_valist (GtkContainer *container, **/ void gtk_container_child_get_property (GtkContainer *container, - GtkWidget *child, - const gchar *property_name, - GValue *value) + GtkWidget *child, + const gchar *property_name, + GValue *value) { GParamSpec *pspec; g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); g_object_ref (container); g_object_ref (child); pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool, property_name, - G_OBJECT_TYPE (container), TRUE); + G_OBJECT_TYPE (container), TRUE); if (!pspec) g_warning ("%s: container class `%s' has no child property named `%s'", - G_STRLOC, - G_OBJECT_TYPE_NAME (container), - property_name); + G_STRLOC, + G_OBJECT_TYPE_NAME (container), + property_name); else if (!(pspec->flags & G_PARAM_READABLE)) g_warning ("%s: child property `%s' of container class `%s' is not readable", - G_STRLOC, - pspec->name, - G_OBJECT_TYPE_NAME (container)); + G_STRLOC, + pspec->name, + G_OBJECT_TYPE_NAME (container)); else { - GValue *prop_value, tmp_value = { 0, }; + GValue *prop_value, tmp_value = G_VALUE_INIT; /* auto-conversion of the callers value type */ if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) - { - g_value_reset (value); - prop_value = value; - } + { + g_value_reset (value); + prop_value = value; + } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value))) - { - g_warning ("can't retrieve child property `%s' of type `%s' as value of type `%s'", - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - G_VALUE_TYPE_NAME (value)); - g_object_unref (child); - g_object_unref (container); - return; - } + { + g_warning ("can't retrieve child property `%s' of type `%s' as value of type `%s'", + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + G_VALUE_TYPE_NAME (value)); + g_object_unref (child); + g_object_unref (container); + return; + } else - { - g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - prop_value = &tmp_value; - } + { + g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + prop_value = &tmp_value; + } container_get_child_property (container, child, pspec, prop_value); if (prop_value != value) - { - g_value_transform (prop_value, value); - g_value_unset (&tmp_value); - } + { + g_value_transform (prop_value, value); + g_value_unset (&tmp_value); + } } g_object_unref (child); g_object_unref (container); @@ -952,16 +1035,15 @@ gtk_container_child_get_property (GtkContainer *container, **/ void gtk_container_child_set_valist (GtkContainer *container, - GtkWidget *child, - const gchar *first_property_name, - va_list var_args) + GtkWidget *child, + const gchar *first_property_name, + va_list var_args) { GObjectNotifyQueue *nqueue; const gchar *name; g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); g_object_ref (container); g_object_ref (child); @@ -970,40 +1052,41 @@ gtk_container_child_set_valist (GtkContainer *container, name = first_property_name; while (name) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; gchar *error = NULL; GParamSpec *pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool, - name, - G_OBJECT_TYPE (container), - TRUE); + name, + G_OBJECT_TYPE (container), + TRUE); if (!pspec) - { - g_warning ("%s: container class `%s' has no child property named `%s'", - G_STRLOC, - G_OBJECT_TYPE_NAME (container), - name); - break; - } + { + g_warning ("%s: container class `%s' has no child property named `%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (container), + name); + break; + } if (!(pspec->flags & G_PARAM_WRITABLE)) - { - g_warning ("%s: child property `%s' of container class `%s' is not writable", - G_STRLOC, - pspec->name, - G_OBJECT_TYPE_NAME (container)); - break; - } - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - G_VALUE_COLLECT (&value, var_args, 0, &error); + { + g_warning ("%s: child property `%s' of container class `%s' is not writable", + G_STRLOC, + pspec->name, + G_OBJECT_TYPE_NAME (container)); + break; + } + + G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec), + var_args, 0, &error); if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - - /* we purposely leak the value here, it might not be - * in a sane state if an error condition occoured - */ - break; - } + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a sane state if an error condition occoured + */ + break; + } container_set_child_property (container, child, pspec, &value, nqueue); g_value_unset (&value); name = va_arg (var_args, gchar*); @@ -1025,16 +1108,15 @@ gtk_container_child_set_valist (GtkContainer *container, **/ void gtk_container_child_set_property (GtkContainer *container, - GtkWidget *child, - const gchar *property_name, - const GValue *value) + GtkWidget *child, + const gchar *property_name, + const GValue *value) { GObjectNotifyQueue *nqueue; GParamSpec *pspec; g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); @@ -1043,17 +1125,17 @@ gtk_container_child_set_property (GtkContainer *container, nqueue = g_object_notify_queue_freeze (G_OBJECT (child), _gtk_widget_child_property_notify_context); pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool, property_name, - G_OBJECT_TYPE (container), TRUE); + G_OBJECT_TYPE (container), TRUE); if (!pspec) g_warning ("%s: container class `%s' has no child property named `%s'", - G_STRLOC, - G_OBJECT_TYPE_NAME (container), - property_name); + G_STRLOC, + G_OBJECT_TYPE_NAME (container), + property_name); else if (!(pspec->flags & G_PARAM_WRITABLE)) g_warning ("%s: child property `%s' of container class `%s' is not writable", - G_STRLOC, - pspec->name, - G_OBJECT_TYPE_NAME (container)); + G_STRLOC, + pspec->name, + G_OBJECT_TYPE_NAME (container)); else { container_set_child_property (container, child, pspec, value, nqueue); @@ -1068,17 +1150,17 @@ gtk_container_child_set_property (GtkContainer *container, * @container: a #GtkContainer * @widget: a widget to be placed inside @container * @first_prop_name: the name of the first child property to set - * @Varargs: a %NULL-terminated list of property names and values, starting - * with @first_prop_name + * @...: a %NULL-terminated list of property names and values, starting + * with @first_prop_name * * Adds @widget to @container, setting child properties at the same time. * See gtk_container_add() and gtk_container_child_set() for more details. - **/ + */ void gtk_container_add_with_properties (GtkContainer *container, - GtkWidget *widget, - const gchar *first_prop_name, - ...) + GtkWidget *widget, + const gchar *first_prop_name, + ...) { g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -1108,23 +1190,19 @@ gtk_container_add_with_properties (GtkContainer *container, * @container: a #GtkContainer * @child: a widget which is a child of @container * @first_prop_name: the name of the first property to set - * @Varargs: a %NULL-terminated list of property names and values, starting - * with @first_prop_name + * @...: a %NULL-terminated list of property names and values, starting + * with @first_prop_name * * Sets one or more child properties for @child and @container. - **/ + */ void gtk_container_child_set (GtkContainer *container, - GtkWidget *child, - const gchar *first_prop_name, - ...) + GtkWidget *child, + const gchar *first_prop_name, + ...) { va_list var_args; - g_return_if_fail (GTK_IS_CONTAINER (container)); - g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); - va_start (var_args, first_prop_name); gtk_container_child_set_valist (container, child, first_prop_name, var_args); va_end (var_args); @@ -1135,23 +1213,19 @@ gtk_container_child_set (GtkContainer *container, * @container: a #GtkContainer * @child: a widget which is a child of @container * @first_prop_name: the name of the first property to get - * @Varargs: return location for the first property, followed + * @...: return location for the first property, followed * optionally by more name/return location pairs, followed by %NULL * * Gets the values of one or more child properties for @child and @container. - **/ + */ void gtk_container_child_get (GtkContainer *container, - GtkWidget *child, - const gchar *first_prop_name, - ...) + GtkWidget *child, + const gchar *first_prop_name, + ...) { va_list var_args; - g_return_if_fail (GTK_IS_CONTAINER (container)); - g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); - va_start (var_args, first_prop_name); gtk_container_child_get_valist (container, child, first_prop_name, var_args); va_end (var_args); @@ -1167,8 +1241,8 @@ gtk_container_child_get (GtkContainer *container, **/ void gtk_container_class_install_child_property (GtkContainerClass *cclass, - guint property_id, - GParamSpec *pspec) + guint property_id, + GParamSpec *pspec) { g_return_if_fail (GTK_IS_CONTAINER_CLASS (cclass)); g_return_if_fail (G_IS_PARAM_SPEC (pspec)); @@ -1184,8 +1258,8 @@ gtk_container_class_install_child_property (GtkContainerClass *cclass, if (g_param_spec_pool_lookup (_gtk_widget_child_property_pool, pspec->name, G_OBJECT_CLASS_TYPE (cclass), FALSE)) { g_warning (G_STRLOC ": class `%s' already contains a child property named `%s'", - G_OBJECT_CLASS_NAME (cclass), - pspec->name); + G_OBJECT_CLASS_NAME (cclass), + pspec->name); return; } g_param_spec_ref (pspec); @@ -1196,38 +1270,41 @@ gtk_container_class_install_child_property (GtkContainerClass *cclass, /** * gtk_container_class_find_child_property: - * @cclass: a #GtkContainerClass + * @cclass: (type GtkContainerClass): a #GtkContainerClass * @property_name: the name of the child property to find - * @returns: (allow-none): the #GParamSpec of the child property or %NULL if @class has no - * child property with that name. * * Finds a child property of a container class by name. + * + * Returns: (transfer none): the #GParamSpec of the child property + * or %NULL if @class has no child property with that name. */ GParamSpec* gtk_container_class_find_child_property (GObjectClass *cclass, - const gchar *property_name) + const gchar *property_name) { g_return_val_if_fail (GTK_IS_CONTAINER_CLASS (cclass), NULL); g_return_val_if_fail (property_name != NULL, NULL); return g_param_spec_pool_lookup (_gtk_widget_child_property_pool, - property_name, - G_OBJECT_CLASS_TYPE (cclass), - TRUE); + property_name, + G_OBJECT_CLASS_TYPE (cclass), + TRUE); } /** * gtk_container_class_list_child_properties: - * @cclass: a #GtkContainerClass + * @cclass: (type GtkContainerClass): a #GtkContainerClass * @n_properties: location to return the number of child properties found - * @returns: a newly allocated %NULL-terminated array of #GParamSpec*. - * The array must be freed with g_free(). * * Returns all child properties of a container class. + * + * Returns: (array length=n_properties) (transfer container): + * a newly allocated %NULL-terminated array of #GParamSpec*. + * The array must be freed with g_free(). */ GParamSpec** gtk_container_class_list_child_properties (GObjectClass *cclass, - guint *n_properties) + guint *n_properties) { GParamSpec **pspecs; guint n; @@ -1235,8 +1312,8 @@ gtk_container_class_list_child_properties (GObjectClass *cclass, g_return_val_if_fail (GTK_IS_CONTAINER_CLASS (cclass), NULL); pspecs = g_param_spec_pool_list (_gtk_widget_child_property_pool, - G_OBJECT_CLASS_TYPE (cclass), - &n); + G_OBJECT_CLASS_TYPE (cclass), + &n); if (n_properties) *n_properties = n; @@ -1245,14 +1322,14 @@ gtk_container_class_list_child_properties (GObjectClass *cclass, static void gtk_container_add_unimplemented (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { g_warning ("GtkContainerClass::add not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (container))); } static void gtk_container_remove_unimplemented (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { g_warning ("GtkContainerClass::remove not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (container))); } @@ -1269,7 +1346,6 @@ gtk_container_init (GtkContainer *container) priv->focus_child = NULL; priv->border_width = 0; - priv->need_resize = FALSE; priv->resize_mode = GTK_RESIZE_PARENT; priv->reallocate_redraws = FALSE; } @@ -1280,9 +1356,12 @@ gtk_container_destroy (GtkWidget *widget) GtkContainer *container = GTK_CONTAINER (widget); GtkContainerPrivate *priv = container->priv; - if (_gtk_widget_get_resize_pending (GTK_WIDGET (container))) + if (priv->resize_pending) _gtk_container_dequeue_resize_handler (container); + if (priv->restyle_pending) + priv->restyle_pending = FALSE; + if (priv->focus_child) { g_object_unref (priv->focus_child); @@ -1302,9 +1381,9 @@ gtk_container_destroy (GtkWidget *widget) static void gtk_container_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkContainer *container = GTK_CONTAINER (object); @@ -1327,9 +1406,9 @@ gtk_container_set_property (GObject *object, static void gtk_container_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GtkContainer *container = GTK_CONTAINER (object); GtkContainerPrivate *priv = container->priv; @@ -1367,7 +1446,7 @@ gtk_container_get_property (GObject *object, **/ void gtk_container_set_border_width (GtkContainer *container, - guint border_width) + guint border_width) { GtkContainerPrivate *priv; @@ -1381,7 +1460,7 @@ gtk_container_set_border_width (GtkContainer *container, g_object_notify (G_OBJECT (container), "border-width"); if (gtk_widget_get_realized (GTK_WIDGET (container))) - gtk_widget_queue_resize (GTK_WIDGET (container)); + gtk_widget_queue_resize (GTK_WIDGET (container)); } } @@ -1409,16 +1488,16 @@ gtk_container_get_border_width (GtkContainer *container) * * Adds @widget to @container. Typically used for simple containers * such as #GtkWindow, #GtkFrame, or #GtkButton; for more complicated - * layout containers such as #GtkBox or #GtkTable, this function will + * layout containers such as #GtkBox or #GtkGrid, this function will * pick default packing parameters that may not be correct. So * consider functions such as gtk_box_pack_start() and - * gtk_table_attach() as an alternative to gtk_container_add() in + * gtk_grid_attach() as an alternative to gtk_container_add() in * those cases. A widget may be added to only one container at a time; * you can't place the same widget inside two different containers. **/ void gtk_container_add (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { GtkWidget *parent; @@ -1458,11 +1537,11 @@ gtk_container_add (GtkContainer *container, **/ void gtk_container_remove (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container)); + g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container) || GTK_IS_ASSISTANT (container)); g_signal_emit (container, container_signals[REMOVE], 0, widget); } @@ -1471,10 +1550,9 @@ void _gtk_container_dequeue_resize_handler (GtkContainer *container) { g_return_if_fail (GTK_IS_CONTAINER (container)); - g_return_if_fail (_gtk_widget_get_resize_pending (GTK_WIDGET (container))); + g_return_if_fail (container->priv->resize_pending); - container_resize_queue = g_slist_remove (container_resize_queue, container); - _gtk_widget_set_resize_pending (GTK_WIDGET (container), FALSE); + container->priv->resize_pending = FALSE; } /** @@ -1490,7 +1568,7 @@ _gtk_container_dequeue_resize_handler (GtkContainer *container) **/ void gtk_container_set_resize_mode (GtkContainer *container, - GtkResizeMode resize_mode) + GtkResizeMode resize_mode) { GtkContainerPrivate *priv; @@ -1543,124 +1621,173 @@ gtk_container_get_resize_mode (GtkContainer *container) **/ void gtk_container_set_reallocate_redraws (GtkContainer *container, - gboolean needs_redraws) + gboolean needs_redraws) { g_return_if_fail (GTK_IS_CONTAINER (container)); container->priv->reallocate_redraws = needs_redraws ? TRUE : FALSE; } -static GtkContainer* -gtk_container_get_resize_container (GtkContainer *container) -{ - GtkWidget *parent; - GtkWidget *widget = GTK_WIDGET (container); - - while ((parent = gtk_widget_get_parent (widget))) +static void +gtk_container_idle_sizer (GdkFrameClock *clock, + GtkContainer *container) +{ + /* We validate the style contexts in a single loop before even trying + * to handle resizes instead of doing validations inline. + * This is mostly necessary for compatibility reasons with old code, + * because both style_updated and size_allocate functions often change + * styles and so could cause infinite loops in this function. + * + * It's important to note that even an invalid style context returns + * sane values. So the result of an invalid style context will never be + * a program crash, but only a wrong layout or rendering. + */ + if (container->priv->restyle_pending) { - widget = parent; - if (GTK_IS_RESIZE_CONTAINER (widget)) - break; - } + GtkBitmask *empty; + gint64 current_time; - return GTK_IS_RESIZE_CONTAINER (widget) ? (GtkContainer*) widget : NULL; -} + empty = _gtk_bitmask_new (); + current_time = g_get_monotonic_time (); + + container->priv->restyle_pending = FALSE; + _gtk_style_context_validate (gtk_widget_get_style_context (GTK_WIDGET (container)), + current_time, + 0, + empty); + + _gtk_bitmask_free (empty); + } -static gboolean -gtk_container_idle_sizer (gpointer data) -{ /* we may be invoked with a container_resize_queue of NULL, because * queue_resize could have been adding an extra idle function while * the queue still got processed. we better just ignore such case * than trying to explicitely work around them with some extra flags, * since it doesn't cause any actual harm. */ - while (container_resize_queue) + if (container->priv->resize_pending) { - GSList *slist; - GtkWidget *widget; - - slist = container_resize_queue; - container_resize_queue = slist->next; - widget = slist->data; - g_slist_free_1 (slist); + container->priv->resize_pending = FALSE; + gtk_container_check_resize (container); + } - _gtk_widget_set_resize_pending (widget, FALSE); - gtk_container_check_resize (GTK_CONTAINER (widget)); + if (!container->priv->restyle_pending && !container->priv->resize_pending) + { + _gtk_container_stop_idle_sizer (container); + } + else + { + gdk_frame_clock_request_phase (clock, + GDK_FRAME_CLOCK_PHASE_LAYOUT); } +} - gdk_window_process_all_updates (); +static void +gtk_container_start_idle_sizer (GtkContainer *container) +{ + GdkFrameClock *clock; - return FALSE; + if (container->priv->resize_handler != 0) + return; + + clock = gtk_widget_get_frame_clock (GTK_WIDGET (container)); + if (clock == NULL) + return; + + container->priv->resize_clock = clock; + container->priv->resize_handler = g_signal_connect (clock, "layout", + G_CALLBACK (gtk_container_idle_sizer), container); + gdk_frame_clock_request_phase (clock, + GDK_FRAME_CLOCK_PHASE_LAYOUT); +} + +void +_gtk_container_stop_idle_sizer (GtkContainer *container) +{ + if (container->priv->resize_handler == 0) + return; + + g_signal_handler_disconnect (container->priv->resize_clock, + container->priv->resize_handler); + container->priv->resize_handler = 0; + container->priv->resize_clock = NULL; +} + +static void +gtk_container_queue_resize_handler (GtkContainer *container) +{ + GtkWidget *widget; + + g_return_if_fail (GTK_IS_RESIZE_CONTAINER (container)); + + widget = GTK_WIDGET (container); + + if (gtk_widget_get_visible (widget) && + (gtk_widget_is_toplevel (widget) || + gtk_widget_get_realized (widget))) + { + switch (container->priv->resize_mode) + { + case GTK_RESIZE_QUEUE: + if (!container->priv->resize_pending) + { + container->priv->resize_pending = TRUE; + gtk_container_start_idle_sizer (container); + } + break; + + case GTK_RESIZE_IMMEDIATE: + gtk_container_check_resize (container); + break; + + case GTK_RESIZE_PARENT: + default: + g_assert_not_reached (); + break; + } + } } static void _gtk_container_queue_resize_internal (GtkContainer *container, - gboolean invalidate_only) + gboolean invalidate_only) { - GtkContainerPrivate *priv; - GtkContainer *resize_container; - GtkWidget *parent; GtkWidget *widget; g_return_if_fail (GTK_IS_CONTAINER (container)); - priv = container->priv; widget = GTK_WIDGET (container); - resize_container = gtk_container_get_resize_container (container); - - while (TRUE) + do { _gtk_widget_set_alloc_needed (widget, TRUE); - _gtk_widget_set_width_request_needed (widget, TRUE); - _gtk_widget_set_height_request_needed (widget, TRUE); - - if ((resize_container && widget == GTK_WIDGET (resize_container)) || - !(parent = gtk_widget_get_parent (widget))) - break; - - widget = parent; - } - - if (resize_container && !invalidate_only) - { - if (gtk_widget_get_visible (GTK_WIDGET (resize_container)) && - (gtk_widget_is_toplevel (GTK_WIDGET (resize_container)) || - gtk_widget_get_realized (GTK_WIDGET (resize_container)))) - { - switch (resize_container->priv->resize_mode) - { - case GTK_RESIZE_QUEUE: - if (!_gtk_widget_get_resize_pending (GTK_WIDGET (resize_container))) - { - _gtk_widget_set_resize_pending (GTK_WIDGET (resize_container), TRUE); - if (container_resize_queue == NULL) - gdk_threads_add_idle_full (GTK_PRIORITY_RESIZE, - gtk_container_idle_sizer, - NULL, NULL); - container_resize_queue = g_slist_prepend (container_resize_queue, resize_container); - } - break; - - case GTK_RESIZE_IMMEDIATE: - gtk_container_check_resize (resize_container); - break; - - case GTK_RESIZE_PARENT: - g_assert_not_reached (); - break; - } - } - else - { - /* we need to let hidden resize containers know that something - * changed while they where hidden (currently only evaluated by - * toplevels). - */ - resize_container->priv->need_resize = TRUE; - } + _gtk_size_request_cache_clear (_gtk_widget_peek_request_cache (widget)); + + if (GTK_IS_RESIZE_CONTAINER (widget)) + break; + + widget = gtk_widget_get_parent (widget); } + while (widget); + + if (widget && !invalidate_only) + gtk_container_queue_resize_handler (GTK_CONTAINER (widget)); +} + +void +_gtk_container_queue_restyle (GtkContainer *container) +{ + GtkContainerPrivate *priv; + + g_return_if_fail (GTK_CONTAINER (container)); + + priv = container->priv; + + if (priv->restyle_pending) + return; + + gtk_container_start_idle_sizer (container); + priv->restyle_pending = TRUE; } /** @@ -1693,6 +1820,13 @@ _gtk_container_resize_invalidate (GtkContainer *container) _gtk_container_queue_resize_internal (container, TRUE); } +void +_gtk_container_maybe_start_idle_sizer (GtkContainer *container) +{ + if (container->priv->restyle_pending || container->priv->resize_pending) + gtk_container_start_idle_sizer (container); +} + void gtk_container_check_resize (GtkContainer *container) { @@ -1721,7 +1855,7 @@ gtk_container_real_check_resize (GtkContainer *container) gtk_widget_set_allocation (widget, &allocation); } else - gtk_widget_queue_resize (widget); + gtk_widget_queue_resize (widget); } else { @@ -1796,32 +1930,11 @@ gtk_container_adjust_size_allocation (GtkWidget *widget, container = GTK_CONTAINER (widget); - if (!GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width) + if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width) { - parent_class->adjust_size_allocation (widget, orientation, - minimum_size, natural_size, allocated_pos, - allocated_size); - return; - } - - border_width = container->priv->border_width; - - *allocated_size -= border_width * 2; - - /* If we get a pathological too-small allocation to hold - * even the border width, leave all allocation to the actual - * widget, and leave x,y unchanged. (GtkWidget's min size is - * 1x1 if you're wondering why <1 and not <0) - * - * As long as we have space, set x,y properly. - */ + border_width = container->priv->border_width; - if (*allocated_size < 1) - { - *allocated_size += border_width * 2; - } - else - { + *allocated_size -= border_width * 2; *allocated_pos += border_width; *minimum_size -= border_width * 2; *natural_size -= border_width * 2; @@ -1835,8 +1948,49 @@ gtk_container_adjust_size_allocation (GtkWidget *widget, * and padding values. */ parent_class->adjust_size_allocation (widget, orientation, - minimum_size, natural_size, allocated_pos, - allocated_size); + minimum_size, natural_size, allocated_pos, + allocated_size); +} + +typedef struct { + gint hfw; + gint wfh; +} RequestModeCount; + +static void +count_request_modes (GtkWidget *widget, + RequestModeCount *count) +{ + GtkSizeRequestMode mode = gtk_widget_get_request_mode (widget); + + switch (mode) + { + case GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH: + count->hfw++; + break; + case GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT: + count->wfh++; + break; + case GTK_SIZE_REQUEST_CONSTANT_SIZE: + default: + break; + } +} + +static GtkSizeRequestMode +gtk_container_get_request_mode (GtkWidget *widget) +{ + GtkContainer *container = GTK_CONTAINER (widget); + RequestModeCount count = { 0, 0 }; + + gtk_container_forall (container, (GtkCallback)count_request_modes, &count); + + if (!count.hfw && !count.wfh) + return GTK_SIZE_REQUEST_CONSTANT_SIZE; + else + return count.wfh > count.hfw ? + GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT : + GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; } /** @@ -1865,7 +2019,7 @@ gtk_container_class_handle_border_width (GtkContainerClass *klass) /** * gtk_container_forall: * @container: a #GtkContainer - * @callback: a callback + * @callback: (scope call) (closure callback_data): a callback * @callback_data: callback user data * * Invokes @callback on each child of @container, including children @@ -1874,11 +2028,13 @@ gtk_container_class_handle_border_width (GtkContainerClass *klass) * of the container, but were added by the container implementation * itself. Most applications should use gtk_container_foreach(), * rather than gtk_container_forall(). + * + * Virtual: forall **/ void gtk_container_forall (GtkContainer *container, - GtkCallback callback, - gpointer callback_data) + GtkCallback callback, + gpointer callback_data) { GtkContainerClass *class; @@ -1904,8 +2060,8 @@ gtk_container_forall (GtkContainer *container, **/ void gtk_container_foreach (GtkContainer *container, - GtkCallback callback, - gpointer callback_data) + GtkCallback callback, + gpointer callback_data) { GtkContainerClass *class; @@ -1934,7 +2090,7 @@ gtk_container_foreach (GtkContainer *container, */ void gtk_container_set_focus_child (GtkContainer *container, - GtkWidget *child) + GtkWidget *child) { g_return_if_fail (GTK_IS_CONTAINER (container)); if (child) @@ -1951,8 +2107,9 @@ gtk_container_set_focus_child (GtkContainer *container, * currently focused widget. That can be obtained by calling * gtk_window_get_focus(). * - * Returns: The child widget which will recieve the focus inside @container when - * the @conatiner is focussed, or %NULL if none is set. + * Returns: (transfer none): The child widget which will receive the + * focus inside @container when the @conatiner is focussed, + * or %NULL if none is set. * * Since: 2.14 **/ @@ -1979,15 +2136,15 @@ gtk_container_get_children (GtkContainer *container) GList *children = NULL; gtk_container_foreach (container, - gtk_container_children_callback, - &children); + gtk_container_children_callback, + &children); return g_list_reverse (children); } static void gtk_container_child_position_callback (GtkWidget *widget, - gpointer client_data) + gpointer client_data) { struct { GtkWidget *child; @@ -2002,7 +2159,7 @@ gtk_container_child_position_callback (GtkWidget *widget, static gchar* gtk_container_child_default_composite_name (GtkContainer *container, - GtkWidget *child) + GtkWidget *child) { struct { GtkWidget *child; @@ -2016,19 +2173,19 @@ gtk_container_child_default_composite_name (GtkContainer *container, data.i = 0; data.index = 0; gtk_container_forall (container, - gtk_container_child_position_callback, - &data); + gtk_container_child_position_callback, + &data); name = g_strdup_printf ("%s-%u", - g_type_name (G_TYPE_FROM_INSTANCE (child)), - data.index); + g_type_name (G_TYPE_FROM_INSTANCE (child)), + data.index); return name; } gchar* _gtk_container_child_composite_name (GtkContainer *container, - GtkWidget *child) + GtkWidget *child) { gboolean composite_child; @@ -2043,19 +2200,19 @@ _gtk_container_child_composite_name (GtkContainer *container, gchar *name; if (!quark_composite_name) - quark_composite_name = g_quark_from_static_string ("gtk-composite-name"); + quark_composite_name = g_quark_from_static_string ("gtk-composite-name"); name = g_object_get_qdata (G_OBJECT (child), quark_composite_name); if (!name) - { - GtkContainerClass *class; + { + GtkContainerClass *class; - class = GTK_CONTAINER_GET_CLASS (container); - if (class->composite_name) - name = class->composite_name (container, child); - } + class = GTK_CONTAINER_GET_CLASS (container); + if (class->composite_name) + name = class->composite_name (container, child); + } else - name = g_strdup (name); + name = g_strdup (name); return name; } @@ -2070,7 +2227,7 @@ typedef struct { static void gtk_container_compute_expand_callback (GtkWidget *widget, - gpointer client_data) + gpointer client_data) { ComputeExpandData *data = client_data; @@ -2112,7 +2269,7 @@ gtk_container_compute_expand (GtkWidget *widget, static void gtk_container_real_set_focus_child (GtkContainer *container, - GtkWidget *child) + GtkWidget *child) { GtkContainerPrivate *priv; @@ -2124,10 +2281,10 @@ gtk_container_real_set_focus_child (GtkContainer *container, if (child != priv->focus_child) { if (priv->focus_child) - g_object_unref (priv->focus_child); + g_object_unref (priv->focus_child); priv->focus_child = child; if (priv->focus_child) - g_object_ref (priv->focus_child); + g_object_ref (priv->focus_child); } @@ -2144,16 +2301,16 @@ gtk_container_real_set_focus_child (GtkContainer *container, hadj = g_object_get_qdata (G_OBJECT (container), hadjustment_key_id); vadj = g_object_get_qdata (G_OBJECT (container), vadjustment_key_id); if (hadj || vadj) - { + { - focus_child = priv->focus_child; - while (GTK_IS_CONTAINER (focus_child) && gtk_container_get_focus_child (GTK_CONTAINER (focus_child))) - { - focus_child = gtk_container_get_focus_child (GTK_CONTAINER (focus_child)); - } + focus_child = priv->focus_child; + while (GTK_IS_CONTAINER (focus_child) && gtk_container_get_focus_child (GTK_CONTAINER (focus_child))) + { + focus_child = gtk_container_get_focus_child (GTK_CONTAINER (focus_child)); + } - gtk_widget_translate_coordinates (focus_child, priv->focus_child, - 0, 0, &x, &y); + gtk_widget_translate_coordinates (focus_child, priv->focus_child, + 0, 0, &x, &y); gtk_widget_get_allocation (priv->focus_child, &allocation); x += allocation.x; @@ -2161,12 +2318,12 @@ gtk_container_real_set_focus_child (GtkContainer *container, gtk_widget_get_allocation (focus_child, &allocation); - if (vadj) - gtk_adjustment_clamp_page (vadj, y, y + allocation.height); + if (vadj) + gtk_adjustment_clamp_page (vadj, y, y + allocation.height); - if (hadj) - gtk_adjustment_clamp_page (hadj, x, x + allocation.width); - } + if (hadj) + gtk_adjustment_clamp_page (hadj, x, x + allocation.width); + } } } @@ -2178,14 +2335,14 @@ get_focus_chain (GtkContainer *container) /* same as gtk_container_get_children, except it includes internals */ -static GList * -gtk_container_get_all_children (GtkContainer *container) +GList * +_gtk_container_get_all_children (GtkContainer *container) { GList *children = NULL; gtk_container_forall (container, - gtk_container_children_callback, - &children); + gtk_container_children_callback, + &children); return children; } @@ -2199,7 +2356,7 @@ gtk_container_real_get_path_for_child (GtkContainer *container, GList *classes; context = gtk_widget_get_style_context (GTK_WIDGET (container)); - path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container))); + path = _gtk_widget_create_path (GTK_WIDGET (container)); /* Copy any permanent classes to the path */ classes = gtk_style_context_list_classes (context); @@ -2215,6 +2372,8 @@ gtk_container_real_get_path_for_child (GtkContainer *container, g_list_free_1 (cur); } + gtk_widget_path_append_for_widget (path, child); + return path; } @@ -2238,10 +2397,10 @@ gtk_container_focus (GtkWidget *widget, if (gtk_widget_get_can_focus (widget)) { if (!gtk_widget_has_focus (widget)) - { - gtk_widget_grab_focus (widget); - return_val = TRUE; - } + { + gtk_widget_grab_focus (widget); + return_val = TRUE; + } } else { @@ -2249,21 +2408,21 @@ gtk_container_focus (GtkWidget *widget, * chain to override. */ if (priv->has_focus_chain) - children = g_list_copy (get_focus_chain (container)); + children = g_list_copy (get_focus_chain (container)); else - children = gtk_container_get_all_children (container); + children = _gtk_container_get_all_children (container); if (priv->has_focus_chain && - (direction == GTK_DIR_TAB_FORWARD || - direction == GTK_DIR_TAB_BACKWARD)) - { - sorted_children = g_list_copy (children); - - if (direction == GTK_DIR_TAB_BACKWARD) - sorted_children = g_list_reverse (sorted_children); - } + (direction == GTK_DIR_TAB_FORWARD || + direction == GTK_DIR_TAB_BACKWARD)) + { + sorted_children = g_list_copy (children); + + if (direction == GTK_DIR_TAB_BACKWARD) + sorted_children = g_list_reverse (sorted_children); + } else - sorted_children = _gtk_container_focus_sort (container, children, direction, NULL); + sorted_children = _gtk_container_focus_sort (container, children, direction, NULL); return_val = gtk_container_focus_move (container, sorted_children, direction); @@ -2276,8 +2435,8 @@ gtk_container_focus (GtkWidget *widget, static gint tab_compare (gconstpointer a, - gconstpointer b, - gpointer data) + gconstpointer b, + gpointer data) { GtkAllocation child1_allocation, child2_allocation; const GtkWidget *child1 = a; @@ -2297,9 +2456,9 @@ tab_compare (gconstpointer a, gint x2 = child2_allocation.x + child2_allocation.width / 2; if (text_direction == GTK_TEXT_DIR_RTL) - return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1); + return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1); else - return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1); + return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1); } else return (y1 < y2) ? -1 : 1; @@ -2307,9 +2466,9 @@ tab_compare (gconstpointer a, static GList * gtk_container_focus_sort_tab (GtkContainer *container, - GList *children, - GtkDirectionType direction, - GtkWidget *old_focus) + GList *children, + GtkDirectionType direction, + GtkWidget *old_focus) { GtkTextDirection text_direction = gtk_widget_get_direction (GTK_WIDGET (container)); children = g_list_sort_with_data (children, tab_compare, GINT_TO_POINTER (text_direction)); @@ -2328,13 +2487,13 @@ gtk_container_focus_sort_tab (GtkContainer *container, */ static gboolean get_allocation_coords (GtkContainer *container, - GtkWidget *widget, - GdkRectangle *allocation) + GtkWidget *widget, + GdkRectangle *allocation) { gtk_widget_get_allocation (widget, allocation); return gtk_widget_translate_coordinates (widget, GTK_WIDGET (container), - 0, 0, &allocation->x, &allocation->y); + 0, 0, &allocation->x, &allocation->y); } /* Look for a child in @children that is intermediate between @@ -2343,7 +2502,7 @@ get_allocation_coords (GtkContainer *container, */ static GtkWidget * find_old_focus (GtkContainer *container, - GList *children) + GList *children) { GList *tmp_list = children; while (tmp_list) @@ -2352,16 +2511,16 @@ find_old_focus (GtkContainer *container, GtkWidget *widget = child; while (widget && widget != (GtkWidget *)container) - { - GtkWidget *parent; + { + GtkWidget *parent; parent = gtk_widget_get_parent (widget); - if (parent && (gtk_container_get_focus_child (GTK_CONTAINER (parent)) != widget)) - goto next; + if (parent && (gtk_container_get_focus_child (GTK_CONTAINER (parent)) != widget)) + goto next; - widget = parent; - } + widget = parent; + } return child; @@ -2374,7 +2533,7 @@ find_old_focus (GtkContainer *container, static gboolean old_focus_coords (GtkContainer *container, - GdkRectangle *old_focus_rect) + GdkRectangle *old_focus_rect) { GtkWidget *widget = GTK_WIDGET (container); GtkWidget *toplevel = gtk_widget_get_toplevel (widget); @@ -2402,8 +2561,8 @@ struct _CompareInfo static gint up_down_compare (gconstpointer a, - gconstpointer b, - gpointer data) + gconstpointer b, + gpointer data) { GdkRectangle allocation1; GdkRectangle allocation2; @@ -2422,9 +2581,9 @@ up_down_compare (gconstpointer a, gint x2 = abs (allocation2.x + allocation2.width / 2 - compare->x); if (compare->reverse) - return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1); + return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1); else - return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1); + return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1); } else return (y1 < y2) ? -1 : 1; @@ -2432,9 +2591,9 @@ up_down_compare (gconstpointer a, static GList * gtk_container_focus_sort_up_down (GtkContainer *container, - GList *children, - GtkDirectionType direction, - GtkWidget *old_focus) + GList *children, + GtkDirectionType direction, + GtkWidget *old_focus) { CompareInfo compare; GList *tmp_list; @@ -2458,38 +2617,38 @@ gtk_container_focus_sort_up_down (GtkContainer *container, compare_x2 = old_allocation.x + old_allocation.width; if (direction == GTK_DIR_UP) - compare_y = old_allocation.y; + compare_y = old_allocation.y; else - compare_y = old_allocation.y + old_allocation.height; + compare_y = old_allocation.y + old_allocation.height; tmp_list = children; while (tmp_list) - { - GtkWidget *child = tmp_list->data; - GList *next = tmp_list->next; - gint child_x1, child_x2; - GdkRectangle child_allocation; - - if (child != old_focus) - { - if (get_allocation_coords (container, child, &child_allocation)) - { - child_x1 = child_allocation.x; - child_x2 = child_allocation.x + child_allocation.width; - - if ((child_x2 <= compare_x1 || child_x1 >= compare_x2) /* No horizontal overlap */ || - (direction == GTK_DIR_DOWN && child_allocation.y + child_allocation.height < compare_y) || /* Not below */ - (direction == GTK_DIR_UP && child_allocation.y > compare_y)) /* Not above */ - { - children = g_list_delete_link (children, tmp_list); - } - } - else - children = g_list_delete_link (children, tmp_list); - } - - tmp_list = next; - } + { + GtkWidget *child = tmp_list->data; + GList *next = tmp_list->next; + gint child_x1, child_x2; + GdkRectangle child_allocation; + + if (child != old_focus) + { + if (get_allocation_coords (container, child, &child_allocation)) + { + child_x1 = child_allocation.x; + child_x2 = child_allocation.x + child_allocation.width; + + if ((child_x2 <= compare_x1 || child_x1 >= compare_x2) /* No horizontal overlap */ || + (direction == GTK_DIR_DOWN && child_allocation.y + child_allocation.height < compare_y) || /* Not below */ + (direction == GTK_DIR_UP && child_allocation.y > compare_y)) /* Not above */ + { + children = g_list_delete_link (children, tmp_list); + } + } + else + children = g_list_delete_link (children, tmp_list); + } + + tmp_list = next; + } compare.x = (compare_x1 + compare_x2) / 2; compare.y = old_allocation.y + old_allocation.height / 2; @@ -2505,21 +2664,21 @@ gtk_container_focus_sort_up_down (GtkContainer *container, gtk_widget_get_allocation (widget, &allocation); if (old_focus_coords (container, &old_focus_rect)) - { - compare.x = old_focus_rect.x + old_focus_rect.width / 2; - } + { + compare.x = old_focus_rect.x + old_focus_rect.width / 2; + } else - { - if (!gtk_widget_get_has_window (widget)) - compare.x = allocation.x + allocation.width / 2; - else - compare.x = allocation.width / 2; - } + { + if (!gtk_widget_get_has_window (widget)) + compare.x = allocation.x + allocation.width / 2; + else + compare.x = allocation.width / 2; + } if (!gtk_widget_get_has_window (widget)) - compare.y = (direction == GTK_DIR_DOWN) ? allocation.y : allocation.y + allocation.height; + compare.y = (direction == GTK_DIR_DOWN) ? allocation.y : allocation.y + allocation.height; else - compare.y = (direction == GTK_DIR_DOWN) ? 0 : + allocation.height; + compare.y = (direction == GTK_DIR_DOWN) ? 0 : + allocation.height; } children = g_list_sort_with_data (children, up_down_compare, &compare); @@ -2532,8 +2691,8 @@ gtk_container_focus_sort_up_down (GtkContainer *container, static gint left_right_compare (gconstpointer a, - gconstpointer b, - gpointer data) + gconstpointer b, + gpointer data) { GdkRectangle allocation1; GdkRectangle allocation2; @@ -2552,9 +2711,9 @@ left_right_compare (gconstpointer a, gint y2 = abs (allocation2.y + allocation2.height / 2 - compare->y); if (compare->reverse) - return (y1 < y2) ? 1 : ((y1 == y2) ? 0 : -1); + return (y1 < y2) ? 1 : ((y1 == y2) ? 0 : -1); else - return (y1 < y2) ? -1 : ((y1 == y2) ? 0 : 1); + return (y1 < y2) ? -1 : ((y1 == y2) ? 0 : 1); } else return (x1 < x2) ? -1 : 1; @@ -2562,9 +2721,9 @@ left_right_compare (gconstpointer a, static GList * gtk_container_focus_sort_left_right (GtkContainer *container, - GList *children, - GtkDirectionType direction, - GtkWidget *old_focus) + GList *children, + GtkDirectionType direction, + GtkWidget *old_focus) { CompareInfo compare; GList *tmp_list; @@ -2588,38 +2747,38 @@ gtk_container_focus_sort_left_right (GtkContainer *container, compare_y2 = old_allocation.y + old_allocation.height; if (direction == GTK_DIR_LEFT) - compare_x = old_allocation.x; + compare_x = old_allocation.x; else - compare_x = old_allocation.x + old_allocation.width; + compare_x = old_allocation.x + old_allocation.width; tmp_list = children; while (tmp_list) - { - GtkWidget *child = tmp_list->data; - GList *next = tmp_list->next; - gint child_y1, child_y2; - GdkRectangle child_allocation; - - if (child != old_focus) - { - if (get_allocation_coords (container, child, &child_allocation)) - { - child_y1 = child_allocation.y; - child_y2 = child_allocation.y + child_allocation.height; - - if ((child_y2 <= compare_y1 || child_y1 >= compare_y2) /* No vertical overlap */ || - (direction == GTK_DIR_RIGHT && child_allocation.x + child_allocation.width < compare_x) || /* Not to left */ - (direction == GTK_DIR_LEFT && child_allocation.x > compare_x)) /* Not to right */ - { - children = g_list_delete_link (children, tmp_list); - } - } - else - children = g_list_delete_link (children, tmp_list); - } - - tmp_list = next; - } + { + GtkWidget *child = tmp_list->data; + GList *next = tmp_list->next; + gint child_y1, child_y2; + GdkRectangle child_allocation; + + if (child != old_focus) + { + if (get_allocation_coords (container, child, &child_allocation)) + { + child_y1 = child_allocation.y; + child_y2 = child_allocation.y + child_allocation.height; + + if ((child_y2 <= compare_y1 || child_y1 >= compare_y2) /* No vertical overlap */ || + (direction == GTK_DIR_RIGHT && child_allocation.x + child_allocation.width < compare_x) || /* Not to left */ + (direction == GTK_DIR_LEFT && child_allocation.x > compare_x)) /* Not to right */ + { + children = g_list_delete_link (children, tmp_list); + } + } + else + children = g_list_delete_link (children, tmp_list); + } + + tmp_list = next; + } compare.y = (compare_y1 + compare_y2) / 2; compare.x = old_allocation.x + old_allocation.width / 2; @@ -2635,21 +2794,21 @@ gtk_container_focus_sort_left_right (GtkContainer *container, gtk_widget_get_allocation (widget, &allocation); if (old_focus_coords (container, &old_focus_rect)) - { - compare.y = old_focus_rect.y + old_focus_rect.height / 2; - } + { + compare.y = old_focus_rect.y + old_focus_rect.height / 2; + } else - { - if (!gtk_widget_get_has_window (widget)) - compare.y = allocation.y + allocation.height / 2; - else - compare.y = allocation.height / 2; - } + { + if (!gtk_widget_get_has_window (widget)) + compare.y = allocation.y + allocation.height / 2; + else + compare.y = allocation.height / 2; + } if (!gtk_widget_get_has_window (widget)) - compare.x = (direction == GTK_DIR_RIGHT) ? allocation.x : allocation.x + allocation.width; + compare.x = (direction == GTK_DIR_RIGHT) ? allocation.x : allocation.x + allocation.width; else - compare.x = (direction == GTK_DIR_RIGHT) ? 0 : allocation.width; + compare.x = (direction == GTK_DIR_RIGHT) ? 0 : allocation.width; } children = g_list_sort_with_data (children, left_right_compare, &compare); @@ -2681,16 +2840,16 @@ gtk_container_focus_sort_left_right (GtkContainer *container, **/ GList * _gtk_container_focus_sort (GtkContainer *container, - GList *children, - GtkDirectionType direction, - GtkWidget *old_focus) + GList *children, + GtkDirectionType direction, + GtkWidget *old_focus) { GList *visible_children = NULL; while (children) { if (gtk_widget_get_realized (children->data)) - visible_children = g_list_prepend (visible_children, children->data); + visible_children = g_list_prepend (visible_children, children->data); children = children->next; } @@ -2714,8 +2873,8 @@ _gtk_container_focus_sort (GtkContainer *container, static gboolean gtk_container_focus_move (GtkContainer *container, - GList *children, - GtkDirectionType direction) + GList *children, + GtkDirectionType direction) { GtkContainerPrivate *priv = container->priv; GtkWidget *focus_child; @@ -2729,7 +2888,7 @@ gtk_container_focus_move (GtkContainer *container, children = children->next; if (!child) - continue; + continue; if (focus_child) { @@ -2737,8 +2896,8 @@ gtk_container_focus_move (GtkContainer *container, { focus_child = NULL; - if (gtk_widget_child_focus (child, direction)) - return TRUE; + if (gtk_widget_child_focus (child, direction)) + return TRUE; } } else if (gtk_widget_is_drawable (child) && @@ -2755,7 +2914,7 @@ gtk_container_focus_move (GtkContainer *container, static void gtk_container_children_callback (GtkWidget *widget, - gpointer client_data) + gpointer client_data) { GList **children; @@ -2824,7 +2983,7 @@ gtk_container_set_focus_chain (GtkContainer *container, g_return_if_fail (GTK_IS_WIDGET (tmp_list->data)); /* In principle each widget in the chain should be a descendant - * of the container, but we don't want to check that here, it's + * of the container, but we don't want to check that here. It's * expensive and also it's allowed to set the focus chain before * you pack the widgets, or have a widget in the chain that isn't * always packed. So we check for ancestor during actual traversal. @@ -2868,7 +3027,7 @@ gtk_container_set_focus_chain (GtkContainer *container, **/ gboolean gtk_container_get_focus_chain (GtkContainer *container, - GList **focus_chain) + GList **focus_chain) { GtkContainerPrivate *priv; @@ -2879,9 +3038,9 @@ gtk_container_get_focus_chain (GtkContainer *container, if (focus_chain) { if (priv->has_focus_chain) - *focus_chain = g_list_copy (get_focus_chain (container)); + *focus_chain = g_list_copy (get_focus_chain (container)); else - *focus_chain = NULL; + *focus_chain = NULL; } return priv->has_focus_chain; @@ -2947,7 +3106,7 @@ gtk_container_unset_focus_chain (GtkContainer *container) */ void gtk_container_set_focus_vadjustment (GtkContainer *container, - GtkAdjustment *adjustment) + GtkAdjustment *adjustment) { g_return_if_fail (GTK_IS_CONTAINER (container)); if (adjustment) @@ -2957,9 +3116,9 @@ gtk_container_set_focus_vadjustment (GtkContainer *container, g_object_ref (adjustment); g_object_set_qdata_full (G_OBJECT (container), - vadjustment_key_id, - adjustment, - g_object_unref); + vadjustment_key_id, + adjustment, + g_object_unref); } /** @@ -3002,7 +3161,7 @@ gtk_container_get_focus_vadjustment (GtkContainer *container) */ void gtk_container_set_focus_hadjustment (GtkContainer *container, - GtkAdjustment *adjustment) + GtkAdjustment *adjustment) { g_return_if_fail (GTK_IS_CONTAINER (container)); if (adjustment) @@ -3012,9 +3171,9 @@ gtk_container_set_focus_hadjustment (GtkContainer *container, g_object_ref (adjustment); g_object_set_qdata_full (G_OBJECT (container), - hadjustment_key_id, - adjustment, - g_object_unref); + hadjustment_key_id, + adjustment, + g_object_unref); } /** @@ -3046,14 +3205,14 @@ gtk_container_show_all (GtkWidget *widget) g_return_if_fail (GTK_IS_CONTAINER (widget)); gtk_container_foreach (GTK_CONTAINER (widget), - (GtkCallback) gtk_widget_show_all, - NULL); + (GtkCallback) gtk_widget_show_all, + NULL); gtk_widget_show (widget); } static void gtk_container_draw_child (GtkWidget *child, - gpointer client_data) + gpointer client_data) { struct { GtkWidget *container; @@ -3061,8 +3220,8 @@ gtk_container_draw_child (GtkWidget *child, } *data = client_data; gtk_container_propagate_draw (GTK_CONTAINER (data->container), - child, - data->cr); + child, + data->cr); } static gint @@ -3079,14 +3238,14 @@ gtk_container_draw (GtkWidget *widget, gtk_container_forall (GTK_CONTAINER (widget), gtk_container_draw_child, - &data); + &data); return FALSE; } static void gtk_container_map_child (GtkWidget *child, - gpointer client_data) + gpointer client_data) { if (gtk_widget_get_visible (child) && gtk_widget_get_child_visible (child) && @@ -3100,8 +3259,8 @@ gtk_container_map (GtkWidget *widget) gtk_widget_set_mapped (widget, TRUE); gtk_container_forall (GTK_CONTAINER (widget), - gtk_container_map_child, - NULL); + gtk_container_map_child, + NULL); if (gtk_widget_get_has_window (widget)) gdk_window_show (gtk_widget_get_window (widget)); @@ -3218,19 +3377,6 @@ gtk_container_propagate_draw (GtkContainer *container, cairo_restore (cr); } -gboolean -_gtk_container_get_need_resize (GtkContainer *container) -{ - return container->priv->need_resize; -} - -void -_gtk_container_set_need_resize (GtkContainer *container, - gboolean need_resize) -{ - container->priv->need_resize = need_resize; -} - gboolean _gtk_container_get_reallocate_redraws (GtkContainer *container) { @@ -3243,7 +3389,7 @@ _gtk_container_get_reallocate_redraws (GtkContainer *container) * @child: a child of @container * * Returns a newly created widget path representing all the widget hierarchy - * from the toplevel down to @child (this one not being included). + * from the toplevel down to and including @child. * * Returns: A newly created #GtkWidgetPath **/ @@ -3251,9 +3397,21 @@ GtkWidgetPath * gtk_container_get_path_for_child (GtkContainer *container, GtkWidget *child) { + GtkWidgetPath *path; + g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL); g_return_val_if_fail (GTK_IS_WIDGET (child), NULL); g_return_val_if_fail (container == (GtkContainer *) gtk_widget_get_parent (child), NULL); - return GTK_CONTAINER_GET_CLASS (container)->get_path_for_child (container, child); + path = GTK_CONTAINER_GET_CLASS (container)->get_path_for_child (container, child); + if (gtk_widget_path_get_object_type (path) != G_OBJECT_TYPE (child)) + { + g_critical ("%s %p returned a widget path for type %s, but child is %s", + G_OBJECT_TYPE_NAME (container), + container, + g_type_name (gtk_widget_path_get_object_type (path)), + G_OBJECT_TYPE_NAME (child)); + } + + return path; }