X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcontainer.c;h=ce16fe4df42e224471754b0886415b08b200e474;hb=d484721b5ca9e82d6422cca8a3a40f001208f87b;hp=61ed85aad1d5b0d78283a03c088b2882e3517bab;hpb=f91c04e2846de010871ee21389eb926dd18e065e;p=~andy%2Fgtk diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 61ed85aad..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 { @@ -307,6 +315,7 @@ 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); @@ -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; @@ -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; @@ -508,6 +517,8 @@ gtk_container_class_init (GtkContainerClass *class) 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 @@ -547,7 +558,7 @@ gtk_container_buildable_set_child_property (GtkContainer *container, const gchar *value) { GParamSpec *pspec; - GValue gvalue = { 0, }; + GValue gvalue = G_VALUE_INIT; GError *error = NULL; pspec = gtk_container_class_find_child_property @@ -761,6 +772,68 @@ 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, @@ -779,7 +852,7 @@ container_set_child_property (GtkContainer *container, 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 */ @@ -828,7 +901,6 @@ gtk_container_child_get_valist (GtkContainer *container, 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); @@ -836,7 +908,7 @@ 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; @@ -897,7 +969,6 @@ gtk_container_child_get_property (GtkContainer *container, 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)); @@ -917,7 +988,7 @@ gtk_container_child_get_property (GtkContainer *container, 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 */ @@ -973,7 +1044,6 @@ gtk_container_child_set_valist (GtkContainer *container, 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); @@ -982,7 +1052,7 @@ 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, @@ -1047,7 +1117,6 @@ gtk_container_child_set_property (GtkContainer *container, 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)); @@ -1081,12 +1150,12 @@ 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, @@ -1121,11 +1190,11 @@ 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, @@ -1134,10 +1203,6 @@ gtk_container_child_set (GtkContainer *container, { 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); @@ -1148,11 +1213,11 @@ 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, @@ -1161,10 +1226,6 @@ gtk_container_child_get (GtkContainer *container, { 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); @@ -1211,10 +1272,11 @@ gtk_container_class_install_child_property (GtkContainerClass *cclass, * gtk_container_class_find_child_property: * @cclass: (type GtkContainerClass): a #GtkContainerClass * @property_name: the name of the child property to find - * @returns: (transfer 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, @@ -1233,11 +1295,12 @@ gtk_container_class_find_child_property (GObjectClass *cclass, * gtk_container_class_list_child_properties: * @cclass: (type GtkContainerClass): a #GtkContainerClass * @n_properties: location to return the number of child properties found - * @returns: (array length=n_properties) (transfer container): 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, @@ -1283,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; } @@ -1294,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); @@ -1423,10 +1488,10 @@ 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. **/ @@ -1476,7 +1541,7 @@ gtk_container_remove (GtkContainer *container, { 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); } @@ -1485,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; } /** @@ -1564,115 +1628,166 @@ gtk_container_set_reallocate_redraws (GtkContainer *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) { - GtkContainer *resize_container; - GtkWidget *parent; GtkWidget *widget; g_return_if_fail (GTK_IS_CONTAINER (container)); 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); + _gtk_size_request_cache_clear (_gtk_widget_peek_request_cache (widget)); - if ((resize_container && widget == GTK_WIDGET (resize_container)) || - !(parent = gtk_widget_get_parent (widget))) + if (GTK_IS_RESIZE_CONTAINER (widget)) break; - widget = parent; + widget = gtk_widget_get_parent (widget); } + while (widget); - 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; + if (widget && !invalidate_only) + gtk_container_queue_resize_handler (GTK_CONTAINER (widget)); +} + +void +_gtk_container_queue_restyle (GtkContainer *container) +{ + GtkContainerPrivate *priv; - case GTK_RESIZE_IMMEDIATE: - gtk_container_check_resize (resize_container); - break; + g_return_if_fail (GTK_CONTAINER (container)); - 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; - } - } + priv = container->priv; + + if (priv->restyle_pending) + return; + + gtk_container_start_idle_sizer (container); + priv->restyle_pending = TRUE; } /** @@ -1705,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) { @@ -1808,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; @@ -1851,6 +1952,47 @@ gtk_container_adjust_size_allocation (GtkWidget *widget, 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; +} + /** * gtk_container_class_handle_border_width: * @klass: the class struct of a #GtkContainer subclass @@ -1877,7 +2019,7 @@ gtk_container_class_handle_border_width (GtkContainerClass *klass) /** * gtk_container_forall: * @container: a #GtkContainer - * @callback: (scope call): a callback + * @callback: (scope call) (closure callback_data): a callback * @callback_data: callback user data * * Invokes @callback on each child of @container, including children @@ -1886,6 +2028,8 @@ 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, @@ -2191,8 +2335,8 @@ 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; @@ -2212,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); @@ -2228,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; } @@ -2264,7 +2410,7 @@ gtk_container_focus (GtkWidget *widget, if (priv->has_focus_chain) 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 || @@ -3231,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) { @@ -3256,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 **/ @@ -3264,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; }