From 21aeca34962d9fb07f678fd0221a173c9ada2758 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Mon, 13 Jan 2025 21:28:59 +0100 Subject: [PATCH] [Win] Disallow autoscale mode "integer" for monitor-specific scaling The default auto-scale value is "integer"/"integer200", which makes everything in the UI except fonts not scale according to the actual native zoom value but according to a value rounded to 100 or 200. While most code performing adaptations to zoom considers this for a static zoom value applied to the whole application, it leads to hard-to-resolve issues when scaling every shell according to the current monitor's zoom. Since that autoscale mode is complex and should be replaced by uniform scaling of everything (in particular when images are based on vector graphics that can sharply be rendered for every zoom factor) anyway, this is not to be supported by the monitor-specific scaling feature currently being introduced for Windows. With this change, that mode will thus be limited to reasonable autoscale modes like "quarter" and "exact" or ones fixing the zoom value like specifying an explicit value or "false". --- .../org/eclipse/swt/internal/DPIUtil.java | 26 ++++++++++++++++++- .../org/eclipse/swt/widgets/Display.java | 3 ++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java index 8d631342e8d..ebe0044a767 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java @@ -654,10 +654,34 @@ public static int getZoomForAutoscaleProperty (int nativeDeviceZoom) { return zoom; } -public static boolean isAutoScaleOnRuntimeActive() { +public static boolean isMonitorSpecificScalingActive() { return autoScaleOnRuntime; } +public static void setAutoScaleForMonitorSpecificScaling() { + boolean isDefaultAutoScale = autoScaleValue == null; + if (isDefaultAutoScale) { + autoScaleValue = "quarter"; + } else if (!isSupportedAutoScaleForMonitorSpecificScaling()) { + throw new SWTError(SWT.ERROR_NOT_IMPLEMENTED, + "monitor-specific scaling is only implemented for auto-scale values \"quarter\", \"exact\", \"false\" or a concrete zoom value, but \"" + + autoScaleValue + "\" has been specified"); + } +} + +private static boolean isSupportedAutoScaleForMonitorSpecificScaling() { + switch (autoScaleValue) { + case "false", "quarter", "exact": return true; + } + try { + Integer.parseInt(autoScaleValue); + return true; + } catch (NumberFormatException e) { + // unsupported value, use default + } + return false; +} + /** * AutoScale ImageDataProvider. */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 70576d85cea..cc19d1cf3f3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -948,8 +948,9 @@ public void close () { protected void create (DeviceData data) { checkSubclass (); checkDisplay (thread = Thread.currentThread (), true); - if (DPIUtil.isAutoScaleOnRuntimeActive()) { + if (DPIUtil.isMonitorSpecificScalingActive()) { setRescalingAtRuntime(true); + DPIUtil.setAutoScaleForMonitorSpecificScaling(); } createDisplay (data); register (this);