You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by eb...@apache.org on 2020/01/03 10:40:38 UTC
[netbeans] branch master updated: [NETBEANS-2954] Fix broken tab
dragging on HiDPI displays (Windows) (#1804)
This is an automated email from the ASF dual-hosted git repository.
ebakke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 7813792 [NETBEANS-2954] Fix broken tab dragging on HiDPI displays (Windows) (#1804)
7813792 is described below
commit 78137924fbe8d8a51ccf4bc98ed746675ea3b4c7
Author: Eirik Bakke <eb...@ultorg.com>
AuthorDate: Fri Jan 3 11:40:26 2020 +0100
[NETBEANS-2954] Fix broken tab dragging on HiDPI displays (Windows) (#1804)
[NETBEANS-2954] Fix broken tab dragging in window system on HiDPI displays on Windows
---
.../view/dnd/DragAndDropFeedbackVisualizer.java | 6 ++--
.../windows/view/dnd/TopComponentDragSupport.java | 6 ++--
.../core/windows/view/dnd/WindowDnDManager.java | 41 ++++++++++++++++++++--
.../core/windows/view/ui/toolbars/DnDSupport.java | 17 +++++----
4 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/DragAndDropFeedbackVisualizer.java b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/DragAndDropFeedbackVisualizer.java
index 9343b24..3a550b0 100644
--- a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/DragAndDropFeedbackVisualizer.java
+++ b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/DragAndDropFeedbackVisualizer.java
@@ -128,8 +128,10 @@ public class DragAndDropFeedbackVisualizer {
}
public void update(DragSourceDragEvent e) {
- if( null != dragWindow )
- dragWindow.setLocation( e.getLocation().x-dragOffset.x, e.getLocation().y-dragOffset.y );
+ if( null != dragWindow ) {
+ Point location = WindowDnDManager.getLocationWorkaround(e);
+ dragWindow.setLocation( location.x-dragOffset.x, location.y-dragOffset.y );
+ }
}
public void dispose( boolean dropSuccessful ) {
diff --git a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/TopComponentDragSupport.java b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/TopComponentDragSupport.java
index 27e7572..58d2c24 100644
--- a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/TopComponentDragSupport.java
+++ b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/TopComponentDragSupport.java
@@ -568,11 +568,12 @@ implements AWTEventListener, DragSourceListener, DragSourceMotionListener {
final Set<Component> floatingFrames = windowDnDManager.getFloatingFrames();
// Finally schedule the "drop" task later to be able to
// detect if ESC was pressed.
+ final Point location = WindowDnDManager.getLocationWorkaround(evt);
RequestProcessor.getDefault().post(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(createDropIntoFreeAreaTask(
- evt, evt.getLocation(), floatingFrames));
+ evt, location, floatingFrames));
}},
350 // XXX #21918, Neccessary to skip after possible ESC key event.
);
@@ -589,8 +590,7 @@ implements AWTEventListener, DragSourceListener, DragSourceMotionListener {
return true;
}
- // Gets location.
- Point location = evt.getLocation();
+ Point location = WindowDnDManager.getLocationWorkaround(evt);
if(location == null) {
return true;
}
diff --git a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/WindowDnDManager.java b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/WindowDnDManager.java
index a5206c8..7980960 100644
--- a/platform/core.windows/src/org/netbeans/core/windows/view/dnd/WindowDnDManager.java
+++ b/platform/core.windows/src/org/netbeans/core/windows/view/dnd/WindowDnDManager.java
@@ -35,6 +35,7 @@ import org.netbeans.core.windows.*;
import org.netbeans.core.windows.view.*;
import org.netbeans.core.windows.view.ui.*;
import org.openide.util.Lookup;
+import org.openide.util.Utilities;
import org.openide.util.WeakSet;
import org.openide.windows.TopComponent;
@@ -111,8 +112,44 @@ implements DropTargetGlassPane.Observer, DropTargetGlassPane.Informer {
AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK
);
}
-
+ /**
+ * Get the location of a {@link DragSourceEvent}, incorporating a workaround for a JDK bug on
+ * HiDPI screens on Windows. See NETBEANS-2954. This method should be called only while the
+ * mouse pointer is still likely to be in the same position as it was when the event was
+ * originally created.
+ */
+ public static Point getLocationWorkaround(DragSourceEvent evt) {
+ Point ret = evt.getLocation();
+ if (Utilities.isWindows() && ret != null) {
+ /* Workaround for JDK bug where DragSourceEvent.getLocation() returns incorrect screen
+ coordinates for displays with HiDPI scaling on Windows. Use MouseInfo.getPointerInfo
+ instead; that one handles HiDPI displays correctly. In the JDK codebase, the bug can be
+ seen by comparing the correct implementation of MouseInfo.getPointerInfo at
+
+ java.desktop/windows/native/libawt/windows/MouseInfo.cpp
+ (see Java_sun_awt_windows_WMouseInfoPeer_fillPointWithCoords )
+
+ with the function AwtDragSource::GiveFeedback, which initiates the creation of
+ DragSourceEvent objects, in
+
+ java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp
+ (see GetCursorPos, call_dSCenter, and call_dSCmotion calls in
+ AwtDragSource::GiveFeedback)
+
+ In both cases the screen coordinates of the mouse pointer is retrieved using the
+ "GetCursorPos" Windows API function. This one seems to return device coordinates rather
+ than logical coordinates, presumably because the java.exe executable (and the NetBeans
+ launcher, since NETBEANS-1227) declares itself to be fully DPI-aware. In MouseInfo.cpp,
+ extra code is added to convert the device coordinates to logical coordinates based on
+ the DPI scaling level. This is not done in awt_DnDDS.cpp, however. */
+ PointerInfo pointerInfo = MouseInfo.getPointerInfo();
+ if (pointerInfo != null) {
+ ret = pointerInfo.getLocation();
+ }
+ }
+ return ret;
+ }
/** Indicates whether the window drag and drop is enabled. */
public static boolean isDnDEnabled() {
@@ -990,7 +1027,7 @@ implements DropTargetGlassPane.Observer, DropTargetGlassPane.Informer {
debugLog("dragMouseMoved evt=" + evt); // NOI18N
}
- Point location = evt.getLocation();
+ Point location = WindowDnDManager.getLocationWorkaround(evt);
if(location == null) {
return;
}
diff --git a/platform/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/DnDSupport.java b/platform/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/DnDSupport.java
index d9e8d10..3c45e85 100644
--- a/platform/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/DnDSupport.java
+++ b/platform/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/DnDSupport.java
@@ -60,12 +60,12 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.netbeans.core.windows.nativeaccess.NativeWindowSystem;
+import org.netbeans.core.windows.view.dnd.WindowDnDManager;
import org.openide.awt.Toolbar;
import org.openide.awt.ToolbarPool;
import org.openide.filesystems.FileUtil;
@@ -170,7 +170,9 @@ final class DnDSupport implements DragSourceListener, DragGestureListener, DropT
}
sourceComponent.repaint();
resetDropGesture();
- if( e.getDropSuccess() == false && !isInToolbarPanel( e.getLocation() ) ) {
+ if( e.getDropSuccess() == false &&
+ !isInToolbarPanel( WindowDnDManager.getLocationWorkaround(e) ) )
+ {
//TODO catch ESC key
removeButton( e.getDragSourceContext().getTransferable() );
}
@@ -320,28 +322,29 @@ final class DnDSupport implements DragSourceListener, DragGestureListener, DropT
}
public void dragMouseMoved(DragSourceDragEvent e) {
+ Point location = WindowDnDManager.getLocationWorkaround(e);
DragSourceContext context = e.getDragSourceContext();
if( isButtonDrag ) {
int action = e.getDropAction();
if ((action & DnDConstants.ACTION_MOVE) != 0) {
context.setCursor( dragMoveCursor );
} else {
- if( isInToolbarPanel( e.getLocation() ) ) {
+ if( isInToolbarPanel( location ) ) {
context.setCursor( dragNoDropCursor );
} else {
context.setCursor( dragRemoveCursor );
}
}
} else if( isToolbarDrag && null != dragWindow ) {
- Point p = new Point( e.getLocation() );
+ Point p = new Point( location );
p.x -= startingPoint.x;
p.y -= startingPoint.y;
dragWindow.setLocation(p);
context.setCursor( Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) );
- ToolbarRow row = config.getToolbarRowAt( e.getLocation() );
+ ToolbarRow row = config.getToolbarRowAt( location );
if( null == row && (sourceRow.countVisibleToolbars() > 1 || !config.isLastRow(sourceRow)) ) {
- row = config.maybeAddEmptyRow( e.getLocation() );
+ row = config.maybeAddEmptyRow( location );
}
ToolbarRow oldRow = currentRow;
@@ -351,7 +354,7 @@ final class DnDSupport implements DragSourceListener, DragGestureListener, DropT
config.repaint();
}
if( null != currentRow )
- currentRow.showDropFeedback( sourceContainer, e.getLocation(), dragImage );
+ currentRow.showDropFeedback( sourceContainer, location, dragImage );
if( !config.isLastRow(currentRow) )
config.maybeRemoveLastRow();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists