Question/feedback regarding Windows Hi DPI support and how it will affect applications

Jim Graham james.graham at oracle.com
Wed Feb 18 01:27:49 UTC 2015


I'm currently investigating what changes we need to make to get Windows 
HiDPI support up and running.  As it stands, anyone with a Hi DPI 
Windows machine will see all Java and JavaFX programs run very tiny 
since the Java executables have declared that we are "DPI Aware" in the 
program manifest for a few releases now.  That setting was necessary to 
prevent the platform from pixel-scaling us back at a time when the 
actual DPIs of screens were not that drastically different from the norm 
and pixel scaling looked remarkably ugly compared to the amount of size 
difference it bought you.

But, things are changing rapidly and there are a number of screens out 
there now upon which Windows recommends that you should scale by 1.5x up 
to 3x.  A retina iMac or MacBook Pro (220 DPI) running Windows 7+, for 
example, will request us to scale by 2x, we'll implicitly indicate that 
we've heard that request by the fact that the Java manifest says we are 
"System DPI Aware" and they'll trust our sizes in pixels even though we 
calculated them based on a regular DPI screen - and we end up being half 
the size we want and nearly unreadable.  There are also Windows laptops 
such as the Lenovo Yoga 2 Pro (released Oct 2013) and Yoga 3 Pro that 
have nearly 300DPI screens where the default pixel scale requested is 
3x.  Java and FX windows are even tinier and harder to read on those 
screens.

(Side note: In FX, as it turns out, our "em" scaling in css is actually 
DPI aware so if you sized everything using CSS and the "em", then you 
might actually look OK.  In practice, though, there are a ton of pixel 
dimensions in the default L&F CSS files so you'd have to do quite a bit 
of customization to make that work.)

Adding a scale factor to the Windows platform code is not hard, and I 
have that code up and running.  But, we run into the following issues 
that didn't come up when we did the retina port:

- non-integer coordinates in events

Our Mac code truncates and filters events to integers, but Windows may 
specify non-integer scaling so this gets trickier now.  Certainly we can 
round or truncate, and filter for integers, but we end up in situations 
where the user can see the mouse move, but the program does not react 
because that event was filtered out.  Note that a test program on the 
Mac does show that we sometimes repeat Mouse coordinates on retina 
screens which shows that even with the 2x scaling on Mac we are seeing 
repeated coordinates - they are somewhat rare, though, since I think the 
Mac internally only processes mouse moves in a virtual space.  It will 
be much more common with Windows more flexible scaling, though, since 
the mouse cursor moves based on pixel distances, not based on filtered 
event distances.

- screen dimensions

For a single screen we can simply divide by the pixel scale, but with 3x 
scaling the division produces non-integers.  This would also show up if 
we embrace the 125% and 150% scales that Windows documents/APIs 
recommend we support.

But, a bigger issue happens with multi-monitor setups.  The Mac lays out 
the screens (in the Control Panel UI, and in the bounds they report) in 
virtual coordinates based on the pixel scale.  That, combined with the 
fact that they use 2x scaling only and screens are even numbers of 
pixels in size, means we can pass those numbers on and they don't look 
odd.  But, Windows allows a wider range of scales (125%, 150%, 200%, 
300%) and it also lays out screens in pixels which raises a couple of 
issues - non-integer screen sizes for some combinations of scale factors 
and pixel sizes, and also screens are supposed to lie against each 
others' edges so the user can line them up perfectly in the Control 
Panel and if we try to represent that same layout in "virtual scaled 
coordinates" the monitors may not line up correctly.  I'll get into more 
detail on that below.

So, my questions to developers are:

- Would seeing non-integer event coordinates break your code?
- Would seeing non-integer window sizes and positions break your code?
- Would non-integer screen sizes break your code?
- If we try to translate Windows Screen pixel sizes into virtual 
coordinates and the layout doesn't quite represent what they see in the 
Control Panel, how much of a problem is that?
- If we try to translate Windows Screen pixel sizes into virtual 
coordinates and, due to a complex layout, our algorithm cannot get all 
of the edges to match each other as they do in pixel space and we need 
to punt, how much might it break code if there are gaps or overlaps in 
the reported Screen bounds (i.e. this is worse than "the layout doesn't 
quite look the same" I asked about above)?
- If we provide a flag or scale factor on the screens to indicate that 
the dimensions provided are in pixels and you must convert your desired 
window sizes by the indicated scale factor in order to know how big to 
make your window - how much impact would that have?
- As a followup to "screens in pixel sizes", we could alternately 
arrange so that specifying how big your Scene is and/or using the 
standard setWidth()/setHeight() methods on stage and relying on default 
window positioning or using the default "centerOnScreen()" types of 
positioning methods could be taught to work regardless of what we decide 
here.  It would only be if you wanted to correlate all of the screens 
and come up with your own x,y,w,h - that would be where you might need 
to be aware if the screen dimensions are not in the same space as scene 
dimensions.

To get an idea of the kinds of problems we might encounter when trying 
to translate the screens into "virtual coordinates", consider that the 
default layout of linearly placing all screens next to each other is 
easy to translate (though if one screen doesn't "divide out" evenly then 
some of the locations might be non-integers).  But, consider a 3x3 grid 
of displays (i.e. 9 monitors in a square grid layout).  If they are 
identical then the layout would be a perfectly aligned grid.  If the 
middle screen has double (or half) the resolution of the others then we 
have to either have it float in the middle of a "virtual size" space 
that is too large for its dimensions, or have it overlap the 8 screens 
around the outside, or push the 8 screens around the outside away from 
each other so that they no longer touch.  Since the user laid the 
screens out in pixels in the Control Panel UI, they believe that they 
may have created a perfect grid, but we will have to present an 
imperfect grid to the JavaFX program if we want to maintain the illusion 
that FX Screen object sizes are scaled.  Even worse, the adjustments we 
have to make would be heuristic and depending on what we choose it might 
break what they wanted to achieve, or it might not matter, it depends on 
what they were thinking and what we independently decided as to how to 
best represent it.

So, we could:

- Expose the "screen dimensions are pixels which may not match the 
coordinates in your scenes" property of Windows screens.  This may cause 
problems for programs that examine the screens and attempt to do their 
own custom positioning, but should not matter to programs that trust the 
default positioning, or centerOnScreen() method(s?).

- Expose "screen dimensions are pixels", but make common APIs work in 
Virtual coordinates - scene/stage.setWidth/Height() could be in virtual 
coordinates for instance.  Screen might have multiple getBounds() 
methods depending on if you want virtual coordinates or pixel 
coordinates and only relying on the pixel coordinate versions will work 
in Windows in all cases.  The issue here is that sometimes the base APIs 
might not correlate well with each other, but they will make sense if 
you know the trick.

- Try to convert Windows screens into logical coordinates that make 
sense.  It will work for 99% of cases probably most of which are single 
screen or default linear layouts.  In some number of corner cases, 
though, we may get it wrong and the values you find in screen bounds 
could have gaps or overlaps or bear no resemblance to how the user 
perceives his workspace.

- Any other ideas?

			...jim


More information about the openjfx-dev mailing list