diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index 9c1f6c9e5c1..01f6f3470fe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -3969,8 +3969,9 @@ void subclass () { */ public Point toControl (int x, int y) { checkWidget (); - int zoom = getZoom(); - return DPIUtil.scaleDown(toControlInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom); + Point displayPointInPixels = getDisplay().getLocationInPixelsInDisplayCoordinateSystem(x, y); + final Point controlPointInPixels = toControlInPixels(displayPointInPixels.x, displayPointInPixels.y); + return DPIUtil.scaleDown(controlPointInPixels, getZoom()); } Point toControlInPixels (int x, int y) { @@ -4003,9 +4004,7 @@ Point toControlInPixels (int x, int y) { public Point toControl (Point point) { checkWidget (); if (point == null) error (SWT.ERROR_NULL_ARGUMENT); - int zoom = getZoom(); - point = DPIUtil.scaleUp(point, zoom); - return DPIUtil.scaleDown(toControlInPixels(point.x, point.y), zoom); + return toControl(point.x, point.y); } /** @@ -4031,7 +4030,8 @@ public Point toControl (Point point) { public Point toDisplay (int x, int y) { checkWidget (); int zoom = getZoom(); - return DPIUtil.scaleDown(toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom); + Point displayPointInPixels = toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)); + return getDisplay().getLocationInPointInDisplayCoordinateSystem(displayPointInPixels); } Point toDisplayInPixels (int x, int y) { @@ -4064,9 +4064,7 @@ Point toDisplayInPixels (int x, int y) { public Point toDisplay (Point point) { checkWidget (); if (point == null) error (SWT.ERROR_NULL_ARGUMENT); - int zoom = getZoom(); - point = DPIUtil.scaleUp(point, zoom); - return DPIUtil.scaleDown(toDisplayInPixels(point.x, point.y), zoom); + return toDisplay(point.x, point.y); } long topHandle () { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 13c0e43ffae..629123fae23 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -1691,7 +1691,8 @@ public Control getCursorControl () { */ public Point getCursorLocation () { checkDevice (); - return DPIUtil.autoScaleDown(getCursorLocationInPixels()); + Point cursorLocationInPixels = getCursorLocationInPixels(); + return getLocationInPointInDisplayCoordinateSystem(cursorLocationInPixels.x, cursorLocationInPixels.y); } Point getCursorLocationInPixels () { @@ -1700,6 +1701,30 @@ Point getCursorLocationInPixels () { return new Point (pt.x, pt.y); } +Point getLocationInPixelsInDisplayCoordinateSystem(Point point) { + return getLocationInPixelsInDisplayCoordinateSystem(point.x, point.y); +} + +Point getLocationInPixelsInDisplayCoordinateSystem(int x, int y) { + Monitor monitor = getContainingMonitor(x, y); + int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom); + x = DPIUtil.scaleUp(x - monitor.clientX, zoom) + monitor.clientX; + y = DPIUtil.scaleUp(y - monitor.clientY, zoom) + monitor.clientY; + return new Point(x, y); +} + +Point getLocationInPointInDisplayCoordinateSystem(Point point) { + return getLocationInPointInDisplayCoordinateSystem(point.x, point.y); +} + +Point getLocationInPointInDisplayCoordinateSystem(int x, int y) { + Monitor monitor = getContainingMonitorInPixelsCoordiate(x, y); + int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom); + x = DPIUtil.scaleDown(x - monitor.clientX, zoom) + monitor.clientX; + y = DPIUtil.scaleDown(y - monitor.clientY, zoom) + monitor.clientY; + return new Point(x, y); +} + /** * Returns an array containing the recommended cursor sizes. * @@ -2170,18 +2195,25 @@ Monitor getMonitor (long hmonitor) { OS.GetMonitorInfo (hmonitor, lpmi); Monitor monitor = new Monitor (); monitor.handle = hmonitor; - Rectangle boundsInPixels = new Rectangle (lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top); - monitor.setBounds (DPIUtil.autoScaleDown (boundsInPixels)); - Rectangle clientAreaInPixels = new Rectangle (lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top); - monitor.setClientArea (DPIUtil.autoScaleDown (clientAreaInPixels)); + Rectangle boundsInPixels = new Rectangle(lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top); + Rectangle clientAreaInPixels = new Rectangle(lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top); int [] dpiX = new int[1]; int [] dpiY = new int[1]; int result = OS.GetDpiForMonitor (monitor.handle, OS.MDT_EFFECTIVE_DPI, dpiX, dpiY); result = (result == OS.S_OK) ? DPIUtil.mapDPIToZoom (dpiX[0]) : 100; + + int autoscaleZoom; + if (DPIUtil.isAutoScaleOnRuntimeActive()) { + autoscaleZoom = DPIUtil.getZoomForAutoscaleProperty(result); + } else { + autoscaleZoom = DPIUtil.getDeviceZoom(); + } if (result == 0) { System.err.println("***WARNING: GetDpiForMonitor: SWT could not get valid monitor scaling factor."); result = 100; } + monitor.setBounds(getMonitorBoundsInPointsInDisplayCoordinateSystem(boundsInPixels, autoscaleZoom)); + monitor.setClientArea(getMonitorBoundsInPointsInDisplayCoordinateSystem(clientAreaInPixels, autoscaleZoom)); /* * Always return true monitor zoom value as fetched from native, else will lead * to scaling issue on OS Win8.1 and above, for more details refer bug 537614. @@ -2190,6 +2222,13 @@ Monitor getMonitor (long hmonitor) { return monitor; } +private Rectangle getMonitorBoundsInPointsInDisplayCoordinateSystem(Rectangle boundsInPixels, int zoom) { + Rectangle bounds = DPIUtil.scaleDown(boundsInPixels, zoom); + bounds.x = boundsInPixels.x; + bounds.y = boundsInPixels.y; + return bounds; +} + /** * Returns an array of monitors attached to the device. * @@ -2969,9 +3008,7 @@ boolean isValidThread () { public Point map (Control from, Control to, Point point) { checkDevice (); if (point == null) error (SWT.ERROR_NULL_ARGUMENT); - int zoom = getZoomLevelForMapping(from, to); - point = DPIUtil.scaleUp(point, zoom); - return DPIUtil.scaleDown(mapInPixels(from, to, point), zoom); + return map(from, to, point.x, point.y); } Point mapInPixels (Control from, Control to, Point point) { @@ -3016,10 +3053,18 @@ Point mapInPixels (Control from, Control to, Point point) { */ public Point map (Control from, Control to, int x, int y) { checkDevice (); - int zoom = getZoomLevelForMapping(from, to); - x = DPIUtil.scaleUp(x, zoom); - y = DPIUtil.scaleUp(y, zoom); - return DPIUtil.scaleDown(mapInPixels(from, to, x, y), zoom); + Point mappedPointInPoints; + if (from == null) { + Point mappedPointInpixels = mapInPixels(from, to, getLocationInPixelsInDisplayCoordinateSystem(x, y)); + mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom()); + } else if (to == null) { + Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom())); + mappedPointInPoints = getLocationInPointInDisplayCoordinateSystem(mappedPointInpixels); + } else { + Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom())); + mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom()); + } + return mappedPointInPoints; } Point mapInPixels (Control from, Control to, int x, int y) { @@ -3035,15 +3080,6 @@ Point mapInPixels (Control from, Control to, int x, int y) { return new Point (point.x, point.y); } -private int getZoomLevelForMapping(Control from, Control to) { - if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); - if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); - if (to != null) { - return to.getZoom(); - } - return from.getZoom(); -} - /** * Maps a point from one coordinate system to another. * When the control is null, coordinates are mapped to @@ -3083,9 +3119,25 @@ private int getZoomLevelForMapping(Control from, Control to) { public Rectangle map (Control from, Control to, Rectangle rectangle) { checkDevice (); if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT); - int zoom = getZoomLevelForMapping(from, to); - rectangle = DPIUtil.scaleUp(rectangle, zoom); - return DPIUtil.scaleDown(mapInPixels(from, to, rectangle), zoom); + return map(from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height); +} + +private Rectangle getRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height) { + Point topLeft = getLocationInPixelsInDisplayCoordinateSystem(x, y); + Monitor monitor = getContainingMonitor(x, y); + int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom); + int widthInPixels = DPIUtil.scaleUp(width, zoom); + int heightInPixels = DPIUtil.scaleUp(height, zoom); + return new Rectangle(topLeft.x, topLeft.y, widthInPixels, heightInPixels); +} + +private Rectangle getRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels) { + Point topLeft = getLocationInPointInDisplayCoordinateSystem(x, y); + Monitor monitor = getContainingMonitorInPixelsCoordiate(x, y); + int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom); + int width = DPIUtil.scaleDown(widthInPixels, zoom); + int height = DPIUtil.scaleDown(heightInPixels, zoom); + return new Rectangle(topLeft.x, topLeft.y, width, height); } Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) { @@ -3132,12 +3184,18 @@ Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) { */ public Rectangle map (Control from, Control to, int x, int y, int width, int height) { checkDevice (); - int zoom = getZoomLevelForMapping(from, to); - x = DPIUtil.scaleUp(x, zoom); - y = DPIUtil.scaleUp(y, zoom); - width = DPIUtil.scaleUp(width, zoom); - height = DPIUtil.scaleUp(height, zoom); - return DPIUtil.scaleDown(mapInPixels(from, to, x, y, width, height), zoom); + Rectangle mappedRectangleInPoints; + if (from == null) { + Rectangle mappedRectangleInPixels = mapInPixels(from, to, getRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height)); + mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom()); + } else if (to == null) { + Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom())); + mappedRectangleInPoints = getRectangleInPointsInDisplayCoordinateSystem(mappedRectangleInPixels.x, mappedRectangleInPixels.y, mappedRectangleInPixels.width, mappedRectangleInPixels.height); + } else { + Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom())); + mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom()); + } + return mappedRectangleInPoints; } Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int height) { @@ -4380,7 +4438,8 @@ public void sendPostExternalEventDispatchEvent () { */ public void setCursorLocation (int x, int y) { checkDevice (); - setCursorLocationInPixels (DPIUtil.autoScaleUp (x), DPIUtil.autoScaleUp (y)); + Point cursorLocationInPixels = getLocationInPixelsInDisplayCoordinateSystem(x, y); + setCursorLocationInPixels (cursorLocationInPixels.x, cursorLocationInPixels.y); } void setCursorLocationInPixels (int x, int y) { @@ -5306,4 +5365,27 @@ private void setProperDPIAwareness() { } } +Monitor getContainingMonitor(int x, int y) { + Monitor[] monitors = getMonitors(); + for (Monitor currentMonitor : monitors) { + Rectangle clientArea = currentMonitor.getClientArea(); + if (clientArea.contains(x, y)) { + return currentMonitor; + } + } + return getPrimaryMonitor(); +} + +Monitor getContainingMonitorInPixelsCoordiate(int xInPixels, int yInPixels) { + Monitor[] monitors = getMonitors(); + for (Monitor current : monitors) { + Rectangle clientArea = DPIUtil.scaleUp(current.getClientArea(), DPIUtil.getZoomForAutoscaleProperty(current.zoom)); + clientArea.x = current.clientX; + clientArea.y = current.clientY; + if (clientArea.contains(xInPixels, yInPixels)) { + return current; + } + } + return getPrimaryMonitor(); +} } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java index 64bd00650d0..61aeaf88be0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java @@ -1571,6 +1571,50 @@ public void setAlpha (int alpha) { } } +@Override +public Rectangle getBounds() { + Rectangle boundsInPixels = getBoundsInPixels (); + Rectangle bounds = DPIUtil.scaleDown(boundsInPixels, getZoom()); + Point pointWithMonitorOffset = display.getLocationInPointInDisplayCoordinateSystem(boundsInPixels.x, boundsInPixels.y); + bounds.x = pointWithMonitorOffset.x; + bounds.y = pointWithMonitorOffset.y; + return bounds; +} + +@Override +public Point getLocation() { + Point locationInPixels = getLocationInPixels(); + Point location = display.getLocationInPointInDisplayCoordinateSystem(locationInPixels.x, locationInPixels.y); + return location; +} + +@Override +public void setLocation(Point location) { + if (location == null) error (SWT.ERROR_NULL_ARGUMENT); + location = display.getLocationInPixelsInDisplayCoordinateSystem(location.x, location.y); + setLocationInPixels(location.x, location.y); +} + +@Override +public void setLocation(int x, int y) { + Point location = display.getLocationInPixelsInDisplayCoordinateSystem(x, y); + setLocationInPixels(location.x, location.y); +} + +@Override +public void setBounds(Rectangle rect) { + if (rect == null) error (SWT.ERROR_NULL_ARGUMENT); + setBounds(rect.x, rect.y, rect.width, rect.height); +} + +@Override +public void setBounds(int x, int y, int width2, int height2) { + Point topLeft = display.getLocationInPixelsInDisplayCoordinateSystem(x, y); + int width = DPIUtil.scaleUp(width2, getZoom()); + int height = DPIUtil.scaleUp(height2, getZoom()); + setBoundsInPixels(topLeft.x, topLeft.y, width, height); +} + @Override void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) { if (fullScreen) setFullScreen (false);