Skip to content

Commit 51d6029

Browse files
committed
[Win32] Fix drag and drop without monitor-specific scaling #2394
To fix drag and drop behavior on multiple monitors with different zooms when using monitor-specific scaling, a recent change adapted the OS callbacks for drop operations to run with the required DPI awareness (PerMonitorV2) in that case. This change did not consider that without monitor-specific scaling (and particularly when DPI awareness "System" is used), running with that modified DPI awareness is not correct. This change adapts the drop callback to only adapt the DPI awareness if appropriate (i.e., if monitor-specific scaling is enabled). Fixes #2394
1 parent 812289e commit 51d6029

File tree

3 files changed

+14
-18
lines changed

3 files changed

+14
-18
lines changed

bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ void createCOMInterfaces() {
242242
public long method2(long[] args) {return Release();}
243243
@Override
244244
public long method3(long[] args) {
245-
return Win32DPIUtils.runWithProperDPIAwareness(() -> {
245+
return Win32DPIUtils.runWithProperDPIAwareness(getDisplay(), () -> {
246246
if (args.length == 5) {
247247
return DragEnter(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]);
248248
} else {
@@ -252,7 +252,7 @@ public long method3(long[] args) {
252252
}
253253
@Override
254254
public long method4(long[] args) {
255-
return Win32DPIUtils.runWithProperDPIAwareness(() -> {
255+
return Win32DPIUtils.runWithProperDPIAwareness(getDisplay(), () -> {
256256
if (args.length == 4) {
257257
return DragOver((int)args[0], (int)args[1], (int)args[2], args[3]);
258258
} else {
@@ -264,7 +264,7 @@ public long method4(long[] args) {
264264
public long method5(long[] args) {return DragLeave();}
265265
@Override
266266
public long method6(long[] args) {
267-
return Win32DPIUtils.runWithProperDPIAwareness(() -> {
267+
return Win32DPIUtils.runWithProperDPIAwareness(getDisplay(), () -> {
268268
if (args.length == 5) {
269269
return Drop(args[0], (int)args[1], (int)args[2], (int)args[3], args[4]);
270270
} else {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.eclipse.swt.graphics.*;
2020
import org.eclipse.swt.internal.win32.*;
2121
import org.eclipse.swt.internal.win32.version.*;
22+
import org.eclipse.swt.widgets.*;
2223

2324
/**
2425
* This class is used in the win32 implementation only to provide
@@ -68,8 +69,11 @@ public static boolean setDPIAwareness(int desiredDpiAwareness) {
6869
return true;
6970
}
7071

71-
public static <T> T runWithProperDPIAwareness(Supplier<T> operation) {
72-
// refreshing is only necessary, when monitor specific scaling is active
72+
public static <T> T runWithProperDPIAwareness(Display display, Supplier<T> operation) {
73+
// only with monitor-specific scaling enabled, the main thread's DPI awareness may be adapted
74+
if (!display.isRescalingAtRuntime()) {
75+
return operation.get();
76+
}
7377
long previousDPIAwareness = OS.GetThreadDpiAwarenessContext();
7478
try {
7579
if (!setDPIAwareness(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) {

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@ public Widget findWidget (Widget widget, long id) {
14611461

14621462
long foregroundIdleProc (long code, long wParam, long lParam) {
14631463
if (code >= 0) {
1464-
Runnable processMessages = () -> {
1464+
Supplier<Boolean> processMessages = () -> {
14651465
sendPostExternalEventDispatchEvent ();
14661466
if (runMessagesInIdle) {
14671467
if (runMessagesInMessageProc) {
@@ -1487,6 +1487,7 @@ long foregroundIdleProc (long code, long wParam, long lParam) {
14871487
int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT;
14881488
if (!OS.PeekMessage (msg, 0, 0, 0, flags)) wakeThread ();
14891489
sendPreExternalEventDispatchEvent ();
1490+
return true;
14901491
};
14911492
if (!synchronizer.isMessagesEmpty()) {
14921493
// Windows hooks will inherit the thread DPI awareness from
@@ -1495,7 +1496,7 @@ long foregroundIdleProc (long code, long wParam, long lParam) {
14951496
// This requires to reset the thread DPi awareness to make
14961497
// sure, all UI updates caused by this will be executed
14971498
// with the correct DPI awareness
1498-
runWithProperDPIAwareness(processMessages);
1499+
Win32DPIUtils.runWithProperDPIAwareness(this, processMessages);
14991500
}
15001501
}
15011502
return OS.CallNextHookEx (idleHook, (int)code, wParam, lParam);
@@ -3478,10 +3479,11 @@ long msgFilterProc (long code, long wParam, long lParam) {
34783479
// This requires to reset the thread DPi awareness to make
34793480
// sure, all UI updates caused by this will be executed
34803481
// with the correct DPI awareness
3481-
runWithProperDPIAwareness(() -> {
3482+
Win32DPIUtils.runWithProperDPIAwareness(this, () -> {
34823483
if (!OS.PeekMessage (msg, 0, 0, 0, flags)) {
34833484
if (runAsyncMessages (false)) wakeThread ();
34843485
}
3486+
return true;
34853487
});
34863488
}
34873489
break;
@@ -5414,14 +5416,4 @@ private boolean setMonitorSpecificScaling(boolean activate) {
54145416
return false;
54155417
}
54165418

5417-
private void runWithProperDPIAwareness(Runnable operation) {
5418-
if (isRescalingAtRuntime()) {
5419-
Win32DPIUtils.runWithProperDPIAwareness(() -> {
5420-
operation.run();
5421-
return true;
5422-
});
5423-
} else {
5424-
operation.run();
5425-
}
5426-
}
54275419
}

0 commit comments

Comments
 (0)