diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java index 2a804684a87..c3a78447efc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java @@ -242,29 +242,35 @@ void createCOMInterfaces() { public long method2(long[] args) {return Release();} @Override public long method3(long[] args) { - if (args.length == 5) { - return DragEnter(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]); - } else { - return DragEnter_64(args[0], (int)args[1], args[2], args[3]); - } + return Win32DPIUtils.runWithProperDPIAwareness(() -> { + if (args.length == 5) { + return DragEnter(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]); + } else { + return DragEnter_64(args[0], (int)args[1], args[2], args[3]); + } + }); } @Override public long method4(long[] args) { - if (args.length == 4) { - return DragOver((int)args[0], (int)args[1], (int)args[2], args[3]); - } else { - return DragOver_64((int)args[0], args[1], args[2]); - } + return Win32DPIUtils.runWithProperDPIAwareness(() -> { + if (args.length == 4) { + return DragOver((int)args[0], (int)args[1], (int)args[2], args[3]); + } else { + return DragOver_64((int)args[0], args[1], args[2]); + } + }); } @Override public long method5(long[] args) {return DragLeave();} @Override public long method6(long[] args) { - if (args.length == 5) { - return Drop(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]); - } else { - return Drop_64(args[0], (int)args[1], args[2], args[3]); - } + return Win32DPIUtils.runWithProperDPIAwareness(() -> { + if (args.length == 5) { + return Drop(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]); + } else { + return Drop_64(args[0], (int)args[1], args[2], args[3]); + } + }); } }; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java new file mode 100644 index 00000000000..89bbb16a9e3 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/Win32DPIUtils.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2025 Yatta Solutions and others. + * + * 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 + * + * Contributors: + * Yatta Solutions - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.internal; + +import java.util.function.*; + +import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.internal.win32.version.*; + +/** + * This class is used in the win32 implementation only to provide + * DPI related utility methods. + *

+ * IMPORTANT: This class is not part of the public + * API for SWT. It is marked public only so that it can be shared + * within the packages provided by SWT. It is not available on all + * platforms, and should never be called from application code. + *

+ * @noreference This class is not intended to be referenced by clients + */ +public class Win32DPIUtils { + public static boolean setDPIAwareness(int desiredDpiAwareness) { + if (desiredDpiAwareness == OS.GetThreadDpiAwarenessContext()) { + return true; + } + if (desiredDpiAwareness == OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) { + // "Per Monitor V2" only available in more recent Windows version + boolean perMonitorV2Available = OsVersion.IS_WIN10_1809; + if (!perMonitorV2Available) { + System.err.println("***WARNING: the OS version does not support DPI awareness mode PerMonitorV2."); + return false; + } + } + long setDpiAwarenessResult = OS.SetThreadDpiAwarenessContext(desiredDpiAwareness); + if (setDpiAwarenessResult == 0L) { + System.err.println("***WARNING: setting DPI awareness failed."); + return false; + } + return true; + } + + public static T runWithProperDPIAwareness(Supplier operation) { + // refreshing is only necessary, when monitor specific scaling is active + long previousDPIAwareness = OS.GetThreadDpiAwarenessContext(); + try { + if (!setDPIAwareness(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { + // awareness was not changed, so no need to reset it + previousDPIAwareness = 0; + } + return operation.get(); + } finally { + if (previousDPIAwareness > 0) { + OS.SetThreadDpiAwarenessContext(previousDPIAwareness); + } + } + } +} 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 511fcdfec44..a775cfcb74c 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 @@ -5404,7 +5404,7 @@ public boolean setRescalingAtRuntime(boolean activate) { private boolean setMonitorSpecificScaling(boolean activate) { int desiredApiAwareness = activate ? OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 : OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; - if (setDPIAwareness(desiredApiAwareness)) { + if (Win32DPIUtils.setDPIAwareness(desiredApiAwareness)) { rescalingAtRuntime = activate; coordinateSystemMapper = activate ? new MultiZoomCoordinateSystemMapper(this, this::getMonitors) : new SingleZoomCoordinateSystemMapper(this); // dispose a existing font registry for the default display @@ -5414,38 +5414,12 @@ private boolean setMonitorSpecificScaling(boolean activate) { return false; } -private boolean setDPIAwareness(int desiredDpiAwareness) { - if (desiredDpiAwareness == OS.GetThreadDpiAwarenessContext()) { - return true; - } - if (desiredDpiAwareness == OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) { - // "Per Monitor V2" only available in more recent Windows version - boolean perMonitorV2Available = OsVersion.IS_WIN10_1809; - if (!perMonitorV2Available) { - System.err.println("***WARNING: the OS version does not support DPI awareness mode PerMonitorV2."); - return false; - } - } - long setDpiAwarenessResult = OS.SetThreadDpiAwarenessContext(desiredDpiAwareness); - if (setDpiAwarenessResult == 0L) { - System.err.println("***WARNING: setting DPI awareness failed."); - return false; - } - return true; -} - private void runWithProperDPIAwareness(Runnable operation) { if (isRescalingAtRuntime()) { - // refreshing is only necessary, when monitor specific scaling is active - long previousDPIAwareness = OS.GetThreadDpiAwarenessContext(); - if (!setDPIAwareness(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { - // awareness was not changed, so no need to reset it - previousDPIAwareness = 0; - } - operation.run(); - if (previousDPIAwareness > 0) { - OS.SetThreadDpiAwarenessContext(previousDPIAwareness); - } + Win32DPIUtils.runWithProperDPIAwareness(() -> { + operation.run(); + return true; + }); } else { operation.run(); }