-
-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set default pixel density to the display's density. #952
base: main
Are you sure you want to change the base?
Set default pixel density to the display's density. #952
Conversation
This is aimed at achieving a High DPI by default for displays that support it.
Thank you, @yehiarasheed , for this PR! What platforms have you tested this on? I suspect platform specific behavior might add some wrinkles. I'd be happy to be wrong about this. Perhaps I have been traumatized by too many MacOS issues. :( Can you make the visibility of the new method |
As it turns out, you're actually correct. After a bit more research, I've discovered that the main issue is actually with windows systems as some of them by default return a DPI of 96 instead of the actual DPI whenever the DPI is high as could be seen here. On another note, I've discovered a fault in the logic of the getDisplayDPI() method implementation that I will correct and add to the PR description so that it is visible for anyone debugging any problems later on. I am testing it on a Windows machine currently on IntelliJ as instructed. Please review and get back to me. My implementation should cover most displays although, upon research, I've discovered that using JavaFX is generally more accurate than using the |
- Added check for Windows systems where Toolkit.getScreenResolution() incorrectly reports 96 DPI on high-DPI screens. - Force 2x scaling for Windows if DPI is 96 to ensure correct display scaling. - Maintain normal 2x scaling for DPI >= 144, fallback to 1x for lower DPI.
Is there a risk this might need to change in the future as monitors & technology evolve?
What other approaches are available here? JavaFX is nice but does that require extra JavaFX jars and libraries to be available? I do like JavaFX though, good for you to look into that. Is there a way to get the pixel density info by making a call directly to the OS? Trying to infer the pixel density from the DPI feels like a less certain approach. We can write native code for each OS to do this. |
There is definitely a risk that this might need to change in the future since we’re relying on a specific number. A better approach would be us checking if the DPI is just greater than 96, so that we don’t specifically check for numbers greater than 144 (hardcoding) and we can include any display with a DPI higher than the standard 96 as high-DPI. Although, most OSes do tend to standardize scaling factors so the number 144 should work fine in most cases.
As for the JavaFX approach, it’s generally more accurate than using the Note Upon revision, if we decided to go with implementing platform-specific methods to get the correct pixel density, we could reuse the methods already implemented in the |
Hi @hx2A , I’m adding support for detecting pixel density across platforms (Windows, macOS, Linux, Wayland). Since Thanks! |
Let's pursue this avenue and see where we can go with it.
I'm not familiar with https://processing.org/reference/libraries/io/index.html Not everyone will be using that library though. In core.jar you will find a For Windows there is a executable called I'm not sure about what to do for Linux. Generally Linux is better behaved about these kinds of things though. |
- Added the getScaleFactor method to different.m to retrieve the display scale factor on macOS. - Updated ThinkDifferent.java to include the native method declaration for getScaleFactor. - Ensured the Makefile compiles different.m correctly for both x86_64 and ARM architectures and creates a universal library. - Implemented getScaleFactor in PImage to call native OS methods based on the platform. This commit prepares the code for compilation and testing on a macOS machine.
- Enhanced `getScaleFactor` to include native OS calls for Windows DPI using `Fenster.exe`. - Adjusted scale factor rounding to use 1.5 as the threshold for high DPI detection. - Added debug print statements to assist with troubleshooting, which can be easily enabled if needed. - Included error handling for potential issues with executing `Fenster.exe`.
- Implement `getScaleFactor()` and `getScaleFactor(String method)` to determine the scale factor based on the operating system. - Add `roundScaleFactor(String roundingMethod, float scaleFactor)` to apply different rounding methods to the scale factor. - Introduce `setDefaultDPIRoundingMethod(String method)` and `getDefaultDPIRoundingMethod()` to manage the default DPI rounding method. - Update error message for running the required executable to be more user-friendly.
- Implemented DPI scaling for Linux using `xdpyinfo` for X11 and `wlr-randr` for Wayland. - Added error handling for potential IOExceptions. - Added logging to indicate the DPI scaling method used. Note: This implementation is pending testing on an AWS instance.
- Added handling for NumberFormatException in the Linux X11 DPI scaling logic. - Tested the changes on a Linux X11 machine.
Description
This PR closes issue #950. The aim of this PR is to change the default value of the
pixelDensity
variable, represented by thepixelDensity()
method to the display's density (DPI). The purpose of this change is to provide sharper rendering by default to displays that support High DPI.Implementation
This Section is regarding the implementation itself, I'll leave it here in case it is needed later for debugging. The DPI feature is computed as follows, we are making use of the
Toolkit
class found in thejava.awt
package. I've decided to implement the DPI Computation in a separate method for modularity and easier maintenance later on as could be seen below.I've used the
Toolkit.getDefaultToolkit()
method to acquire the Default Toolkit, on which I invoke the instance methodgetScreenResolution()
which returns the DPI of the display if it could be computed. This introduced a tricky case, on some windows machines, whenever the DPI of the Display is high sometimes windows defaults to a DPI of 96 sometimes as could be seen in this case. Leading us to check if the DPI is equal to 96 and the system is Windows, then assume a High DPI, else just check the DPI value. We assume a High DPI value to be greater than or equal to 144 to cover Windows and Retina macOS displays effectively.Additionally, I've updated the PImage Constructors that make use of the init method, which sets the pixelDensity variable, to use the getDisplayDPI method instead of the default value 1.
As well as the init method itself that has three parameters to use the getDisplayDPI method too.
Any feedback is welcomed.