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 782494 - Regression in GtkListBox internal child listing
Regression in GtkListBox internal child listing
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
3.22.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2017-05-11 04:09 UTC by Ikey Doherty
Modified: 2017-05-12 07:29 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
listbox: manually unparent placeholder in dispose (1.66 KB, patch)
2017-05-11 13:36 UTC, Timm Bäder
none Details | Review

Description Ikey Doherty 2017-05-11 04:09:32 UTC
As of the following commit, the internal behaviour of GtkListBox has changed:

https://git.gnome.org/browse/gtk+/commit/?h=gtk-3-22&id=b7fdc5b447b44b5b7638a3ac41cac58136bc5ca2

Now the internals include the placeholder widget within `gtk_container_foreach` and `gtk_container_forall`, meaning `gtk_container_get_children` now returns the placeholder widget, which previously was not.

For programs that previously iterated on the contents, expecting just the children rows to be returned, this is no longer the case, as we may *also* get the placeholder, leading to segfault situations.

See this Budgie fix for the impact of this bug:

https://github.com/budgie-desktop/budgie-desktop/commit/b07359f5c14185126ac6d780c44b25fe325c2cba
Comment 1 Emmanuele Bassi (:ebassi) 2017-05-11 12:32:50 UTC
As a general rule, you cannot expect anything from the list of children returned by GtkContainer.get_children(), except that the GtkWidget.parent of each child is going to be the container. GTK+ widgets are free to interpose any child in between the widget you added and themselves, like GtkListBox already does, for instance.

The appropriate way to only deal with children you added by yourself is to use an ancillary data structure; alternatively, if you only want to deal with GtkListBoxRow instances, which are the ones added via gtk_container_add(), you should do a type check on each item of the returned list.

In this case, since the placeholder is explicitly added by the developer, even not through gtk_container_add(), masking it as an "internal" child (thus not returned by GtkContainer.get_children()) is both slightly incorrect, and it's likely going to break additional assumptions with regard to styling and internal state. See bug 778617 for the discussion.
Comment 2 Ikey Doherty 2017-05-11 12:38:33 UTC
I'm aware of the problem which is why I've first fixed it in Budgie.
However the facts remain:

 - The "ancillary structure" is already there by means of GtkListBoxRow (GtkBin)
 - A minor update in the *stable* release of GTK has broken dependent API contracts and caused regressions, contrary to documentation in all gtk_container* methods and gtklistbox.c comments.
 - Distributions are updating to the latest stable GTK version, following the same major branch they've been on, to encounter breaking changes in terms of function behaviour. The perception is that GTK3 is LTS, which seems contradicted by changes like this (And the X11 clipboard regression)

If this was a gtk4 fix I could see into it, with a clearly documented change in expected behaviour in the documentation, though I'm highly doubtful I'll be the last one that's affected by this.
Comment 3 Emmanuele Bassi (:ebassi) 2017-05-11 12:50:02 UTC
(In reply to Ikey Doherty from comment #2)

> However the facts remain:
> 
>  - The "ancillary structure" is already there by means of GtkListBoxRow
> (GtkBin)

No, not really. When I say "ancillary structure" I mean an additional list of widgets you *know* you added, instead of relying on the list of children provided by GtkContainer — because the list of children returned by GtkContainer is the list of widgets GTK+ internally manages, and that may or may not match what *you* added to the container.

>  - A minor update in the *stable* release of GTK has broken dependent API
> contracts and caused regressions, contrary to documentation in all
> gtk_container* methods and gtklistbox.c comments.

Again, no: not really. If you're relying on undefined behaviour, then you cannot claim an API break.

In any case, this is why I didn't close the bug: there is some leeway to argue that the placeholder widget, while being *explicitly* added by the application developer, can also be considered "internal". Personally, I think it's entirely correct to mark the placeholder as *not* internal, because it's not a widget added through some level of indirection, and it *is* a child of GtkListBox.

The change in bug 778617 was introduced to fix a segmentation fault and a warning in GTK+ 3.22, not because of GTK+ 4.0 development.

>  - Distributions are updating to the latest stable GTK version, following
> the same major branch they've been on, to encounter breaking changes in
> terms of function behaviour. The perception is that GTK3 is LTS, which seems
> contradicted by changes like this (And the X11 clipboard regression)

This is inconsequential ranting, so please leave it out of Bugzilla.

Being "feature and API stable" does not imply being "bug free", otherwise we would not need to release GTK+ 3.22 at all.
Comment 4 Ikey Doherty 2017-05-11 12:59:42 UTC
> because the list of children returned by GtkContainer is the list of widgets GTK+ internally manages, and that may or may not match what *you* added to the container.

Surely this is why we have the differentiation of internal in the first place with the GtkContainer->forall vfunc?

> Again, no: not really. If you're relying on undefined behaviour, then you cannot claim an API break.

Then the documentation should make this explicitly clear. Either the path for managing placeholders is to NULL or destroy it, or to expect it to be returned by the child list for the commonly used foreach child in list pattern.

> not because of GTK+ 4.0 development.

You missed my point, I didn't infer it was a GTK4 backport - rather that breaking changes typically happen in major versions, not minor.

> This is inconsequential ranting, so please leave it out of Bugzilla.

Pointing out facts which are applicable to the downstreams deploying your software does not constitute "inconsequential ranting" - it highlights the importance of the issue and how they'll come to a head in other distributions too. Your response to dismiss it as "ranting" is disappointing. It's possible to have a complaint that is not emotionally based, but based on the technical issues at hand.
Comment 5 Timm Bäder 2017-05-11 13:36:22 UTC
Created attachment 351635 [details] [review]
listbox: manually unparent placeholder in dispose

To be applied after reverting b7fdc5b447b44b5b7638a3ac41cac58136bc5ca2.
Comment 6 Timm Bäder 2017-05-12 06:59:43 UTC
Marking this fixed since that commit has been pushed to gtk-3-22 and is part of 3.22.15.
Comment 7 Ikey Doherty 2017-05-12 07:10:36 UTC
Cheers lads
Comment 8 Timm Bäder 2017-05-12 07:16:42 UTC
I *just* figured out that this is the reason I don't see the placeholder in my project anymore btw (I thought it's another problem I have...). Never made the connection, so thanks for noticing and reporting :)
Comment 9 Ikey Doherty 2017-05-12 07:29:30 UTC
Ah no biggie. FWIW it was impossible for me to not notice it, Budgie Panel segfaulted on startup xD