From e0b4fe9e8cca4d5bd05ededb3fa81f60a63584ae Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 15 Jan 2025 11:57:55 +0100 Subject: [PATCH] Remove type hierarchy of Win32AutoscaleTestBase Auto-scale related, Windows-specific tests are currently organized in a class hierarchy based on Win32AutoscaleTestBase. This leads to unnecessarily initialized objects (e.g., shells or displays without any need for a test) and the strict necessity to use activated monitor-specific scaling in actual tests or to revert the setup logic affecting that value by hand. This change removes the Win32AutoscaleTestBase and moves the common test functionality into extensions (PlatformSpecificExecution, ResetMonitorSpecificScaling and WithMonitorSpecificScaling) as well as the utility class DPITestUtil. --- .../eclipse/swt/graphics/GCWin32Tests.java | 12 ++- .../eclipse/swt/graphics/PathWin32Tests.java | 9 ++- .../swt/graphics/RegionWin32Tests.java | 8 +- .../swt/graphics/TextLayoutWin32Tests.java | 13 +++- .../swt/graphics/TransformWin32Tests.java | 8 +- ...utoscaleTestBase.java => DPITestUtil.java} | 29 ++----- .../internal/DefaultSWTFontRegistryTests.java | 8 +- ...> PlatformSpecificExecutionExtension.java} | 11 ++- .../ResetMonitorSpecificScalingExtension.java | 38 ++++++++++ .../internal/ScalingSWTFontRegistryTests.java | 7 +- .../WithMonitorSpecificScalingExtension.java | 30 ++++++++ .../swt/widgets/ControlWin32Tests.java | 76 ++++++++++--------- .../eclipse/swt/widgets/DisplayWin32Test.java | 7 +- .../eclipse/swt/widgets/WidgetWin32Tests.java | 50 +++++++----- .../org/eclipse/swt/internal/DPIUtil.java | 4 + 15 files changed, 205 insertions(+), 105 deletions(-) rename bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/{Win32AutoscaleTestBase.java => DPITestUtil.java} (60%) rename bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/{PlatformSpecificExecution.java => PlatformSpecificExecutionExtension.java} (77%) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ResetMonitorSpecificScalingExtension.java create mode 100644 bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/WithMonitorSpecificScalingExtension.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java index ed15d8a7e19..d21c6ab0e42 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java @@ -20,12 +20,18 @@ import org.eclipse.swt.*; import org.eclipse.swt.internal.*; +import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class GCWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class GCWin32Tests { @Test public void gcZoomLevelMustChangeOnShellZoomChange() { + Shell shell = new Shell(Display.getDefault()); + CompletableFuture gcNativeZoom = new CompletableFuture<>(); CompletableFuture scaledGcNativeZoom = new CompletableFuture<>(); int zoom = DPIUtil.getDeviceZoom(); @@ -42,7 +48,7 @@ public void gcZoomLevelMustChangeOnShellZoomChange() { assertEquals("GCData must have a zoom level equal to the actual zoom level of the widget/shell", DPIUtil.getNativeDeviceZoom(), (int) gcNativeZoom.join()); int newSWTZoom = zoom * 2; - changeDPIZoom(newSWTZoom); + DPITestUtil.changeDPIZoom(shell, newSWTZoom); isScaled.set(true); shell.setVisible(false); shell.setVisible(true); @@ -52,6 +58,8 @@ public void gcZoomLevelMustChangeOnShellZoomChange() { @Test public void drawnElementsShouldScaleUpToTheRightZoomLevel() { + Shell shell = new Shell(Display.getDefault()); + int zoom = DPIUtil.getDeviceZoom(); int scalingFactor = 2; GC gc = GC.win32_new(shell, new GCData()); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/PathWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/PathWin32Tests.java index 66a5a29b6fd..523102cd712 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/PathWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/PathWin32Tests.java @@ -19,15 +19,20 @@ import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.gdip.*; +import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class PathWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class PathWin32Tests { int zoom = 100; int scaledZoom = 200; @Test public void testPathMustBeScaledOnZoomLevelChange() { + Display display = Display.getDefault(); Path path = new Path(display); path.addArc(0, 0, 10, 10, 0, 90); PathData pathData = path.getPathData(); @@ -40,6 +45,7 @@ public void testPathMustBeScaledOnZoomLevelChange() { @Test public void testHandlesExistForEachZoomLevelInHashMap() { + Display display = Display.getDefault(); DPIUtil.setDeviceZoom(zoom); Path path = new Path(display); path.addArc(0, 0, 10, 10, 0, 90); @@ -50,6 +56,7 @@ public void testHandlesExistForEachZoomLevelInHashMap() { @Test public void testBoundsAreScaledWRTZoomLevel() { + Display display = Display.getDefault(); DPIUtil.setDeviceZoom(zoom); int scalingFactor = scaledZoom/zoom; Path path = new Path(display); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/RegionWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/RegionWin32Tests.java index 48f68684b36..0526268635b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/RegionWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/RegionWin32Tests.java @@ -17,12 +17,18 @@ import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class RegionWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class RegionWin32Tests { @Test public void testRegionMustBeScaledOnHandleOfScaledZoomLevel() { + Display display = Display.getDefault(); + int zoom = DPIUtil.getDeviceZoom(); int scalingFactor = 2; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TextLayoutWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TextLayoutWin32Tests.java index 4baa8920881..33957562d0a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TextLayoutWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TextLayoutWin32Tests.java @@ -17,13 +17,19 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import org.eclipse.swt.internal.*; +import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class TextLayoutWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class TextLayoutWin32Tests { final static String text = "This is a text for testing."; @Test public void testGetBoundPublicAPIshouldReturnTheSameValueRegardlessOfZoomLevel() { + Display display = Display.getDefault(); + final TextLayout layout = new TextLayout(display); GCData unscaledData = new GCData(); unscaledData.nativeZoom = DPIUtil.getNativeDeviceZoom(); @@ -44,6 +50,9 @@ public void testGetBoundPublicAPIshouldReturnTheSameValueRegardlessOfZoomLevel() @Test public void testCalculateGetBoundsWithVerticalIndent() { + Display display = Display.getDefault(); + Shell shell = new Shell(display); + TextLayout layout = new TextLayout(display); layout.setVerticalIndent(16); layout.setText(text); @@ -51,7 +60,7 @@ public void testCalculateGetBoundsWithVerticalIndent() { int scalingFactor = 2; int newZoom = DPIUtil.getNativeDeviceZoom() * scalingFactor; - changeDPIZoom(newZoom); + DPITestUtil.changeDPIZoom(shell, newZoom); TextLayout scaledLayout = new TextLayout(display); scaledLayout.setVerticalIndent(16); scaledLayout.setText(text); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TransformWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TransformWin32Tests.java index aee256616c1..c675364382d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TransformWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/TransformWin32Tests.java @@ -18,12 +18,17 @@ import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.gdip.*; +import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class TransformWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class TransformWin32Tests { @Test public void testShouldHaveDifferentHandlesAtDifferentZoomLevels() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); Transform transform = new Transform(display); long scaledHandle = transform.getHandle(zoom * 2); @@ -34,6 +39,7 @@ public void testShouldHaveDifferentHandlesAtDifferentZoomLevels() { @Test public void testScaledTrasformMustHaveScaledValues() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); Transform transform = new Transform(display, 0, 0, 0, 0, 4, 2); float[] elements = new float[6]; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/Win32AutoscaleTestBase.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DPITestUtil.java similarity index 60% rename from bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/Win32AutoscaleTestBase.java rename to bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DPITestUtil.java index 2ce05ff4f62..c278fc9bef7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/Win32AutoscaleTestBase.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DPITestUtil.java @@ -14,35 +14,16 @@ package org.eclipse.swt.internal; import org.eclipse.swt.widgets.*; -import org.junit.jupiter.api.*; -public abstract class Win32AutoscaleTestBase { - protected Display display; - protected Shell shell; +public final class DPITestUtil { - @BeforeAll - public static void assumeIsFittingPlatform() { - PlatformSpecificExecution.assumeIsFittingPlatform(); + private DPITestUtil() { } - @BeforeEach - public void setUpTest() { - display = Display.getDefault(); - display.setRescalingAtRuntime(true); - shell = new Shell(display); - } - - @AfterEach - public void tearDownTest() { - if (shell != null) { - shell.dispose(); - } - display.dispose(); - } - - protected void changeDPIZoom (int nativeZoom) { + public static void changeDPIZoom (Shell shell, int nativeZoom) { DPIUtil.setDeviceZoom(nativeZoom); float scalingFactor = 1f * DPIUtil.getZoomForAutoscaleProperty(nativeZoom) / DPIUtil.getZoomForAutoscaleProperty(shell.nativeZoom); DPIZoomChangeRegistry.applyChange(shell, nativeZoom, scalingFactor); } -} \ No newline at end of file + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DefaultSWTFontRegistryTests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DefaultSWTFontRegistryTests.java index bd3c345e06b..4dcaead797c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DefaultSWTFontRegistryTests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/DefaultSWTFontRegistryTests.java @@ -20,17 +20,14 @@ import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; +@ExtendWith(PlatformSpecificExecutionExtension.class) class DefaultSWTFontRegistryTests { private static String TEST_FONT = "Helvetica"; private Display display; private SWTFontRegistry fontRegistry; - @BeforeAll - public static void assumeIsFittingPlatform() { - PlatformSpecificExecution.assumeIsFittingPlatform(); - } - @BeforeEach public void setUp() { this.display = Display.getDefault(); @@ -42,6 +39,7 @@ public void tearDown() { if (this.fontRegistry != null) { this.fontRegistry.dispose(); } + display.dispose(); } @Test diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecution.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecutionExtension.java similarity index 77% rename from bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecution.java rename to bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecutionExtension.java index 1b66bc0a07c..5c7e6d93c5b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecution.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/PlatformSpecificExecutionExtension.java @@ -14,11 +14,14 @@ import java.net.*; -public final class PlatformSpecificExecution { - private PlatformSpecificExecution() { +import org.junit.jupiter.api.extension.*; + +public final class PlatformSpecificExecutionExtension implements BeforeAllCallback { + private PlatformSpecificExecutionExtension() { } - public static void assumeIsFittingPlatform() { + @Override + public void beforeAll(ExtensionContext context) throws Exception { assumeTrue("test is specific for Windows", isFittingOS()); assumeTrue("architecture of platform does not match", isFittingArchitecture()); } @@ -28,7 +31,7 @@ private static boolean isFittingOS() { } private static boolean isFittingArchitecture() { - Class thisClass = PlatformSpecificExecution.class; + Class thisClass = PlatformSpecificExecutionExtension.class; String thisClassResourcePath = thisClass.getName().replace('.', '/') + ".class"; URL thisClassURL = thisClass.getClassLoader().getResource(thisClassResourcePath); //$NON-NLS-1$ return thisClassURL.toString().contains(Library.arch()); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ResetMonitorSpecificScalingExtension.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ResetMonitorSpecificScalingExtension.java new file mode 100644 index 00000000000..a07812ce748 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ResetMonitorSpecificScalingExtension.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2025 Vector Informatik GmbH + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.swt.internal; + +import org.eclipse.swt.widgets.*; +import org.junit.jupiter.api.extension.*; + +/** + * Resets the monitor-specific scaling configuration after the test has been executed. + * Disposes the default display before and after test execution. + */ +public sealed class ResetMonitorSpecificScalingExtension implements BeforeEachCallback, AfterEachCallback permits WithMonitorSpecificScalingExtension { + private boolean wasMonitorSpecificScalingActive; + + protected ResetMonitorSpecificScalingExtension() { + } + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + wasMonitorSpecificScalingActive = DPIUtil.isMonitorSpecificScalingActive(); + Display.getDefault().dispose(); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + DPIUtil.setMonitorSpecificScaling(wasMonitorSpecificScalingActive); + Display.getDefault().dispose(); + } + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ScalingSWTFontRegistryTests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ScalingSWTFontRegistryTests.java index bed69c46654..2e892f85955 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ScalingSWTFontRegistryTests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/ScalingSWTFontRegistryTests.java @@ -19,16 +19,13 @@ import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; +@ExtendWith(PlatformSpecificExecutionExtension.class) class ScalingSWTFontRegistryTests { private static String TEST_FONT = "Helvetica"; private SWTFontRegistry fontRegistry; - @BeforeAll - public static void assumeIsFittingPlatform() { - PlatformSpecificExecution.assumeIsFittingPlatform(); - } - @BeforeEach public void setUp() { this.fontRegistry = new ScalingSWTFontRegistry(Display.getDefault()); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/WithMonitorSpecificScalingExtension.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/WithMonitorSpecificScalingExtension.java new file mode 100644 index 00000000000..d75ee1c90d9 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/internal/WithMonitorSpecificScalingExtension.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2025 Vector Informatik GmbH + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.swt.internal; + +import org.junit.jupiter.api.extension.*; + +/** + * Runs a test with monitor specific scaling. Disposes the default display before and after execution. + */ +public final class WithMonitorSpecificScalingExtension extends ResetMonitorSpecificScalingExtension { + + private WithMonitorSpecificScalingExtension() { + super(); + } + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + super.beforeEach(context); + DPIUtil.setMonitorSpecificScaling(true); + } + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ControlWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ControlWin32Tests.java index de94f253dda..21cf0d781a7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ControlWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ControlWin32Tests.java @@ -19,61 +19,63 @@ import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; /** - * Automated Tests for class org.eclipse.swt.widgets.Control - * for Windows specific behavior + * Automated Tests for class org.eclipse.swt.widgets.Control for Windows + * specific behavior * * @see org.eclipse.swt.widgets.Control */ -class ControlWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(ResetMonitorSpecificScalingExtension.class) +class ControlWin32Tests { @Test public void testScaleFontCorrectlyInAutoScaleSzenario() { - assertTrue("Autoscale property is not set to true", display.isRescalingAtRuntime()); + DPIUtil.setMonitorSpecificScaling(true); + Display display = Display.getDefault(); + assertTrue("Autoscale property is not set to true", display.isRescalingAtRuntime()); int scalingFactor = 2; - Control control = new Composite(shell, SWT.NONE); - int zoom = DPIUtil.getDeviceZoom(); - int newZoom = zoom * scalingFactor; - try { - Font oldFont = control.getFont(); - changeDPIZoom(newZoom); - control.setFont(oldFont); - Font newFont = control.getFont(); - FontData fontData = oldFont.getFontData()[0]; - FontData currentFontData = newFont.getFontData()[0]; - int heightInPixels = fontData.data.lfHeight; - int currentHeightInPixels = currentFontData.data.lfHeight; - assertEquals("Font height in points is different on different zoom levels", fontData.getHeight(), currentFontData.getHeight()); - assertEquals("Font height in pixels is not adjusted according to the scale factor", heightInPixels * scalingFactor, currentHeightInPixels); - } finally { - control.dispose(); - } + FontComparison fontComparison = updateFont(scalingFactor); + assertEquals("Font height in pixels is not adjusted according to the scale factor", + fontComparison.originalFontHeight * scalingFactor, fontComparison.currentFontHeight); } @Test public void testDoNotScaleFontCorrectlyInNoAutoScaleSzenario() { - display.setRescalingAtRuntime(false); - assertFalse("Autoscale property is not set to false", display.isRescalingAtRuntime()); + DPIUtil.setMonitorSpecificScaling(false); + Display display = Display.getDefault(); + assertFalse("Autoscale property is not set to false", display.isRescalingAtRuntime()); int scalingFactor = 2; + FontComparison fontComparison = updateFont(scalingFactor); + assertEquals("Font height in pixels is different when setting the same font again", + fontComparison.originalFontHeight, fontComparison.currentFontHeight); + } + + record FontComparison(int originalFontHeight, int currentFontHeight) { + } + + private FontComparison updateFont(int scalingFactor) { + Shell shell = new Shell(Display.getDefault()); Control control = new Composite(shell, SWT.NONE); int zoom = DPIUtil.getDeviceZoom(); int newZoom = zoom * scalingFactor; - try { - Font oldFont = control.getFont(); - changeDPIZoom(newZoom); - control.setFont(oldFont); - Font newFont = control.getFont(); - FontData fontData = oldFont.getFontData()[0]; - FontData currentFontData = newFont.getFontData()[0]; - int heightInPixels = fontData.data.lfHeight; - int currentHeightInPixels = currentFontData.data.lfHeight; - assertEquals("Font height in points is different on different zoom levels", fontData.getHeight(), currentFontData.getHeight()); - assertEquals("Font height in pixels is different when setting the same font again", heightInPixels, currentHeightInPixels); - } finally { - control.dispose(); - } + + Font oldFont = control.getFont(); + DPITestUtil.changeDPIZoom(shell, newZoom); + control.setFont(oldFont); + Font newFont = control.getFont(); + FontData fontData = oldFont.getFontData()[0]; + FontData currentFontData = newFont.getFontData()[0]; + int heightInPixels = fontData.data.lfHeight; + int currentHeightInPixels = currentFontData.data.lfHeight; + assertEquals("Font height in points is different on different zoom levels", fontData.getHeight(), + currentFontData.getHeight()); + + return new FontComparison(heightInPixels, currentHeightInPixels); } + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/DisplayWin32Test.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/DisplayWin32Test.java index dddd407cf0e..7f511e6cc31 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/DisplayWin32Test.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/DisplayWin32Test.java @@ -5,16 +5,13 @@ import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.win32.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; +@ExtendWith(PlatformSpecificExecutionExtension.class) public class DisplayWin32Test { private Display display; - @BeforeAll - public static void assumeIsFittingPlatform() { - PlatformSpecificExecution.assumeIsFittingPlatform(); - } - @BeforeEach public void createDisplay() { display = new Display(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/WidgetWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/WidgetWin32Tests.java index 5f8962a15c6..2d8364b9d53 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/WidgetWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/WidgetWin32Tests.java @@ -22,11 +22,16 @@ import org.eclipse.swt.internal.win32.*; import org.eclipse.swt.layout.*; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; -class WidgetWin32Tests extends Win32AutoscaleTestBase { +@ExtendWith(PlatformSpecificExecutionExtension.class) +@ExtendWith(WithMonitorSpecificScalingExtension.class) +class WidgetWin32Tests { @Test public void testWidgetZoomShouldChangeOnZoomLevelChange() { + Display display = Display.getDefault(); + Shell shell = new Shell(display); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; @@ -36,17 +41,18 @@ public void testWidgetZoomShouldChangeOnZoomLevelChange() { button.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_CYAN)); shell.open(); assertEquals("The initial zoom is wrong", zoom, button.getZoom()); // pre-condition - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); assertEquals("The Zoom Level should be updated for button on zoom change event on its shell", scaledZoom, button.getZoom()); } @Test public void testButtonPointsAfterZooming() throws NoSuchMethodException, IllegalAccessException { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -56,7 +62,7 @@ public void testButtonPointsAfterZooming() throws NoSuchMethodException, Illegal button.setBounds(0, 0, 100, 200); Point sizeBeforeEvent = button.getSize(); Point p1 = button.computeSizeInPixels(sizeBeforeEvent.x, sizeBeforeEvent.y, false); - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); Point sizeAfterEvent = button.getSize(); Point p2 = button.computeSizeInPixels(sizeAfterEvent.x, sizeAfterEvent.y, false); @@ -66,6 +72,7 @@ public void testButtonPointsAfterZooming() throws NoSuchMethodException, Illegal @Test public void testImagePixelsWithDoubleZoomLevel() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; @@ -91,10 +98,11 @@ private Point getImageDimension(Image image, Integer zoomLevel) { @Test public void testButtonFontAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -106,7 +114,7 @@ public void testButtonFontAfterZooming() { button.setFont(font); int heightBeforeZoom = button.getFont().getFontData()[0].data.lfHeight; - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); int heightAfterZoom = button.getFont().getFontData()[0].data.lfHeight; assertEquals("Height of a font of the button should be doubled after zooming to 200", @@ -115,10 +123,11 @@ public void testButtonFontAfterZooming() { @Test public void testCoolItemAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -135,7 +144,7 @@ public void testCoolItemAfterZooming() { var preferredControlSize = item1.getPreferredSizeInPixels(); int xBeforeZoom = preferredControlSize.x; int yBeforeZoom = preferredControlSize.y; - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); var preferredControlSize2 = item1.getPreferredSizeInPixels(); int xAfterZoom = preferredControlSize2.x; int yAfterZoom = preferredControlSize2.y; @@ -153,10 +162,11 @@ public void testCoolItemAfterZooming() { @Test public void testExpandItemAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -170,7 +180,7 @@ public void testExpandItemAfterZooming() { item1.setExpanded(true); var heightBeforeZoom = item1.getHeightInPixels(); - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); var heightAfterZoom = item1.getHeightInPixels(); assertEquals("Height of a font of the button should be doubled after zooming to 200", @@ -179,10 +189,11 @@ public void testExpandItemAfterZooming() { @Test public void testTabFolderSizeAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -197,7 +208,7 @@ public void testTabFolderSizeAfterZooming() { tabItem.setControl(label); Point tabItemSizeBeforeEvent = tabItem.getControl().getSize(); - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); Point tabItemSizeAfterEvent = tabItem.getControl().getSize(); assertEquals("Width of a tab folder item should be halved in points after zooming to 200", @@ -208,10 +219,11 @@ public void testTabFolderSizeAfterZooming() { @Test public void testTableAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -236,7 +248,7 @@ public void testTableAfterZooming() { } int fontHeightBefore = item1.getFont().getFontData()[0].data.lfHeight; - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); int fontHeightAfter = item1.getFont().getFontData()[0].data.lfHeight; assertEquals("Height of a font for table item should be doubled after zooming to 200", @@ -245,10 +257,11 @@ public void testTableAfterZooming() { @Test public void testTreeAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -271,7 +284,7 @@ public void testTreeAfterZooming() { } int fontHeightBefore = item1.getFont().getFontData()[0].data.lfHeight; - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); int fontHeightAfter = item1.getFont().getFontData()[0].data.lfHeight; assertEquals("Height of a font for tree item should be doubled after zooming to 200", @@ -280,10 +293,11 @@ public void testTreeAfterZooming() { @Test public void testCaretInStyledTextAfterZooming() { + Display display = Display.getDefault(); int zoom = DPIUtil.getDeviceZoom(); int scaledZoom = zoom * 2; - shell = new Shell(display); + Shell shell = new Shell(display); shell.setBounds(0, 0, 100, 160); shell.setLayout(new FillLayout()); shell.pack(); @@ -311,7 +325,7 @@ public void testCaretInStyledTextAfterZooming() { // Get the caret size Point caretSize = styledText.getCaret().getSizeInPixels(); - changeDPIZoom(scaledZoom); + DPITestUtil.changeDPIZoom(shell, scaledZoom); Point caretSize2 = styledText.getCaret().getSizeInPixels(); assertEquals("Height of a Caret for Styled Text should be doubled after zooming to 200", caretSize.y * 2, 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 336b726f519..06804718372 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 @@ -650,6 +650,10 @@ public static int getZoomForAutoscaleProperty (int nativeDeviceZoom) { return zoom; } +public static void setMonitorSpecificScaling(boolean activate) { + System.setProperty(SWT_AUTOSCALE_UPDATE_ON_RUNTIME, Boolean.toString(activate)); +} + public static boolean isMonitorSpecificScalingActive() { boolean updateOnRuntimeValue = Boolean.getBoolean (SWT_AUTOSCALE_UPDATE_ON_RUNTIME); return updateOnRuntimeValue;