GNOME Bugzilla – Bug 730687
GtkBox and subclasses don't emit add signal
Last modified: 2014-06-24 16:40:45 UTC
Created attachment 277111 [details] Simple test program to expose the erratic behavior When a widget is added to a GtkBox (using gtk_box_pack_*) then the "add" signal of the GtkContainer superclass is not emitted. There is no equivalent signal either. The bug is present in gtk2 and gtk3 This means that it's impossible to be notified about widgets that were added. And it creates inconsistency because the GtkBox contains all widgets, added with gtk_box_pack* and gtk_container_add, but the "add" signal only emits for the latter. Lastly, the "removed" siganl is emitted for all widgets, even for those that did not result in "add". This constitutes as a bug to in my book. Please find the attached test program which exposes the behavior.
BTW, I think #398241 is related in a way
the GtkContainer::add signal is not meant for getting notification of children addition. it's an unfortunate fact of life, and mostly an historical artefact. the GtkContainer::add signal was added for gtk_container_add() to emit, so that GtkContainer sub-types could override the closure and add their own code there; this was before we had virtual functions and class structures. fact is, we cannot emit the GtkContainer::add signal from within the gtk_box_pack_* functions; they would end up calling the default implementation inside GtkBox, which in the end calls pack_start(). this means that if you called gtk_box_pack_end() you'd end up with this chain: gtk_box_pack_end() GtkContainer::add GtkBox::add gtk_box_pack_start() the gtk_box_pack_start() at the bottom would not be able to distinguish that it's been called from another GtkBox method. even if we changed the default implementation of the GtkContainer::add override inside GtkBox, we would not have enough meta-information from the caller to distinguish from a signal emission made via gtk_container_add() and one from gtk_box_pack_*. to be absolutely fair, I think the entire container API in GTK is absolutely horrific, and it makes it really hard to do anything at all with it; if we had to do this all over again, then I would get rid of the Container API, and move it to GtkWidget.
Thanks for your reply. Yes, as you have said, the add signal is pretty useless for non-container-subclasses. I do wonder though, why it is implemented like that. Why doesn't the mechanism use plain virtual methods. I.e. why doesn't gtk_container_add() simply do GTK_CONTAINER_GET_CLASS(container)->add()? This would seem like the natural way to implement this _and_ allow GTK clients to make use of the "add" signal. The GtkContainer default implementation would just emit the signal and call the virtual method directly. If I were to post a patch that implements the above, would it be considered for merging?
*** This bug has been marked as a duplicate of bug 616850 ***
(In reply to comment #3) > I do wonder though, why it is implemented like that. Why doesn't the mechanism > use plain virtual methods. I.e. why doesn't gtk_container_add() simply do > GTK_CONTAINER_GET_CLASS(container)->add()? Because in the early days, people were scared of subclassing, and so doing gtk_container_new(); and connecting to a signal was easier than doing all the crazy get_type(); magic. These days, we have G_DEFINE_TYPE and other magic macros to help fight the scariness of subclassing.