RFR: 8309460: JScrollBar leaves behind clutter for non-integer UI scales
Alexey Ivanov
aivanov at openjdk.org
Thu Mar 7 16:15:56 UTC 2024
On Wed, 24 Jan 2024 21:11:25 GMT, Alexey Ivanov <aivanov at openjdk.org> wrote:
> > > Because float scale results in fractional pixels?
> > > If the scale is 1.25, then 1 pixel is 1.25 physical pixels; 2 pixels are 2.5 physical pixels and so on.
> >
> > Initially this issue looked similar to fractional scaling issues such as border rendering issues observed on windows previously but it seems to happen only on non-standard fractional UI scales such as 2.3, 2.7 and not on standard fractional scales supported on windows (1.25,1.75,2.25 ..) [#17484 (review)](https://github.com/openjdk/jdk/pull/17484#pullrequestreview-1834275178).
>
> The underlying problem is still the same: there are fractional pixels.
I ran the test now and I'm sure the problem is very similar. When drag the thumb, the width of the left border is usually 2 pixels, sometimes it changes to 3 pixels. As I move farther, that third pixel remains on the background of the scrollbar.
The left over pixels create a regular pattern: 17 pixels followed by 8 pixels, then the cycle repeats. These are physical display pixels.
If you convert user space pixels to physical pixels, you'll see there's a pattern where fraction adds up to whole pixel: 4 user pixels, 3 user pixels.
As you drag the thumb, you can see that the highlight/shadow lines on the thumb itself dance.
This means that as you drag the thumb, the app sees 1-pixel increments which results in 2-pixel and 3-pixel increments on the screen.
> How it related to the "non-standard" fractional metrics(such as 2.3, 2.7) and why it works fine for 1.5 and 1.75.
I believe I explained how it's related to fractional scales. Why does it work for 1.25 and 1.75? I guess we never end up in a situation where a physical pixel doesn't get painted. With 1.5, the probability is even less.
You can still see the width of the left (and right) border changes; the highlight and shadow lines on the thumb continue to dance.
There are this kind of problems wherever pixels are painted by 1-pixel lines. Look at the title bar of a JInternalFrame in SwingSet2 as drag it: the pattern changes even at 1.5 scale; dragging at 1.25 and 1.75 gives another pattern.
> If we draw a border outside of the component that border should be fixed. If the clear/fillRect does not clear the component then we should fix the calculation of the bounds.
No, we don't draw outside of component bounds. We just don't repaint enough pixels as thumb is moved.
As you rightfully noticed something different is needed. Repainting the bounds of the thumb still solves the problem but it doesn't seem right.
As the thumb is dragged, it's repainted in the new location; the old location is erased eventually. When erasure is handled, I'd adjust the left coordinate to be (left - 1) to repaint a larger rectangle or something like this.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/17484#issuecomment-1983874053
More information about the client-libs-dev
mailing list