After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 730687 - GtkBox and subclasses don't emit add signal
GtkBox and subclasses don't emit add signal
Status: RESOLVED DUPLICATE of bug 616850
Product: gtk+
Classification: Platform
Component: Widget: Other
3.12.x
Other All
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2014-05-24 12:58 UTC by Thomas Martitz
Modified: 2014-06-24 16:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Simple test program to expose the erratic behavior (1.87 KB, text/x-c)
2014-05-24 12:58 UTC, Thomas Martitz
Details

Description Thomas Martitz 2014-05-24 12:58:40 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.
Comment 1 Thomas Martitz 2014-05-24 15:10:35 UTC
BTW, I think #398241 is related in a way
Comment 2 Emmanuele Bassi (:ebassi) 2014-05-24 15:36:41 UTC
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.
Comment 3 Thomas Martitz 2014-05-24 23:00:51 UTC
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?
Comment 4 Matthias Clasen 2014-05-25 02:34:01 UTC

*** This bug has been marked as a duplicate of bug 616850 ***
Comment 5 Jasper St. Pierre (not reading bugmail) 2014-06-24 16:40:45 UTC
(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.