Skip to content
Permalink
Browse files
8238575: DragSourceEvent.getLocation() returns wrong value on HiDPI s…
…creens (Windows)

Reviewed-by: prr
  • Loading branch information
mrserb committed Apr 27, 2020
1 parent a0a9595 commit b36738a55aa9dff2948b8a63ad291dc6cf084df2
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -282,7 +282,7 @@ void AwtDragSource::_DoDragDrop(void* param) {

call_dSCddfinished(env, peer, res == DRAGDROP_S_DROP && effects != DROPEFFECT_NONE,
convertDROPEFFECTToActions(effects),
dragSource->m_dragPoint.x, dragSource->m_dragPoint.y);
dragSource->m_dragPoint);

env->DeleteLocalRef(peer);

@@ -649,8 +649,7 @@ HRESULT __stdcall AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWOR

if ( (dragPoint.x != m_dragPoint.x || dragPoint.y != m_dragPoint.y) &&
m_lastmods == modifiers) {//cannot move before cursor change
call_dSCmouseMoved(env, m_peer,
m_actions, modifiers, dragPoint.x, dragPoint.y);
call_dSCmouseMoved(env, m_peer, m_actions, modifiers, dragPoint);
JNU_CHECK_EXCEPTION_RETURN(env, E_UNEXPECTED);
m_dragPoint = dragPoint;
}
@@ -662,8 +661,7 @@ HRESULT __stdcall AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWOR
} else if ((modifiers & JAVA_BUTTON_MASK) != (m_initmods & JAVA_BUTTON_MASK)) {
return DRAGDROP_S_CANCEL;
} else if (m_lastmods != modifiers) {
call_dSCchanged(env, m_peer,
m_actions, modifiers, dragPoint.x, dragPoint.y);
call_dSCchanged(env, m_peer, m_actions, modifiers, dragPoint);
m_bRestoreNodropCustomCursor = TRUE;
}

