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 625316 - [StContainer] Add :first-child, :last-child pseudo classes
[StContainer] Add :first-child, :last-child pseudo classes
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2010-07-26 13:24 UTC by Florian Müllner
Modified: 2010-08-05 17:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[StContainer] Add :first-child, :last-child pseudo classes (5.06 KB, patch)
2010-07-26 13:24 UTC, Florian Müllner
needs-work Details | Review
[StContainer] Add :first-child, :last-child pseudo classes (6.00 KB, patch)
2010-08-01 13:36 UTC, Florian Müllner
reviewed Details | Review
[StContainer] Add :first-child, :last-child pseudo classes (5.31 KB, patch)
2010-08-05 16:44 UTC, Florian Müllner
committed Details | Review

Description Florian Müllner 2010-07-26 13:24:46 UTC
See patch. The pseudo classes are arguably only useful with support for non-uniform borders / border-radii, but one may still hope for those, right? (see bug 624384 and bug 624378)

In contrast to the :hover class, there is no property to opt-in to the automatic tracking - the class changes when children are added / removed from the container, which will queue a relayout anyway. That said, if there are further performance concerns about unnecessary style changes, such a property can easily be added.
Comment 1 Florian Müllner 2010-07-26 13:24:50 UTC
Created attachment 166581 [details] [review]
[StContainer] Add :first-child, :last-child pseudo classes

Add support for the CSS :first-child and :last-child properties to
StContainer, and thus to all containers in St and ShellGenericContainer.

The internal ordering of the container's children is used to determine
the child to which to attach the pseudo class, not the children's
positions. This means that containers where positions can differ from
the ordering (ShellGenericContainer / StGroup) may behave unexpectedly,
so some caution is required.
Comment 2 Dan Winship 2010-07-26 16:30:06 UTC
(In reply to comment #0)
> See patch. The pseudo classes are arguably only useful with support for
> non-uniform borders / border-radii

nah, there are cases where it's useful to have different padding on the ends. (I wanted this in the original message tray summary area.)
Comment 3 Owen Taylor 2010-07-29 09:17:12 UTC
Review of attachment 166581 [details] [review]:

I think it's fine if it works funny for ShellGenericContainer.... if you are creating a ShellGenericContainer where the :first-child/:last_child pseudo-classes are meaningful, you can take care of keeping the child list in the appropriate order. (Or if it becomes an issue, we can shell_generic_container_set_auto_first_last_child() and you can manage the pseudo-classes yourself.) Patch looks basically fine to me, except for some details of the logic.

::: src/st/st-container.c
@@ +53,3 @@
+  StContainerPrivate *priv = container->priv;
+
+  first_item = g_list_first (priv->children);

I really don't like g_list_first personally. I don't think you can use GList without understanding a linked list, and once you know what a linked list is, g_list_first (list) is obviously just list. [I suspect that you were trying for symmetry with the use of g_list_last() - I think that's sort of a fake symmetry - getting the last item of a list is very different than getting the first item of a list]

@@ +55,3 @@
+  first_item = g_list_first (priv->children);
+  if (first_item == NULL)
+    return;

This logic isn't right - if first_item is null, you still might need to remove the first_child/last_child classes from the old children. (I'm assuming that we don't want to leave classes on children that have been removed from the container.)

@@ +66,3 @@
+        st_widget_add_style_pseudo_class (ST_WIDGET (first_child),
+                                          "first-child");
+      priv->first_child = first_child;

A reference should be added to priv->first_child here. Otherwise, when you do this after remove()/remove_all(), priv->first_child might be pointing to unallocated memory and removing the style from it will crash.

@@ +372,3 @@
+
+  if (priv->last_child)
+    priv->last_child = NULL;

This leaves the pseudo-classes on the old children.
Comment 4 Florian Müllner 2010-08-01 13:36:21 UTC
Created attachment 166927 [details] [review]
[StContainer] Add :first-child, :last-child pseudo classes

Add support for the CSS :first-child and :last-child properties to
StContainer, and thus to all containers in St and ShellGenericContainer.
Comment 5 Dan Winship 2010-08-05 14:26:45 UTC
Comment on attachment 166927 [details] [review]
[StContainer] Add :first-child, :last-child pseudo classes

>+      if (priv->first_child)
>+        {
>+          if (ST_IS_WIDGET (priv->first_child))
>+            st_widget_remove_style_pseudo_class (ST_WIDGET (priv->first_child),
>+                                                 "first-child");
>+          g_object_unref (priv->first_child);
>+          priv->first_child = NULL;
>+        }

it seems ugly to have this twice (once for the no children case, once for the children-changed case). A simple "first_child = first_item ? first_item->data : NULL" would get rid of the duplicate cases...

>+  container->priv->first_child = NULL;
>+  container->priv->last_child = NULL;

you don't really need to do that. priv is initialized to 0s.
Comment 6 Florian Müllner 2010-08-05 16:44:24 UTC
Created attachment 167199 [details] [review]
[StContainer] Add :first-child, :last-child pseudo classes

OK.
Comment 7 Florian Müllner 2010-08-05 17:05:58 UTC
Attachment 167199 [details] pushed as 0905940 - [StContainer] Add :first-child, :last-child pseudo classes