GNOME Bugzilla – Bug 699756
GtkAssistant hack in gtk_container_remove() makes custom assistant-like containers impossible
Last modified: 2018-02-11 19:28:57 UTC
In gtk_container_remove(), there is an assertion: https://git.gnome.org/browse/gtk+/tree/gtk/gtkcontainer.c?id=ed1eddabf064769747e927a68f2dc59bd8241ebf#n1552 g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container) || GTK_IS_ASSISTANT (container)); This is because GtkAssistant's "children" are actually children of one of its internal children, so the first clause fails. This hack makes it impossible to implement one's own container with similar behavior. Instead, maybe the second clause could be replaced by a call to some internal function like _gtk_container_has_child() that queries gtk_container_get_children()?
just for the record, you want to create a Container that has an internal layout manager/container, and proxy add() and remove() from your external class to the internal one — correct? I'd rather add an (optional) has_child() virtual function that gets overridden by a GtkContainer implementation. get_children() has to build the list that you need to traverse, and then free — all in a g_return_val_if_fail(). the default implementation would do something like g_list_find(get_children(), child), but we can override it for the classes inside GTK at the very least.
The hack is purely there for backwards compatibility. GtkAssistant used to have direct children, so gtk_container_remove used to work on it. Then, at some point it was rewritten to have internal structure, but gtk_container_remove had to keep working. If you create your own assistant-like widget, you don't need gtk_container_remove to work - just have a my_assistant_remove function that can do whatever is necessary.
Emanuele: proxying add() and remove(), correct. Proxying add() already works, but remove() doesn't, because of the assertion. Matthias: if you're writing a library, then you would have to make sure your library users use your not-sure-why-it's-not-equivalent my_assistant_remove() API instead of gtk_container_remove(). Basically you're exposing an implementation detail that way.
Oh, I missed what you are complaining about - you are subclassing GtkAssistant ?! I guess one answer to that is: don't do that, GtkAssistant is not meant for subclassing.
No, I'm trying to create a container class completely unrelated to GtkAssistant, that proxies add() and remove() to an internal container that is an implementation detail. So I would like gtk_container_add() and gtk_container_remove() to be called on the outer container, but actually add and remove widgets to and from the internal container. Removing doesn't work, because the child widget is not strictly a child of the outer container, but gtk_container_remove() requires it to be. The only reason I mentioned GtkAssistant is because GtkAssistant does this too, and GTK has a special hack to allow it ;-)
Well, as I said, the hack is only there for backwards compatibility reasons.
Do you mean that proxying gtk_container_add() and gtk_container_remove() to an internal child shouldn't be supported?
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
I don't know if this works yet, but in any case the offending check seems to have been removed. It's probably OK to close it.