@@ -726,13 +724,13 @@ HRESULT __stdcall AwtDragSource::GiveFeedback(DWORD dwEffect) {
if (invalid) {
// Don't call dragExit if dragEnter and dragOver haven't been called.
if (!m_enterpending) {
call_dSCexit(env, m_peer, curs.x, curs.y);
call_dSCexit(env, m_peer, curs);
}
m_droptarget = (HWND)NULL;
m_enterpending = TRUE;
} else if (m_droptarget != NULL) {
(*(m_enterpending ? call_dSCenter : call_dSCmotion))
(env, m_peer, m_actions, modifiers, curs.x, curs.y);
(env, m_peer, m_actions, modifiers, curs);

m_enterpending = FALSE;
}
@@ -1176,14 +1174,26 @@ HRESULT __stdcall AwtDragSource::GetProcessId(FORMATETC __RPC_FAR *pFormatEtc, S
return S_OK;
}

static void ScaleDown(POINT &pt) {
HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
Devices::InstanceAccess devices;
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
if (device) {
pt.x = device->ScaleDownX(pt.x);
pt.y = device->ScaleDownY(pt.y);
}
}

DECLARE_JAVA_CLASS(dSCClazz, "sun/awt/windows/WDragSourceContextPeer")

void
AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions,
jint modifiers, jint x, jint y) {
jint modifiers, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCenter, dSCClazz, "dragEnter", "(IIII)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCenter, targetActions, modifiers, x, y);
env->CallVoidMethod(self, dSCenter, targetActions, modifiers, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -1192,10 +1202,11 @@ AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions,

void
AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions,
jint modifiers, jint x, jint y) {
jint modifiers, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCmotion, dSCClazz, "dragMotion", "(IIII)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCmotion, targetActions, modifiers, x, y);
env->CallVoidMethod(self, dSCmotion, targetActions, modifiers, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -1204,22 +1215,24 @@ AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions,

void
AwtDragSource::call_dSCchanged(JNIEnv* env, jobject self, jint targetActions,
jint modifiers, jint x, jint y) {
jint modifiers, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCchanged, dSCClazz, "operationChanged",
"(IIII)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCchanged, targetActions, modifiers, x, y);
env->CallVoidMethod(self, dSCchanged, targetActions, modifiers, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void
AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, jint x, jint y) {
AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCexit, dSCClazz, "dragExit", "(II)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCexit, x, y);
env->CallVoidMethod(self, dSCexit, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -1228,10 +1241,11 @@ AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, jint x, jint y) {

void
AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success,
jint operations, jint x, jint y) {
jint operations, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCddfinished, dSCClazz, "dragDropFinished", "(ZIII)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCddfinished, success, operations, x, y);
env->CallVoidMethod(self, dSCddfinished, success, operations, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -1240,11 +1254,12 @@ AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success,

void
AwtDragSource::call_dSCmouseMoved(JNIEnv* env, jobject self, jint targetActions,
jint modifiers, jint x, jint y) {
jint modifiers, POINT pt) {
ScaleDown(pt);
DECLARE_VOID_JAVA_METHOD(dSCmouseMoved, dSCClazz, "dragMouseMoved",
"(IIII)V");
DASSERT(!JNU_IsNull(env, self));
env->CallVoidMethod(self, dSCmouseMoved, targetActions, modifiers, x, y);
env->CallVoidMethod(self, dSCmouseMoved, targetActions, modifiers, pt.x, pt.y);
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,20 +127,20 @@ class AwtDragSource : virtual public IDropSource, virtual public IDataObject {
static int __cdecl _compar(const void *, const void *);

static void call_dSCenter(JNIEnv* env, jobject self, jint targetActions,
jint modifiers, jint x, jint y);
jint modifiers, POINT pt);
static void call_dSCmotion(JNIEnv* env, jobject self,
jint targetActions, jint modifiers,
jint x, jint y);
POINT pt);
static void call_dSCchanged(JNIEnv* env, jobject self,
jint targetActions, jint modifiers,
jint x, jint y);
POINT pt);
static void call_dSCmouseMoved(JNIEnv* env, jobject self,
jint targetActions, jint modifiers,
jint x, jint y);
static void call_dSCexit(JNIEnv* env, jobject self, jint x, jint y);
POINT pt);
static void call_dSCexit(JNIEnv* env, jobject self, POINT pt);
static void call_dSCddfinished(JNIEnv* env, jobject self,
jboolean success, jint operations,
jint x, jint y);
POINT pt);
protected:

class ADSIEnumFormatEtc : public virtual IEnumFORMATETC {
@@ -254,8 +254,8 @@ class AwtDragSource : virtual public IDropSource, virtual public IDataObject {
jobject m_transferable;
jobject m_formatMap;

POINT m_dragPoint;
POINT m_dropPoint;
POINT m_dragPoint; // device space (pixels)
POINT m_dropPoint; // device space (pixels)
BOOL m_fNC;
BOOL m_bRestoreNodropCustomCursor;//CR 6480706 - MS Bug on hold

@@ -125,7 +125,7 @@ ULONG __stdcall AwtDropTarget::Release() {
return (ULONG)refs;
}

void ScaleDown(POINT &cp, HWND m_window) {
static void ScaleDown(POINT &cp, HWND m_window) {
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(m_window);
Devices::InstanceAccess devices;
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,21 @@
* questions.
*/

import java.awt.Color;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Robot;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
@@ -42,7 +47,7 @@
/**
* @test
* @key headful
* @bug 4955110
* @bug 4955110 8238575
* @summary tests that DragSourceDragEvent.getDropAction() accords to its new
* spec (does not depend on the user drop action)
* @library ../../regtesthelpers
@@ -53,26 +58,56 @@
public final class Button2DragTest {

private volatile boolean dropSuccess;
private volatile boolean locationValid = true;

private static Frame frame;

public static void main(final String[] args) {
Button2DragTest test = new Button2DragTest();
try {
test.run();
} finally {
if (frame != null) {
var lge = GraphicsEnvironment.getLocalGraphicsEnvironment();
for (GraphicsDevice device : lge.getScreenDevices()) {
Button2DragTest test = new Button2DragTest();
frame = new Frame(device.getDefaultConfiguration());
try {
test.run();
} finally {
frame.dispose();
}
}
}

public void run() {
frame = new Frame();
final DragSourceListener dragSourceListener = new DragSourceListener() {
private void checkLocation(DragSourceEvent dsde) {
if (!frame.getBounds().contains(dsde.getLocation())) {
System.err.println("Expected in" + frame.getBounds());
System.err.println("Actual" + dsde.getLocation());
locationValid = false;
}
}

@Override
public void dragEnter(DragSourceDragEvent dsde) {
checkLocation(dsde);
}

@Override
public void dragOver(DragSourceDragEvent dsde) {
checkLocation(dsde);
}

final DragSourceListener dragSourceListener = new DragSourceAdapter() {
public void dragDropEnd(DragSourceDropEvent e) {
dropSuccess = e.getDropSuccess();
@Override
public void dropActionChanged(DragSourceDragEvent dsde) {
checkLocation(dsde);
}

@Override
public void dragExit(DragSourceEvent dse) {
checkLocation(dse);
}

public void dragDropEnd(DragSourceDropEvent dsde) {
checkLocation(dsde);
dropSuccess = dsde.getDropSuccess();
System.err.println("Drop was successful: " + dropSuccess);
}
};
@@ -93,11 +128,9 @@ public void drop(DropTargetDropEvent dtde) {
};
new DropTarget(frame, dropTargetListener);

//What would normally go into main() will probably go here.
//Use System.out.println for diagnostic messages that you want
//to read after the test is done.
frame.setBackground(Color.GREEN);
frame.setUndecorated(true);
frame.setBounds(100, 100, 200, 200);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);

@@ -115,11 +148,8 @@ public void drop(DropTargetDropEvent dtde) {
Util.waitForIdle(robot);
robot.delay(500);

if (dropSuccess) {
System.err.println("test passed");
} else {
if (!dropSuccess || !locationValid) {
throw new RuntimeException("test failed: drop was not successful");
}
}

}

0 comments on commit b36738a

Please sign in to comment.