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 <eba...@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-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists