CustomStyleResolvedEvent Never Called

I have some code which needs to execute after the layout of a VisualElement has been calculated. VisualElement.schedule.Execute only works sometimes (perhaps another bug), so I decided to register a callback to the CustomStyleResolvedEvent like this:

element.RegisterCallback<CustomStyleResolvedEvent>(e => Debug.Log(element.resolvedStyle.width));

Problem is: It never runs. This might also be related to why VisualElement.schedule.Execute only has the layout calculated sometimes. Anyways, this is quite a problem as this leaves me with no reliable way of scheduling code to when the layout of an element has been calculated.

This happens on version 2021.2.0b9.

Why not use GeometryChangedEvent ?

Totally forgot about that! Thanks!

Got a new similar use case where the element where I need the layout to be calculated is being modified (adjustment). Using GeometryChangedEvent creates errors about recursive layout. Any ideas?

Layout update is struggling to process current layout (consider simplifying to avoid recursive layout): VisualElement PanelSettings (x:0.00, y:0.00, width:1920.00, height:1080.00) world rect: (x:0.00, y:0.00, width:1920.00, height:1080.00)
UnityEngine.UIElements.UIElementsRuntimeUtilityNative:UpdateRuntimePanels ()

This log happen when a recursive layout loop is detected.

In your case my guess is that in your GeometryChangedEvent callback you do the adjustment to the layout which trigger a new layout pass. This send another GeometryChangedEvent and then more adjustment are made in the callback which trigger another layout pass and so on until you get the “Layout update is struggling to process current layout” message.

I still wonder why CustomStyleResolvedEvent is/was never called? Even if one could work around this issue, I suspect this should be considered a bug or not?

1 Like

CustomStyleResolvedEvent is only sent when an element is matching any custom style. A custom style property is one that is prefixed with “–”. It can also be used as a variable.

You can refer to this page for more information.

2 Likes

I know the page, but it doesn’t talk about the event :wink:

Do I get this right? With “an element is matching any custom style” you mean:

For an element to receive the CustomStyleResolvedEvent, it needs to have, e.g., a class applied which references a custom style property (--custom-property)? And if it receives the event, it has access to all defined custom properties? Or only the one that is applied to it?

How can I access the value of an arbitrary custom property form C# then? E.g., something like --my-default-border-width

1 Like

I’d suggest being cautious in using GeometryChangedEvent. It seems to have some sort of floating point issue under certain circumstances which makes it get called multiple times during rendering. This can trigger the “Layout update is struggling to process current layout” error.

Also, I was curious about CustomStyleResolvedEvent but I don’t see it documented anywhere on Unity - Manual: Event reference

When the element receives the event it has access to all the custom properties that are applied to this element.

You can register a CustomStyleResolvedEvent callback on the element that --my-default-border-width property is applied to.

This is probably due to the GeometryChangedEvent callback modifying the element layout which will trigger a new layout pass and potentially a new GeometryChangedEvent leading to a loop of layout calculation + GeometryChangedEvent.

Right, but in enough cases, Unity will temporarily change the element’s size during its render process when it probably shouldn’t. Namely when it’s inside of a flex container that is changing sizes. Even if the element won’t end up changing size this event gets triggered because the size gets changed temporarily for some reason.

My solution has been to UnregisterCallback, change the container size, and then RegisterCallback. It feels clunky though.