Question/feedback regarding Windows Hi DPI support and how it will affect applications
james.graham at oracle.com
Mon Feb 23 20:18:48 UTC 2015
That is interesting, especially since it worked better without the
snapToPixel. Also, with a scale factor of 3 integer coordinates should
have been the same as pixel aligned coordinates, so it's unclear how the
snapToPixel could have been at fault (it would have been
snapToEvery3rdPixel which should have been just as smooth as "snap to
Was it a scale factor of "3.0", or a scale factor of "something close to 3"?
On 2/23/2015 12:01 PM, Johan Vos wrote:
> Hi Jim,
> Not sure this is really relevant to your thread, but I added HiDPI to
> Android recently.
> On my Nexus 5, with scale factor of 3 I noticed issues with e.g.
> ScrollPane, which has snapToPixel defaulting to true. The result was a
> blurry screen when scrolling. When I added a
> scrollPane.setSnapToPixel(false) line, the blurring was gone. Again, not
> sure this relates to your question, but in this case it seems a problem
> that the default behaviour tries to snap to an integer (1).
> - Johan
> 2015-02-18 2:27 GMT+01:00 Jim Graham <james.graham at oracle.com
> <mailto:james.graham at oracle.com>>:
> 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
> (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
> - 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?
More information about the openjfx-dev