Skip to content

Commit cc248ab

Browse files
akoch-yattaHeikoKlare
authored andcommitted
[win32] Fix DnD across multiple monitors
This commit addresses issues, when DnD across multiple monitors with monitors specific scaling is used. If the monitors have different zoom dragging into a table or tree on the second monitor will detect the wrong destination items depending on the zoom. To address this the zoom should always be inherited from the underlying control if available.
1 parent 00c6aef commit cc248ab

File tree

1 file changed

+25
-13
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd

1 file changed

+25
-13
lines changed

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

+25-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.swt.dnd;
1515

1616
import org.eclipse.swt.*;
17+
import org.eclipse.swt.graphics.*;
1718
import org.eclipse.swt.internal.*;
1819
import org.eclipse.swt.internal.ole.win32.*;
1920
import org.eclipse.swt.internal.win32.*;
@@ -281,16 +282,14 @@ int DragEnter_64(long pDataObject, int grfKeyState, long pt, long pdwEffect) {
281282
}
282283

283284
int DragEnter(long pDataObject, int grfKeyState, int pt_x, int pt_y, long pdwEffect) {
284-
int zoom = DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
285-
pt_x = DPIUtil.scaleDown(pt_x, zoom);// To Points
286-
pt_y = DPIUtil.scaleDown(pt_y, zoom);// To Points
285+
Point location = convertPixelToPoint(pt_x, pt_y);
287286
selectedDataType = null;
288287
selectedOperation = DND.DROP_NONE;
289288
if (iDataObject != null) iDataObject.Release();
290289
iDataObject = null;
291290

292291
DNDEvent event = new DNDEvent();
293-
if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) {
292+
if (!setEventData(event, pDataObject, grfKeyState, location.x, location.y, pdwEffect)) {
294293
OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4);
295294
return COM.S_FALSE;
296295
}
@@ -349,14 +348,12 @@ int DragOver_64(int grfKeyState, long pt, long pdwEffect) {
349348
}
350349

351350
int DragOver(int grfKeyState, int pt_x, int pt_y, long pdwEffect) {
352-
int zoom = DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
353-
pt_x = DPIUtil.scaleDown(pt_x, zoom);// To Points
354-
pt_y = DPIUtil.scaleDown(pt_y, zoom);// To Points
351+
Point location = convertPixelToPoint(pt_x, pt_y);
355352
if (iDataObject == null) return COM.S_FALSE;
356353
int oldKeyOperation = keyOperation;
357354

358355
DNDEvent event = new DNDEvent();
359-
if (!setEventData(event, iDataObject.getAddress(), grfKeyState, pt_x, pt_y, pdwEffect)) {
356+
if (!setEventData(event, iDataObject.getAddress(), grfKeyState, location.x, location.y, pdwEffect)) {
360357
keyOperation = -1;
361358
OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4);
362359
return COM.S_FALSE;
@@ -403,23 +400,38 @@ int Drop_64(long pDataObject, int grfKeyState, long pt, long pdwEffect) {
403400
return Drop(pDataObject, grfKeyState, point.x, point.y, pdwEffect);
404401
}
405402

403+
private Point convertPixelToPoint(int xInPixels, int yInPixels) {
404+
if (this.control == null) {
405+
// If there is no control for context, the behavior remains as before
406+
int zoom = DPIUtil.getZoomForAutoscaleProperty(this.nativeZoom);
407+
return DPIUtil.scaleDown(new Point(xInPixels, yInPixels), zoom);
408+
}
409+
int zoom = DPIUtil.getZoomForAutoscaleProperty(this.control.nativeZoom);
410+
// There is no API to convert absolute values in pixels to display relative
411+
// points. Therefor, the display relative pixel values are converted to control
412+
// relative pixel values via Windows API. These values can be scaled down to points
413+
POINT pt = new POINT ();
414+
pt.x = xInPixels; pt.y = yInPixels;
415+
OS.ScreenToClient (this.control.handle, pt);
416+
Point p = DPIUtil.scaleDown(new Point (pt.x, pt.y), zoom);
417+
return this.control.toDisplay(p);
418+
}
419+
406420
int Drop(long pDataObject, int grfKeyState, int pt_x, int pt_y, long pdwEffect) {
407421
try {
408-
int zoom = DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
409-
pt_x = DPIUtil.scaleDown(pt_x, zoom);// To Points
410-
pt_y = DPIUtil.scaleDown(pt_y, zoom);// To Points
422+
Point location = convertPixelToPoint(pt_x, pt_y);
411423
DNDEvent event = new DNDEvent();
412424
event.widget = this;
413425
event.time = OS.GetMessageTime();
414426
if (dropEffect != null) {
415-
event.item = dropEffect.getItem(pt_x, pt_y);
427+
event.item = dropEffect.getItem(location.x, location.y);
416428
}
417429
event.detail = DND.DROP_NONE;
418430
notifyListeners(DND.DragLeave, event);
419431
refresh();
420432

421433
event = new DNDEvent();
422-
if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) {
434+
if (!setEventData(event, pDataObject, grfKeyState, location.x, location.y, pdwEffect)) {
423435
keyOperation = -1;
424436
OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4);
425437
return COM.S_FALSE;

0 commit comments

Comments
 (0)