I'm especially wondering if we even need the 'snapToPixel' property at all. I never needed it, never saw it being used or set somewhere else.
With that said, I was also wondering about potential consequences to performance if we try to track the parent snapping property. If we move forward with that, we need to find a good implementation for that.
-- Marius On 9/9/26 4:52 PM, John Hendrikx wrote:
The docs on `snapToPixelProperty` state: /** * Defines whether this region adjusts position, spacing, and size values of * its children to pixel boundaries. This defaults to true, which is generally * the expected behavior in order to have crisp user interfaces. A value of * false will allow for fractional alignment, which may lead to "fuzzy" * looking borders. */ This does leave a lot ambiguous as to what should happen when a region is not snapped, but its children (or grand children) are snapped again. The problem: 1. When an ancestor is unsnapped, no amount of snapping of children will return the claimed "crisp user interfaces" for those children. Once an ancestor decides to allocate a non-integer number of pixels at a non-grid aligned location, even snapped children will not look crisp. 2. Children that are snapped that receive a width/height that is not an integer multiple will be faced with a dilemma: - Do they round their width/height down to not exceed their allocated size? - Do they round it up to ensure they cover the allocated size potentially overlapping another child of the unsnapped parent? - That could undo whatever the parent was trying to achieve... - What do they do with those fractional pixels that are left over when distributing (snapped) space over their own children? - Add the "left over" space to one of those, which then pushes the problem down another layer (the grand child receives a non-integer number of pixels from a snapped(!!) parent)? - Not pass them down to any child, but let the background of the container fill that space? The current implementation in JavaFX for this situation, an unsnapped parent with snapped children, essentially ignores these questions and allows the layout algorithm to use the width and height as given. The result can therefore depend on the exact implementation and order of calculations, without the situation itself being explicitly accounted for. Furthermore, re-enabling snapping below an unsnapped ancestor seems counterintuitive and is unlikely to be useful in practice. If an ancestor has explicitly opted out of pixel snapping, descendants cannot generally undo that decision without either compromising the ancestor's positioning or size allocations, or propagating the fractional-layout problem further down the hierarchy Proposal: I think the existing API documentation has enough leeway to change how we implement snapping in the case of an unsnapped ancestor. I therefore propose to make snapping dependent on the ancestor. A node is only snapped if all of its ancestors are snapped. This would eliminate a number of ambiguities with relatively little downside: - As today, children of an unsnapped container can still end up looking fuzzy. However, they would follow the unsnapped calculation path rather than being presented with an inconsistent combination of snapped and unsnapped constraints. - There would be no need to define how a snapped child should resolve fractional space received from an unsnapped parent. - We would not need to decide where fractional space should go when distributing space among descendants, or whether that space should be propagated to another level. - We would avoid having a snapped child round its dimensions up or down in a way that could contradict the layout decisions made by its unsnapped parent. So once an ancestor opts out of snapping, that should apply to the entire subtree. This makes it much more predictable (and also is likely what was intended) and avoids having to find an unsatisfactory solution for all the edge cases when combining snapped nodes with unsnapped ancestors. I'm curious what others think, and this is relevant as we're about to enshrine snapping rules in the next release I think. --John
