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