GNOME Bugzilla – Bug 764710
GtkListBox row CSS nodes do not reflect visual order
Last modified: 2016-04-11 11:53:21 UTC
If you add a child to a GtkListBox out of order using gtk_list_box_insert(), the CSS nodes generated for the inserted GtkListBoxRows does not reflect the same visual ordering of the list. If you then use the CSS :first-child, :last-child or selectors that are dependent on the order of the rows, this leads to unintended results and hence makes the positional selectors rather useless. For example, append a widget to a GtkListBox then add another above it. This might happen because you are inserting them in order, but at different times: > GtkListBox list = ...; > gtk_container_add(list, widget1); > gtk_list_box_insert(list, widget2, 0); When displayed, this list box will correctly display widget2 above widget1 in the list. If you then style the list's rows using the following CSS: > list > row:first_child { > background: red; > } Unexpectedly, the second row will be styled with the red background.
What happens if you switch 0 to 1? Looking at the code in gtklistbox.c: prev_iter = g_sequence_iter_prev (iter); if (prev_iter != iter) { sibling = g_sequence_get (prev_iter); gtk_css_node_insert_after (gtk_widget_get_css_node (GTK_WIDGET (box)), gtk_widget_get_css_node (child), gtk_widget_get_css_node (sibling)); } That inserting to 0 would result in it not getting the proper positioning since iter_prev would be the same as iter.
Not sure, but I'd expect it to not matter because the visual order would then match the CSS node order. I'll try to come up with a test minimal case and post it here. NB: This also seems to be a problem when setting a sort function on the list box - the CSS nodes again don't match the visual (sorted) order.
Created attachment 325518 [details] Minimal test case Minimal test case attached. Compile with: > gcc `pkg-config --cflags gtk+-3.0` -o list_box_css_order_testcase list_box_css_order_testcase.c `pkg-config --libs gtk+-3.0` When running it, note that although "row:first-child" is used in the CSS selector, it is not the first child that is coloured red. Changing the index of the insert call from 0 to 1 when adding the second list row indeed results in an expected result since the second label is actually added in the second position.