Skip to content

Commit d21643a

Browse files
Move Windows only functionality to Win32DPIUtil
Moving methods that are consumed only by Windows from DPIUtil to Win32DPIUtil (global state handling for monitor-specific scaling). Also extract out GtkDPIUtil and CocoaDPIUtil into its standalone class
1 parent 9baef58 commit d21643a

File tree

11 files changed

+136
-111
lines changed

11 files changed

+136
-111
lines changed

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ResetMonitorSpecificScalingExtension.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ protected ResetMonitorSpecificScalingExtension() {
2525

2626
@Override
2727
public void beforeEach(ExtensionContext context) throws Exception {
28-
wasMonitorSpecificScalingActive = DPIUtil.isMonitorSpecificScalingActive();
28+
wasMonitorSpecificScalingActive = Win32DPIUtils.isMonitorSpecificScalingActive();
2929
Display.getDefault().dispose();
3030
}
3131

3232
@Override
3333
public void afterEach(ExtensionContext context) throws Exception {
34-
DPIUtil.setMonitorSpecificScaling(wasMonitorSpecificScalingActive);
34+
Win32DPIUtils.setMonitorSpecificScaling(wasMonitorSpecificScalingActive);
3535
Display.getDefault().dispose();
3636
}
3737

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/WithMonitorSpecificScalingExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private WithMonitorSpecificScalingExtension() {
2424
@Override
2525
public void beforeEach(ExtensionContext context) throws Exception {
2626
super.beforeEach(context);
27-
DPIUtil.setMonitorSpecificScaling(true);
27+
Win32DPIUtils.setMonitorSpecificScaling(true);
2828
}
2929

3030
}

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ControlWin32Tests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class ControlWin32Tests {
3636

3737
@Test
3838
public void testScaleFontCorrectlyInAutoScaleScenario() {
39-
DPIUtil.setMonitorSpecificScaling(true);
39+
Win32DPIUtils.setMonitorSpecificScaling(true);
4040
Display display = Display.getDefault();
4141

4242
assertTrue("Autoscale property is not set to true", display.isRescalingAtRuntime());
@@ -48,7 +48,7 @@ public void testScaleFontCorrectlyInAutoScaleScenario() {
4848

4949
@Test
5050
public void testSetFontWithMonitorSpecificScalingEnabled() {
51-
DPIUtil.setMonitorSpecificScaling(true);
51+
Win32DPIUtils.setMonitorSpecificScaling(true);
5252
Display display = Display.getDefault();
5353
Image colorImage = new Image(display, 10, 10);
5454
GC gc = new GC(colorImage);
@@ -59,7 +59,7 @@ public void testSetFontWithMonitorSpecificScalingEnabled() {
5959

6060
@Test
6161
public void testScaleFontCorrectlyInNoAutoScaleScenario() {
62-
DPIUtil.setMonitorSpecificScaling(false);
62+
Win32DPIUtils.setMonitorSpecificScaling(false);
6363
Display display = Display.getDefault();
6464

6565
assertFalse("Autoscale property is not set to false", display.isRescalingAtRuntime());
@@ -71,7 +71,7 @@ public void testScaleFontCorrectlyInNoAutoScaleScenario() {
7171

7272
@Test
7373
public void testDoNotScaleFontInNoAutoScaleScenarioWithLegacyFontRegistry() {
74-
DPIUtil.setMonitorSpecificScaling(false);
74+
Win32DPIUtils.setMonitorSpecificScaling(false);
7575
String originalValue = System.getProperty("swt.fontRegistry");
7676
System.setProperty("swt.fontRegistry", "legacy");
7777
try {
@@ -93,7 +93,7 @@ public void testDoNotScaleFontInNoAutoScaleScenarioWithLegacyFontRegistry() {
9393

9494
@Test
9595
public void testCorrectScaleUpUsingDifferentSetBoundsMethod() {
96-
DPIUtil.setMonitorSpecificScaling(true);
96+
Win32DPIUtils.setMonitorSpecificScaling(true);
9797
Display display = Display.getDefault();
9898
Shell shell = new Shell(display);
9999
Button button = new Button(shell, SWT.PUSH);
@@ -114,7 +114,7 @@ public void testCorrectScaleUpUsingDifferentSetBoundsMethod() {
114114
@CsvSource({ "0.5, 100, true", "1.0, 200, true", "2.0, 200, true", "2.0, quarter, true", "0.5, 100, false",
115115
"1.0, 200, false", "2.0, 200, false", "2.0, quarter, false", })
116116
public void testAutoScaleImageData(float scaleFactor, String autoScale, boolean monitorSpecificScaling) {
117-
DPIUtil.setMonitorSpecificScaling(monitorSpecificScaling);
117+
Win32DPIUtils.setMonitorSpecificScaling(monitorSpecificScaling);
118118
DPIUtil.runWithAutoScaleValue(autoScale, () -> {
119119
Display display = new Display();
120120
try {

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/DisplayWin32Test.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ class DisplayWin32Test {
1313

1414
@Test
1515
public void monitorSpecificScaling_activate() {
16-
DPIUtil.setMonitorSpecificScaling(true);
16+
Win32DPIUtils.setMonitorSpecificScaling(true);
1717
Display display = Display.getDefault();
1818
assertTrue(display.isRescalingAtRuntime());
1919
assertEquals(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, OS.GetThreadDpiAwarenessContext());
2020
}
2121

2222
@Test
2323
public void monitorSpecificScaling_deactivate() {
24-
DPIUtil.setMonitorSpecificScaling(false);
24+
Win32DPIUtils.setMonitorSpecificScaling(false);
2525
Display display = Display.getDefault();
2626
assertFalse(display.isRescalingAtRuntime());
2727
}

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,22 +1831,5 @@ public static void drawScaled(GC gc, ImageData imageData, int width, int height,
18311831
imageToDraw.dispose();
18321832
}
18331833

1834-
private final class CocoaDPIUtil {
1835-
1836-
/**
1837-
* Auto-scale down int dimensions.
1838-
*/
1839-
public static int pixelToPoint(int size) {
1840-
return DPIUtil.pixelToPoint(size, DPIUtil.getDeviceZoom());
1841-
}
1842-
1843-
/**
1844-
* Auto-scale down float dimensions.
1845-
*/
1846-
public static float pixelToPoint(float size) {
1847-
return DPIUtil.pixelToPoint(size, DPIUtil.getDeviceZoom());
1848-
}
1849-
}
1850-
18511834
}
18521835

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.eclipse.swt.internal;
2+
3+
public class CocoaDPIUtil {
4+
5+
/**
6+
* Auto-scale down int dimensions.
7+
*/
8+
public static int pixelToPoint(int size) {
9+
return DPIUtil.pixelToPoint(size, DPIUtil.getDeviceZoom());
10+
}
11+
12+
/**
13+
* Auto-scale down float dimensions.
14+
*/
15+
public static float pixelToPoint(float size) {
16+
return DPIUtil.pixelToPoint(size, DPIUtil.getDeviceZoom());
17+
}
18+
19+
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java

Lines changed: 17 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,6 @@ public static Optional<AutoScaleMethod> forString(String s) {
9696
*/
9797
private static final String SWT_AUTOSCALE_METHOD = "swt.autoScale.method";
9898

99-
/**
100-
* System property to enable to scale the application on runtime
101-
* when a DPI change is detected.
102-
* <ul>
103-
* <li>"true": the application is scaled on DPI changes</li>
104-
* <li>"false": the application will remain in its initial scaling</li>
105-
* </ul>
106-
* <b>Important:</b> This flag is only parsed and used on Win32. Setting it to
107-
* true on GTK or cocoa will be ignored.
108-
*/
109-
private static final String SWT_AUTOSCALE_UPDATE_ON_RUNTIME = "swt.autoScale.updateOnRuntime";
11099
static {
111100
autoScaleValue = System.getProperty (SWT_AUTOSCALE);
112101

@@ -115,6 +104,13 @@ public static Optional<AutoScaleMethod> forString(String s) {
115104
autoScaleMethod = AUTO_SCALE_METHOD_SETTING != AutoScaleMethod.AUTO ? AUTO_SCALE_METHOD_SETTING : AutoScaleMethod.NEAREST;
116105
}
117106

107+
static String getAutoScaleValue() {
108+
return autoScaleValue;
109+
}
110+
111+
static void setAutoScaleValue(String autoScaleValueArg) {
112+
autoScaleValue = autoScaleValueArg;
113+
}
118114

119115
public static int pixelToPoint(int size, int zoom) {
120116
if (zoom == 100 || size == SWT.DEFAULT) return size;
@@ -327,20 +323,23 @@ public static void setDeviceZoom (int nativeDeviceZoom) {
327323
// in GTK, preserve the current method when switching to a 100% monitor
328324
boolean preserveScalingMethod = SWT.getPlatform().equals("gtk") && deviceZoom == 100;
329325
if (!preserveScalingMethod && AUTO_SCALE_METHOD_SETTING == AutoScaleMethod.AUTO) {
330-
if (sholdUseSmoothScaling()) {
326+
if (useSmoothScalingByDefaultProvider.shouldUseSmoothScaling()) {
331327
autoScaleMethod = AutoScaleMethod.SMOOTH;
332328
} else {
333329
autoScaleMethod = AutoScaleMethod.NEAREST;
334330
}
335331
}
336332
}
337333

338-
private static boolean sholdUseSmoothScaling() {
339-
return switch (SWT.getPlatform()) {
340-
case "gtk" -> deviceZoom / 100 * 100 != deviceZoom;
341-
case "win32" -> isMonitorSpecificScalingActive();
342-
default -> false;
343-
};
334+
@FunctionalInterface
335+
interface UseSmoothScalingProvider {
336+
boolean shouldUseSmoothScaling();
337+
}
338+
339+
private static UseSmoothScalingProvider useSmoothScalingByDefaultProvider = () -> false;
340+
341+
static void setUseSmoothScalingByDefaultProvider(UseSmoothScalingProvider provider) {
342+
useSmoothScalingByDefaultProvider = provider;
344343
}
345344

346345
public static int getZoomForAutoscaleProperty (int nativeDeviceZoom) {
@@ -388,54 +387,4 @@ public static void runWithAutoScaleValue(String autoScaleValue, Runnable runnabl
388387
}
389388
}
390389

391-
public static void setMonitorSpecificScaling(boolean activate) {
392-
System.setProperty(SWT_AUTOSCALE_UPDATE_ON_RUNTIME, Boolean.toString(activate));
393-
}
394-
395-
public static boolean isMonitorSpecificScalingActive() {
396-
boolean updateOnRuntimeValue = Boolean.getBoolean (SWT_AUTOSCALE_UPDATE_ON_RUNTIME);
397-
return updateOnRuntimeValue;
398-
}
399-
400-
public static void setAutoScaleForMonitorSpecificScaling() {
401-
boolean isDefaultAutoScale = autoScaleValue == null;
402-
if (isDefaultAutoScale) {
403-
autoScaleValue = "quarter";
404-
} else if (!isSupportedAutoScaleForMonitorSpecificScaling()) {
405-
throw new SWTError(SWT.ERROR_NOT_IMPLEMENTED,
406-
"monitor-specific scaling is only implemented for auto-scale values \"quarter\", \"exact\", \"false\" or a concrete zoom value, but \""
407-
+ autoScaleValue + "\" has been specified");
408-
}
409-
}
410-
411-
/**
412-
* Monitor-specific scaling on Windows only supports auto-scale modes in which
413-
* all elements (font, images, control bounds etc.) are scaled equally or almost
414-
* equally. The previously default mode "integer"/"integer200", which rounded
415-
* the scale factor for everything but fonts to multiples of 100, is complex and
416-
* difficult to realize with monitor-specific rescaling of UI elements. Since a
417-
* uniform scale factor for everything should perspectively be used anyway,
418-
* there will be support for complex auto-scale modes for monitor-specific
419-
* scaling.
420-
*
421-
* The supported modes are "quarter" and "exact" or explicit zoom values given
422-
* by the value itself or "false". Every other value will be treated as
423-
* "integer"/"integer200" and is thus not supported.
424-
*/
425-
private static boolean isSupportedAutoScaleForMonitorSpecificScaling() {
426-
if (autoScaleValue == null) {
427-
return false;
428-
}
429-
switch (autoScaleValue.toLowerCase()) {
430-
case "false", "quarter", "exact": return true;
431-
}
432-
try {
433-
Integer.parseInt(autoScaleValue);
434-
return true;
435-
} catch (NumberFormatException e) {
436-
// unsupported value, use default
437-
}
438-
return false;
439-
}
440-
441390
}

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,17 +1592,4 @@ public static void drawScaled(GC gc, ImageData imageData, int width, int height,
15921592
imageToDraw.dispose();
15931593
}
15941594

1595-
private final class GtkDPIUtil {
1596-
1597-
/**
1598-
* Auto-scale up ImageData to device zoom that is at 100%.
1599-
*/
1600-
public static ImageData pointToPixel (Device device, final ImageData imageData) {
1601-
int imageDataZoomFactor = 100;
1602-
if (DPIUtil.getDeviceZoom() == imageDataZoomFactor || imageData == null || (device != null && !device.isAutoScalable())) return imageData;
1603-
float scaleFactor = (float) DPIUtil.getDeviceZoom() / imageDataZoomFactor;
1604-
return DPIUtil.autoScaleImageData(device, imageData, scaleFactor);
1605-
}
1606-
}
1607-
16081595
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.eclipse.swt.internal;
2+
3+
import org.eclipse.swt.graphics.*;
4+
5+
public class GtkDPIUtil {
6+
static {
7+
DPIUtil.setUseSmoothScalingByDefaultProvider(() -> {
8+
return DPIUtil.getDeviceZoom() / 100 * 100 != DPIUtil.getDeviceZoom();
9+
});
10+
}
11+
12+
/**
13+
* Auto-scale up ImageData to device zoom that is at 100%.
14+
*/
15+
public static ImageData pointToPixel (Device device, final ImageData imageData) {
16+
int imageDataZoomFactor = 100;
17+
if (DPIUtil.getDeviceZoom() == imageDataZoomFactor || imageData == null || (device != null && !device.isAutoScalable())) return imageData;
18+
float scaleFactor = (float) DPIUtil.getDeviceZoom() / imageDataZoomFactor;
19+
return DPIUtil.autoScaleImageData(device, imageData, scaleFactor);
20+
}
21+
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@
3232
* @noreference This class is not intended to be referenced by clients
3333
*/
3434
public class Win32DPIUtils {
35+
/**
36+
* System property to enable to scale the application on runtime
37+
* when a DPI change is detected.
38+
* <ul>
39+
* <li>"true": the application is scaled on DPI changes</li>
40+
* <li>"false": the application will remain in its initial scaling</li>
41+
* </ul>
42+
* <b>Important:</b> This flag is only parsed and used on Win32. Setting it to
43+
* true on GTK or cocoa will be ignored.
44+
*/
45+
private static final String SWT_AUTOSCALE_UPDATE_ON_RUNTIME = "swt.autoScale.updateOnRuntime";
46+
47+
static {
48+
DPIUtil.setUseSmoothScalingByDefaultProvider(() -> isMonitorSpecificScalingActive());
49+
}
50+
3551
public static boolean setDPIAwareness(int desiredDpiAwareness) {
3652
if (desiredDpiAwareness == OS.GetThreadDpiAwarenessContext()) {
3753
return true;
@@ -236,6 +252,56 @@ public static Rectangle pointToPixel(Drawable drawable, Rectangle rect, int zoom
236252
return pointToPixel (rect, zoom);
237253
}
238254

255+
public static void setMonitorSpecificScaling(boolean activate) {
256+
System.setProperty(SWT_AUTOSCALE_UPDATE_ON_RUNTIME, Boolean.toString(activate));
257+
}
258+
259+
public static void setAutoScaleForMonitorSpecificScaling() {
260+
boolean isDefaultAutoScale = DPIUtil.getAutoScaleValue() == null;
261+
if (isDefaultAutoScale) {
262+
DPIUtil.setAutoScaleValue("quarter");
263+
} else if (!isSupportedAutoScaleForMonitorSpecificScaling()) {
264+
throw new SWTError(SWT.ERROR_NOT_IMPLEMENTED,
265+
"monitor-specific scaling is only implemented for auto-scale values \"quarter\", \"exact\", \"false\" or a concrete zoom value, but \""
266+
+ DPIUtil.getAutoScaleValue() + "\" has been specified");
267+
}
268+
}
269+
270+
/**
271+
* Monitor-specific scaling on Windows only supports auto-scale modes in which
272+
* all elements (font, images, control bounds etc.) are scaled equally or almost
273+
* equally. The previously default mode "integer"/"integer200", which rounded
274+
* the scale factor for everything but fonts to multiples of 100, is complex and
275+
* difficult to realize with monitor-specific rescaling of UI elements. Since a
276+
* uniform scale factor for everything should perspectively be used anyway,
277+
* there will be support for complex auto-scale modes for monitor-specific
278+
* scaling.
279+
*
280+
* The supported modes are "quarter" and "exact" or explicit zoom values given
281+
* by the value itself or "false". Every other value will be treated as
282+
* "integer"/"integer200" and is thus not supported.
283+
*/
284+
private static boolean isSupportedAutoScaleForMonitorSpecificScaling() {
285+
if (DPIUtil.getAutoScaleValue() == null) {
286+
return false;
287+
}
288+
switch (DPIUtil.getAutoScaleValue().toLowerCase()) {
289+
case "false", "quarter", "exact": return true;
290+
}
291+
try {
292+
Integer.parseInt(DPIUtil.getAutoScaleValue());
293+
return true;
294+
} catch (NumberFormatException e) {
295+
// unsupported value, use default
296+
}
297+
return false;
298+
}
299+
300+
public static boolean isMonitorSpecificScalingActive() {
301+
boolean updateOnRuntimeValue = Boolean.getBoolean (SWT_AUTOSCALE_UPDATE_ON_RUNTIME);
302+
return updateOnRuntimeValue;
303+
}
304+
239305
/**
240306
* AutoScale ImageDataProvider.
241307
*/

0 commit comments

Comments
 (0)