Skip to content

Commit 0780f14

Browse files
Limit autoscale mode to quarter and exact only
swt applications will be limited to use autoscale modes quarter and exact only otherwise user will see an error message stating the incompatibility. Also the tests testing other autoscale values have been removed.
1 parent 93d5d62 commit 0780f14

File tree

3 files changed

+38
-33
lines changed

3 files changed

+38
-33
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public void testCorrectScaleUpUsingDifferentSetBoundsMethod() {
111111
}
112112

113113
@ParameterizedTest
114-
@CsvSource({ "0.5, 100, true", "1.0, 200, true", "2.0, 200, true", "2.0, quarter, true", "0.5, 100, false",
114+
@CsvSource({ "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) {
117117
Win32DPIUtils.setMonitorSpecificScaling(monitorSpecificScaling);

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ public class DPIUtil {
3434
private static int deviceZoom = 100;
3535
private static int nativeDeviceZoom = 100;
3636

37+
/**
38+
* System property that enforces to use autoScale value despite incompatibility
39+
* For e.g. Monitor-specific scaling with int200 autoscale value
40+
*/
41+
private static final String SWT_AUTOSCALE_DISABLE_COMPATIBILITY_CHECK = "swt.autoScale.force";
42+
43+
private static final Set<String> ALLOWED_AUTOSCALE_VALUES_FOR_UPDATE_ON_RUNTIME = Set.of("quarter", "exact");
44+
3745
private static enum AutoScaleMethod { AUTO, NEAREST, SMOOTH;
3846

3947
public static Optional<AutoScaleMethod> forString(String s) {
@@ -114,6 +122,34 @@ static void setAutoScaleValue(String autoScaleValueArg) {
114122
autoScaleValue = autoScaleValueArg;
115123
}
116124

125+
/**
126+
* Returns {@code true} only if the current setup is compatible
127+
* with monitor-specific scaling. Returns {@code false} if:
128+
* <ul>
129+
* <li>Not running on Windows</li>
130+
* <li>The current auto-scale mode is incompatible</li>
131+
* </ul>
132+
*
133+
* <p>Allowed values: {@code quarter}, {@code exact}.
134+
*
135+
*/
136+
public static boolean isSetupCompatibleToMonitorSpecificScaling() {
137+
// Per-monitor DPI supported only on Windows
138+
if (!"win32".equals(SWT.getPlatform())) {
139+
return false;
140+
}
141+
142+
// Default means: treat as "quarter" (compatible)
143+
if (autoScaleValue == null || "true".equalsIgnoreCase(System.getProperty(SWT_AUTOSCALE_DISABLE_COMPATIBILITY_CHECK))) {
144+
return true;
145+
}
146+
147+
String value = autoScaleValue.toLowerCase(Locale.ROOT);
148+
149+
// Compatible only if one of the known values
150+
return ALLOWED_AUTOSCALE_VALUES_FOR_UPDATE_ON_RUNTIME.contains(value);
151+
}
152+
117153
public static boolean isMonitorSpecificScalingActive() {
118154
boolean updateOnRuntimeValue = Boolean.getBoolean (DPIUtil.SWT_AUTOSCALE_UPDATE_ON_RUNTIME);
119155
return updateOnRuntimeValue;

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

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -270,44 +270,13 @@ public static void setAutoScaleForMonitorSpecificScaling() {
270270
boolean isDefaultAutoScale = DPIUtil.getAutoScaleValue() == null;
271271
if (isDefaultAutoScale) {
272272
DPIUtil.setAutoScaleValue("quarter");
273-
} else if (!isSupportedAutoScaleForMonitorSpecificScaling()) {
273+
} else if (!DPIUtil.isSetupCompatibleToMonitorSpecificScaling()) {
274274
throw new SWTError(SWT.ERROR_NOT_IMPLEMENTED,
275275
"monitor-specific scaling is only implemented for auto-scale values \"quarter\", \"exact\", \"false\" or a concrete zoom value, but \""
276276
+ DPIUtil.getAutoScaleValue() + "\" has been specified");
277277
}
278278
}
279279

280-
/**
281-
* Monitor-specific scaling on Windows only supports auto-scale modes in which
282-
* all elements (font, images, control bounds etc.) are scaled equally or almost
283-
* equally. The previously default mode "integer"/"integer200", which rounded
284-
* the scale factor for everything but fonts to multiples of 100, is complex and
285-
* difficult to realize with monitor-specific rescaling of UI elements. Since a
286-
* uniform scale factor for everything should perspectively be used anyway,
287-
* there will be support for complex auto-scale modes for monitor-specific
288-
* scaling.
289-
*
290-
* The supported modes are "quarter" and "exact" or explicit zoom values given
291-
* by the value itself or "false". Every other value will be treated as
292-
* "integer"/"integer200" and is thus not supported.
293-
*/
294-
private static boolean isSupportedAutoScaleForMonitorSpecificScaling() {
295-
if (DPIUtil.getAutoScaleValue() == null) {
296-
return false;
297-
}
298-
switch (DPIUtil.getAutoScaleValue().toLowerCase()) {
299-
case "false", "quarter", "exact": return true;
300-
}
301-
try {
302-
Integer.parseInt(DPIUtil.getAutoScaleValue());
303-
return true;
304-
} catch (NumberFormatException e) {
305-
// unsupported value, use default
306-
}
307-
return false;
308-
}
309-
310-
311280
public static int getPrimaryMonitorZoomAtStartup() {
312281
long hDC = OS.GetDC(0);
313282
int dpi = OS.GetDeviceCaps(hDC, OS.LOGPIXELSX);

0 commit comments

Comments
 (0)