On Tue, 1 Sep 2026 16:11:12 GMT, Michael Strauß <[email protected]> wrote:
>>> * HBox 2 (snapped) gets 10.25 pixels >>> * Child 1 gets 5 pixels >>> * Child 2 gets 5 pixels >>> * (empty space within border of 0.25 pixels) >>> * Empty space location determined by alignment >>> * LEFT: C1 C2 (0.25) >>> * CENTER: (0.125) C1 C2 (0.125) >>> * RIGHT: (0.25) C1 C2 >> >> It can't possibly work like that. You have a snapped HBox that is allocated >> 10.25 pixels. Now, each of the two children must be allocated 5 pixels, as >> otherwise they will be off-grid. If you allocate 5.0 pixels to C1, and 5.25 >> pixels to C2, then the latter will be off-grid at its right edge. >> >> The remainder of 0.25 pixels can't possibly be anywhere else but at the >> right edge of the allocated space: >> 1. If the remainder is at the left edge of the allocation, then both >> children will be offset 0.25 pixels relative to the grid. >> 2. If it is between the children, then the left child will be aligned, but >> the right child will be offset. >> 3. This leaves the right edge as the only place where to insert the >> remainder. >> >> What confuses me is the following: You argue that we should just accept the >> allocation that we receive from the parent. But then you also say that a >> small portion of empty space should be inserted when the children can't fill >> the allocation. I can't help but see a contradiction here. We can only >> choose between two options: >> >> 1. A layout container accepts the allocation it has received, and lays out >> its children so the assigned allocation is perfectly honored. If the >> allocation is not snapped, this inevitably means that at least one child >> can't be perfectly aligned to the grid. In the HBox scenario, it means that >> we can perfectly align all children but the last, which needs to be that >> 0.25 pixels wider in order to perfectly fill the allocation. >> 2. Alternatively, we don't accept the allocation that was given to us, but >> instead snap the allocation to the pixel grid. Only then will be be able to >> perfectly align the children within that allocation. > >> I wonder, why do we even need the unsnapped setting? what is the use case? > > In theory, with a sufficiently high-DPI display, you don't need pixel > snapping at all. The number of photons emitted from a perfectly-aligned > hairline, and a hairline that straddles a pixel boundary, is the same. The > only difference is that in the latter case, the photons are emitted from a > more spread-out area. But once your DPI is so high that you can't see a > difference between the two, there's no need for snapping. > > * HBox 2 (snapped) gets 10.25 pixels > > > > * Child 1 gets 5 pixels > > * Child 2 gets 5 pixels > > * (empty space within border of 0.25 pixels) > > > > * Empty space location determined by alignment > > > > * LEFT: C1 C2 (0.25) > > * CENTER: (0.125) C1 C2 (0.125) > > * RIGHT: (0.25) C1 C2 > > It can't possibly work like that. You have a snapped HBox that is allocated > 10.25 pixels. Now, each of the two children must be allocated 5 pixels, as > otherwise they will be off-grid. If you allocate 5.0 pixels to C1, and 5.25 > pixels to C2, then the latter will be off-grid at its right edge. What makes you think that snapping here will result in being on-grid? Clearly with an allocation of 10.25 pixels, we're dealing with an unsnapped container, why would pixel 0 be on the grid? Where we put that 0.25 of empty space is anyone's guess as to whether that will align you; saying that it can only be on the right edge is ridiculous: <img width="1104" height="259" alt="image" src="https://github.com/user-attachments/assets/5143c4e5-a2ee-48de-b197-0c9d7a5ef386" /> > The remainder of 0.25 pixels can't possibly be anywhere else but at the right > edge of the allocated space: > > 1. If the remainder is at the left edge of the allocation, then both children > will be offset 0.25 pixels relative to the grid. > 2. If it is between the children, then the left child will be aligned, but > the right child will be offset. Both entirely depend on where the container starts. > 3. This leaves the right edge as the only place where to insert the remainder. Assuming that your anchor is on the grid, but it won't be. The rest of your argument is the same. If your unsnapped parent didn't set your x/y to be on the grid, then nothing you can do as a child will get you aligned back. I think you even said as much in the snapping docs. This is why I think we shouldn't bother at all with this, and treat any unsnapped ancestor as final for that subtree. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/2262#discussion_r3906473141
