Different behaviour for markAsDirty between Form and Layout

In my efforts to get the deprecated Form class out of my code I’ve been looking at adding my fields to a Layout instead of a Form. They work okay up to a point but there is a problem I need help with. My application has a View with several read-only TextFields and a popup Window. The popup gathers some data and feeds it to an object whose data are displayed on the read-only fields. When the popup exits it fires an event which causes the View to invoke markAsDirtyRecursive on itself to update the values on the read-only fields.

When I have these read-only fields on a Form added to the View they update just fine.
When I have them on a HorizontalLayout added to the View they don’t update. I can switch to another View and switch back, which forces a re-render and they have the correct values then, but obviously I need this to happen automatically (as it does with a Form).

I’ve ensured they are all setImmediate(true) and setBuffered(false) and as far as I can tell the settings on both the Form and Layout fields are identical. I also added separate markAsDirty() calls on the Layout fields just in case, but that did not help.

What am I missing here? What ensures the Form updates perfectly and the non-Form fails?

Thanks