JPro-one / JPro-Tickets

The right place to report about bugs or suggest improvements for JPro.
https://www.jpro.one
9 stars 4 forks source link

Screen info is wrong #96

Open mipastgt opened 3 years ago

mipastgt commented 3 years ago

My application only works as intended when I have the correct DPI and screen scale of the current display but JPro does not seem to provide these correctly.

Some code like this

   Window w = this.getScene().getWindow();
   List<Screen> screens = Screen.getScreensForRectangle(w.getX(), w.getY(), w.getWidth(), w.getHeight());
   screens.forEach(s -> System.out.println("DPI " + s.getDpi()));
   System.out.println("RenderScaleX " + w.getRenderScaleX());
   System.out.println("RenderScaleY " + w.getRenderScaleY());

prints

DPI 96.0
RenderScaleX 1.0
RenderScaleY 1.0

when run with JPro although the correct output should be

DPI 81.0
RenderScaleX 2.0
RenderScaleY 2.0

I am running locally on a Mac with the following config:

[info] c.j.i.s.Initializer$ -  *** Starting JPro: https://www.jpro.one/ ***
[info] c.j.i.s.Initializer$ - OS: Mac OS X
[info] c.j.i.s.Initializer$ - JPro: 2021.1.0-PREVIEW2
[info] c.j.i.s.Initializer$ - Java version: 15.0.2
[info] c.j.i.s.Initializer$ - JVM: 15.0.2 Oracle Corporation
[info] c.j.i.s.Initializer$ - redirected OUT / ERR
[info] c.j.i.s.Initializer$ - installed SLF4JBridge
[info] c.j.i.s.MonocleInitializer$ - screen: null
[warn] javafx - Unsupported JavaFX configuration: classes were loaded from 'unnamed module @74e95e3d'
[info] c.j.i.s.Initializer$ - finished init!
[info] c.j.i.s.Initializer$ - JavaFX version: 16.0.0.1-jpro+0-2021-04-15-155901

The Mac is attached to a high-resolution Screen and is scaled by a factor 2 like a normal retina display. The browser was the latest Chrome browser.

FlorianKirmaier commented 3 years ago

The screen-class is quite unreliable in combination with JPro - because it doesn't reflect the Screen of the user. It's possible to access the screen information through javascript. WebAPI.executeScriptWithReturn("window.devicePixelRatio",(result) -> <doSomething>); We should add this information to the the WebAPI, so they can be accessed for each user. A small change, we should be able to provide a test version with this.

mipastgt commented 3 years ago

I guess you meant executeScriptWithListener. I got that working but actually this should directly be tracked by JPro because it can change dynamically if the user moves the browser window around on his desktop and thereby going from one screen to another with different properties.

FlorianKirmaier commented 3 years ago

I would add the following methods to the WebAPI:

Double getDevicePixelRatio()
ReadonlyDoubleProperty devicePixelRatio()

This would match your use case, right?

By the way, it's possible to implement the auto-update functionality with the WebAPI. With registerJavaFunction you can register a function you can call from a listener in JavaScript, which will then be executed in the JVM.

Checkout this for some samples

mipastgt commented 3 years ago

Yes that is my use case.

I would make getDevicePixelRatio() return a double and not a Double for consistency and performance reasons. Would it be possible to provide the DPI settings in the same way because when the pixel ratio changes, the DPI value almost always changes too unless the browser always returns a constant value of 96? If both values are returned, it might also make sense to combine them in a single object property, so that you have to register only one listener and only get notified once and not twice.

FlorianKirmaier commented 3 years ago

For what do you use this Information? JavaFX seems to scale Canvas automatically based on the devicePIxelRatio, and JPro does the same. It seems hard to find a use case for it - because most cases are solved by the underlying rendering.

mipastgt commented 3 years ago

One possible use case is for example creating something like a map display. Depending on the screen resolution you have to pick different map tiles. In my case either 256x256 or 512x512 pixel variants. There are further issues when you want to draw very thin but still sharp lines, etc.

FlorianKirmaier commented 3 years ago

That makes sense. The version 2021.1.0-PREVIEW2 is stable and contains the new WebAPI methods!

mipastgt commented 3 years ago

I can confirm that this works now with 2021.1.0-PREVIEW3 but would it be possible to add corresponding methods for the DPI value too?

FlorianKirmaier commented 3 years ago

Forgot to mention it, dpi is rather tricky. The PixelDeviceRatio was tricky, and actually "the internet" was pretty wrong on how to add listeners to the value. For DPI, Safari doesn't seem to support it, and the rest doesn't provide an API to get the value - only media-queries. https://developer.mozilla.org/en-US/docs/Web/CSS/@media/resolution So I guess a solution would be too tricky and therefore wrong and unreliable (for now). Most places recommend multiplying the devicePixelRatio by 96, as a practical approximation.

mipastgt commented 3 years ago

Ok, I understand and I can (have to) probably live with that :-)