From 22e90bffd2e5847ec8387552e04d636dd26133a7 Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Mon, 2 Dec 2019 12:49:26 -0500 Subject: [PATCH 1/4] Refactored DPI to zoom level Prepared to move to zoom level being calculated in the platform instead of DPI being returned. This is because zoom level may be distinct from the system DPI and operating systems may report a DPI of 96 while also requesting a display zooming of 125%. Therefore, using the system display scaling is preferred to using DPI after JEP 263. --- app/src/processing/app/Platform.java | 8 ++--- .../app/platform/DefaultPlatform.java | 34 +++++++++++++++++-- .../app/platform/WindowsPlatform.java | 25 ++++++++++---- app/src/processing/app/ui/Toolkit.java | 2 +- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index d2c58921e..afa36316a 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -411,9 +411,9 @@ public class Platform { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - - static public int getSystemDPI() { - return inst.getSystemDPI(); + + static public float getSystemZoom() { + return inst.getSystemZoom(); } + } diff --git a/app/src/processing/app/platform/DefaultPlatform.java b/app/src/processing/app/platform/DefaultPlatform.java index ac11db87f..9e6ecc481 100644 --- a/app/src/processing/app/platform/DefaultPlatform.java +++ b/app/src/processing/app/platform/DefaultPlatform.java @@ -54,6 +54,8 @@ import processing.app.Preferences; public class DefaultPlatform { Base base; + private final float ZOOM_DEFAULT_SIZING = 1; + private final int DEFAULT_DPI = 96; public void initBase(Base base) { this.base = base; @@ -157,8 +159,34 @@ public class DefaultPlatform { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - public int getSystemDPI() { - return 96; + /** + * Get the zoom or display scaling requested by the operating system. + * + *

+ * Get the operating system zoom setting that Processing may use to resize + * internal elements depending on user preferences. Note that some operating + * systems will perform zooming in a way that is transparent to the + * the applications. If that is the case, this will return 1. Otherwise, + * the operating system will not automatically resize UI elements and this + * will return a value other than 1, meaning that Processing may need to + * resize elements on its own depending on user preferences. + *

+ * + *

+ * Note that this may be distinct from the system DPI and some operating + * systems may report a DPI of 96 while also requesting a display zooming of + * 125%. However, others may not report a "display scaling" but provide a + * DPI of 120 when the elements should have a 125% zoom. This will use the + * preferred method of determining the appropriate zoom given the platform + * in use. Using this system display scaling percentage approach instead of + * returning DPI directly is preferred after JEP 263. + *

+ * + * @return The zoom level where 1 means 100% (no zoom) and 125% means 25% + * additional zoom. + */ + public float getSystemZoom() { + return ZOOM_DEFAULT_SIZING; } + } diff --git a/app/src/processing/app/platform/WindowsPlatform.java b/app/src/processing/app/platform/WindowsPlatform.java index 25cbf2468..8e68ecd21 100644 --- a/app/src/processing/app/platform/WindowsPlatform.java +++ b/app/src/processing/app/platform/WindowsPlatform.java @@ -25,11 +25,13 @@ package processing.app.platform; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.util.Optional; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.platform.win32.Shell32Util; import com.sun.jna.platform.win32.ShlObj; +import com.sun.jna.platform.win32.GDI32; import processing.app.Base; import processing.app.Messages; @@ -61,10 +63,12 @@ public class WindowsPlatform extends DefaultPlatform { "\\" + APP_NAME.toLowerCase() + ".exe \"%1\""; static final String REG_DOC = APP_NAME + ".Document"; - // Starting with Java 9, the scaling is done automatically. If DPI is - // used to scaling within the application, one ends up with 2x the - // expected scale. See JEP 263. - private static final int WINDOWS_NATIVE_DPI = 96; + private Optional cachedDisplayScaling; + + public WindowsPlatform() { + super(); + cachedDisplayScaling = Optional.empty(); + } public void initBase(Base base) { super.initBase(base); @@ -629,10 +633,17 @@ public class WindowsPlatform extends DefaultPlatform { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + public float getSystemZoom() { + if (cachedDisplayScaling.isEmpty()) { + cachedDisplayScaling = Optional.of(calculateSystemZoom()); + } - public int getSystemDPI() { - // Note that this is supported "natively" within Java - See JEP 263. - return WINDOWS_NATIVE_DPI; + return cachedDisplayScaling.get(); + } + + private float calculateSystemZoom() { + // TODO + return 1; } } diff --git a/app/src/processing/app/ui/Toolkit.java b/app/src/processing/app/ui/Toolkit.java index e35cc5c43..72afd481f 100644 --- a/app/src/processing/app/ui/Toolkit.java +++ b/app/src/processing/app/ui/Toolkit.java @@ -851,7 +851,7 @@ public class Toolkit { static private float parseZoom() { if (Preferences.getBoolean("editor.zoom.auto")) { - float newZoom = Platform.getSystemDPI() / 96f; + float newZoom = Platform.getSystemZoom(); String percentSel = ((int) (newZoom*100)) + "%"; Preferences.set("editor.zoom", percentSel); return newZoom; From f9df4ea6eaa62037c7a80cfc5aa7772c66cb15e0 Mon Sep 17 00:00:00 2001 From: Sam Pottinger Date: Mon, 2 Dec 2019 20:21:07 -0700 Subject: [PATCH 2/4] Attempted implementation of JNA based display scaling on windows. --- .../app/platform/WindowsPlatform.java | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/platform/WindowsPlatform.java b/app/src/processing/app/platform/WindowsPlatform.java index 8e68ecd21..2077caf97 100644 --- a/app/src/processing/app/platform/WindowsPlatform.java +++ b/app/src/processing/app/platform/WindowsPlatform.java @@ -22,6 +22,7 @@ package processing.app.platform; +import java.awt.*; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -29,9 +30,7 @@ import java.util.Optional; import com.sun.jna.Library; import com.sun.jna.Native; -import com.sun.jna.platform.win32.Shell32Util; -import com.sun.jna.platform.win32.ShlObj; -import com.sun.jna.platform.win32.GDI32; +import com.sun.jna.platform.win32.*; import processing.app.Base; import processing.app.Messages; @@ -63,6 +62,10 @@ public class WindowsPlatform extends DefaultPlatform { "\\" + APP_NAME.toLowerCase() + ".exe \"%1\""; static final String REG_DOC = APP_NAME + ".Document"; + private static final float RESOLUTION_AT_NO_SCALE = 96; + private static final int VERTRES = 10; + private static final int DESKTOPVERTRES = 117; + private Optional cachedDisplayScaling; public WindowsPlatform() { @@ -642,8 +645,19 @@ public class WindowsPlatform extends DefaultPlatform { } private float calculateSystemZoom() { - // TODO - return 1; + WinDef.HDC hdc = GDI32.INSTANCE.CreateCompatibleDC(null); + + if (hdc == null) { + float resolution = Toolkit.getDefaultToolkit().getScreenResolution(); + return resolution / RESOLUTION_AT_NO_SCALE; + } + + float vertualResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, VERTRES); + float logicalResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, DESKTOPVERTRES); + + GDI32.INSTANCE.DeleteDC(hdc); + + return logicalResolution / vertualResolution; } } From 05f78c94f8bc9e79fb672f4e71618cb5701f3840 Mon Sep 17 00:00:00 2001 From: A Pottinger Date: Thu, 26 Dec 2019 10:16:51 -0800 Subject: [PATCH 3/4] Fixed typo in WindowsPlatform var spelling. --- app/src/processing/app/platform/WindowsPlatform.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/platform/WindowsPlatform.java b/app/src/processing/app/platform/WindowsPlatform.java index 2077caf97..2bc33f6fc 100644 --- a/app/src/processing/app/platform/WindowsPlatform.java +++ b/app/src/processing/app/platform/WindowsPlatform.java @@ -652,12 +652,12 @@ public class WindowsPlatform extends DefaultPlatform { return resolution / RESOLUTION_AT_NO_SCALE; } - float vertualResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, VERTRES); + float virtualResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, VERTRES); float logicalResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, DESKTOPVERTRES); GDI32.INSTANCE.DeleteDC(hdc); - return logicalResolution / vertualResolution; + return logicalResolution / virtualResolution; } } From 546b4122ad0e412c80fce2cb48f323ae3c3a2db2 Mon Sep 17 00:00:00 2001 From: A Samuel Pottinger Date: Tue, 7 Jan 2020 08:37:28 -0800 Subject: [PATCH 4/4] Fix typo in DefaultPlatform getSystemZoom comment --- app/src/processing/app/platform/DefaultPlatform.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/processing/app/platform/DefaultPlatform.java b/app/src/processing/app/platform/DefaultPlatform.java index 9e6ecc481..bfdb5ad8e 100644 --- a/app/src/processing/app/platform/DefaultPlatform.java +++ b/app/src/processing/app/platform/DefaultPlatform.java @@ -182,8 +182,8 @@ public class DefaultPlatform { * returning DPI directly is preferred after JEP 263. *

* - * @return The zoom level where 1 means 100% (no zoom) and 125% means 25% - * additional zoom. + * @return The zoom level where 1.0 means 100% (no zoom) and 1.25 means + * 125% (25% additional zoom). */ public float getSystemZoom() { return ZOOM_DEFAULT_SIZING;