GNOME Bugzilla – Bug 105541
gtk_frame_forall ignores
Last modified: 2014-03-22 22:09:27 UTC
gtk_frame_forall ignores the include_internals argument. The general description for containers says that when include_internals == FALSE only the children that have been added to the container should be visited. So in this case I would expect that the label should not be visited. Change gtk_frame_forall from: if (frame->label_widget) (* callback) (frame->label_widget, callback_data); to: if (include_internals && frame->label_widget) (* callback) (frame->label_widget, callback_data);
I guess the label_widget is not really considered an internal child, since there is a method gtk_frame_set_label_widget().
One could argue that there should be some distinction between "regular" children and "user-added ornaments", but that is currently not the case.
But this behavior is not consistent with other container widgets. This is the list of widgets that have internal children: GtkCList: the column buttons GtkNoteBook: the tab_label and the menu_label GtkScrolledWindow: the horizontal and vertical scrollbars GtkTreeItem: the subtree GtkTreeView: the columns In all cases (except GtkScrolledWindow) the user can replace the internal child with a new widget, but it is still treated as an internal child.
Ok, I only looked at scrolled window as another example...guess I picked the bad one. Looks like you're right and include_internals is in fact intended to discriminate between "regular children" and "ornaments", regardless whether these ornaments are added via API or internally.
I would agree with Matthias's original interpretation ... I suspect that GtkNotebook and GtkTreeView are wrong here in the cases where the children have been added explicitely. In GtkTreeView, they are usually created by the widget, in GtkNotebook, they can be created by the widget in some cases. (GtkTreeItem is an incredibly broken widget, and incorrect in many ways. GtkCList is not ENABLE_BROKEN, but it is deprecated.)
Are you arguing that forall should behave differently for button1 and button2 in the following example ? button1 = gtk_button_new_with_label ("Hi!"); button2 = gtk_button_new (); gtk_container_add (GTK_CONTAINER (button2), gtk_label_new ("Hi!"));
If Matthias' interpretation of Owen's comments is correct (I think it is) this would be highly undesirable behaviour. The distinction between child widgets that have been added by the user (apparently these should not be internal) and the default child widgets that have been added by the parent widget by default (these should be internal) can be very fuzzy. For example take the situation where I want to use a fancy widget that is a subclass of GtkFrame, and that was developed by someone else. In that case I'll have to find out whether or not that developer has used the default label or used something else for the label. If in the next release of the fancy widget makes a different decision I suddenly have more or fewer children. It gets even worse when the fancy widget can decide at runtime if it should use the default label widget or not, perhaps it will use a specialized widget only when the label text is too long to fit on the screen. I still think that the most elegant solution is to say that only the children that have been added with gtk_container_add (or its equivalent) are "true" children and that all other child widgets are internal children. The next best solution is to document for each widget which child widgets are internal. For the current implementation, this would mean that the label of a frame is always a "true" child and never an internal child. But the alternative that Owen appears to suggest is IMNSHO a horrible idea. Another more compelling argument perhaps, is that it would require rewriting existing Gtk code.
Well, maybe we should back up and ask you what you want this information for? I don't think we really _have_ a definition of what forall() and foreach() are for right now, except that: forall() will go through ALL children foreach() will at least go through all children added explicitely by the application.
This also relates to the problem of gtk_container_show_all breaking some composite widgets (e.g. the opacity fields in the color selection will become visible), since the hide/show_all functions use foreach.
The original reason that I ran into this was that I've implemented a widget based on GtkContainer and wondered how it should handle gtk_container_forall and gtk_container_foreach. Looking at the implementations I found that in general all children that are added with gtk_container_add are considered "true" children, and that all other child widgets are "internal" children. That is a very simple rule. AFAIK the only changes that are needed to enforce this rule is the modification I suggested to GtkFrame. I don't expect that it will break much existing code because programmers that want to process all child widgets will have used gtk_container_forall (that is not affected) and programmers that only want to process the widget that is inside the frame will already have some check to skip the label. Also most programmers that have used other container widgets will be surprised (and probably unpleasantly surprised) that the label is not considered an internal child of a GtkFrame. Does this interpretation break any of the existing widgets? Ambiguous specifications are bad and are a frequent source of bugs. So, even though this is a pretty minor issue, I would really welcome it if you could come up with a clear design decision on this point.
Just so its not forgotten - whatever is decided here needs to be propogated to gtk_expander_forall too.
closing out old bugs