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 10fb35212d4..01ec5ea9f21 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 @@ -3970,6 +3970,11 @@ void subclass () { public Point toControl (int x, int y) { checkWidget (); int zoom = getZoom(); + if (getDisplay().isRescalingAtRuntime()) { + Point displayPointInPixels = getDisplay().translateLocationInPixelsInDisplayCoordinateSystem(x, y); + final Point controlPointInPixels = toControlInPixels(displayPointInPixels.x, displayPointInPixels.y); + return DPIUtil.scaleDown(controlPointInPixels, zoom); + } return DPIUtil.scaleDown(toControlInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom); } @@ -4003,9 +4008,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,6 +4034,10 @@ public Point toControl (Point point) { public Point toDisplay (int x, int y) { checkWidget (); int zoom = getZoom(); + if (getDisplay().isRescalingAtRuntime()) { + Point displayPointInPixels = toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)); + return getDisplay().translateLocationInPointInDisplayCoordinateSystem(displayPointInPixels.x, displayPointInPixels.y); + } return DPIUtil.scaleDown(toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom); } @@ -4064,9 +4071,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 0c8a71f4d02..2871c11890c 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 @@ -1704,7 +1704,11 @@ public Control getCursorControl () { */ public Point getCursorLocation () { checkDevice (); - return DPIUtil.autoScaleDown(getCursorLocationInPixels()); + Point cursorLocationInPixels = getCursorLocationInPixels(); + if (isRescalingAtRuntime()) { + return translateLocationInPointInDisplayCoordinateSystem(cursorLocationInPixels.x, cursorLocationInPixels.y); + } + return DPIUtil.autoScaleDown(cursorLocationInPixels); } Point getCursorLocationInPixels () { @@ -2183,14 +2187,21 @@ 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; + + if (DPIUtil.isAutoScaleOnRuntimeActive()) { + int autoscaleZoom = DPIUtil.getZoomForAutoscaleProperty(result); + monitor.setBounds(getMonitorBoundsInPointsInDisplayCoordinateSystem(boundsInPixels, autoscaleZoom)); + monitor.setClientArea(getMonitorBoundsInPointsInDisplayCoordinateSystem(clientAreaInPixels, autoscaleZoom)); + } else { + monitor.setBounds(DPIUtil.autoScaleDown(boundsInPixels)); + monitor.setClientArea(DPIUtil.autoScaleDown(clientAreaInPixels)); + } if (result == 0) { System.err.println("***WARNING: GetDpiForMonitor: SWT could not get valid monitor scaling factor."); result = 100; @@ -2203,6 +2214,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. * @@ -2944,6 +2962,9 @@ boolean isValidThread () { public Point map (Control from, Control to, Point point) { checkDevice (); if (point == null) error (SWT.ERROR_NULL_ARGUMENT); + if (isRescalingAtRuntime()) { + return map(from, to, point.x, point.y); + } int zoom = getZoomLevelForMapping(from, to); point = DPIUtil.scaleUp(point, zoom); return DPIUtil.scaleDown(mapInPixels(from, to, point), zoom); @@ -2991,6 +3012,20 @@ Point mapInPixels (Control from, Control to, Point point) { */ public Point map (Control from, Control to, int x, int y) { checkDevice (); + if (isRescalingAtRuntime()) { + Point mappedPointInPoints; + if (from == null) { + Point mappedPointInpixels = mapInPixels(from, to, getPixelsFromPoint(to.getShell().getMonitor(), 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 = getPointFromPixels(from.getShell().getMonitor(), mappedPointInpixels.x, mappedPointInpixels.y); + } else { + Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom())); + mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom()); + } + return mappedPointInPoints; + } int zoom = getZoomLevelForMapping(from, to); x = DPIUtil.scaleUp(x, zoom); y = DPIUtil.scaleUp(y, zoom); @@ -3058,6 +3093,9 @@ 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); + if (isRescalingAtRuntime()) { + return map(from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height); + } int zoom = getZoomLevelForMapping(from, to); rectangle = DPIUtil.scaleUp(rectangle, zoom); return DPIUtil.scaleDown(mapInPixels(from, to, rectangle), zoom); @@ -3107,6 +3145,20 @@ Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) { */ public Rectangle map (Control from, Control to, int x, int y, int width, int height) { checkDevice (); + if (isRescalingAtRuntime()) { + Rectangle mappedRectangleInPoints; + if (from == null) { + Rectangle mappedRectangleInPixels = mapInPixels(from, to, translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, to.getShell().getMonitor())); + 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 = translateRectangleInPointsInDisplayCoordinateSystem(mappedRectangleInPixels.x, mappedRectangleInPixels.y, mappedRectangleInPixels.width, mappedRectangleInPixels.height, from.getShell().getMonitor()); + } else { + Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom())); + mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom()); + } + return mappedRectangleInPoints; + } int zoom = getZoomLevelForMapping(from, to); x = DPIUtil.scaleUp(x, zoom); y = DPIUtil.scaleUp(y, zoom); @@ -3130,6 +3182,57 @@ Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int he return new Rectangle (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); } +Point translateLocationInPixelsInDisplayCoordinateSystem(int x, int y) { + Monitor monitor = getContainingMonitor(x, y); + return getPixelsFromPoint(monitor, x, y); +} + +Point translateLocationInPointInDisplayCoordinateSystem(int x, int y) { + Monitor monitor = getContainingMonitorInPixelsCoordinate(x, y); + return getPointFromPixels(monitor, x, y); +} + +Rectangle translateRectangleInPixelsInDisplayCoordinateSystemByContainment(int x, int y, int width, int height) { + Monitor monitorByLocation = getContainingMonitor(x, y); + Monitor monitorByContainment = getContainingMonitor(x, y, width, height); + return translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, monitorByLocation, monitorByContainment); +} + +private Rectangle translateRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height, Monitor monitor) { + return translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, monitor, monitor); +} + +private Rectangle translateRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height, Monitor monitorOfLocation, Monitor monitorOfArea) { + Point topLeft = getPixelsFromPoint(monitorOfLocation, x, y); + int zoom = getApplicableMonitorZoom(monitorOfArea); + int widthInPixels = DPIUtil.scaleUp(width, zoom); + int heightInPixels = DPIUtil.scaleUp(height, zoom); + return new Rectangle(topLeft.x, topLeft.y, widthInPixels, heightInPixels); +} + +Rectangle translateRectangleInPointsInDisplayCoordinateSystemByContainment(int x, int y, int widthInPixels, int heightInPixels) { + Monitor monitorByLocation = getContainingMonitor(x, y); + Monitor monitorByContainment = getContainingMonitor(x, y, widthInPixels, heightInPixels); + return translateRectangleInPointsInDisplayCoordinateSystem(x, y, widthInPixels, heightInPixels, monitorByLocation, monitorByContainment); +} + +private Rectangle translateRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels, Monitor monitor) { + return translateRectangleInPointsInDisplayCoordinateSystem(x, y, widthInPixels, heightInPixels, monitor, monitor); +} + + +private Rectangle translateRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels, Monitor monitorOfLocation, Monitor monitorOfArea) { + Point topLeft = getPointFromPixels(monitorOfLocation, x, y); + int zoom = getApplicableMonitorZoom(monitorOfArea); + int width = DPIUtil.scaleDown(widthInPixels, zoom); + int height = DPIUtil.scaleDown(heightInPixels, zoom); + return new Rectangle(topLeft.x, topLeft.y, width, height); +} + +private int getApplicableMonitorZoom(Monitor monitor) { + return DPIUtil.getZoomForAutoscaleProperty(isRescalingAtRuntime() ? monitor.zoom : getDeviceZoom()); +} + long messageProc (long hwnd, long msg, long wParam, long lParam) { switch ((int)msg) { case SWT_RUNASYNC: { @@ -4355,7 +4458,12 @@ public void sendPostExternalEventDispatchEvent () { */ public void setCursorLocation (int x, int y) { checkDevice (); - setCursorLocationInPixels (DPIUtil.autoScaleUp (x), DPIUtil.autoScaleUp (y)); + if (isRescalingAtRuntime()) { + Point cursorLocationInPixels = translateLocationInPixelsInDisplayCoordinateSystem(x, y); + setCursorLocationInPixels (cursorLocationInPixels.x, cursorLocationInPixels.y); + } else { + setCursorLocationInPixels (DPIUtil.autoScaleUp (x), DPIUtil.autoScaleUp (y)); + } } void setCursorLocationInPixels (int x, int y) { @@ -5390,4 +5498,63 @@ private boolean setDPIAwareness(int desiredDpiAwareness) { return true; } +private 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(); +} + +private Monitor getContainingMonitor(int x, int y, int width, int height) { + Rectangle rectangle = new Rectangle(x, y, width, height); + Monitor[] monitors = getMonitors(); + Monitor selectedMonitor = getPrimaryMonitor(); + int highestArea = 0; + for (Monitor currentMonitor : monitors) { + Rectangle clientArea = currentMonitor.getClientArea(); + Rectangle intersection = clientArea.intersection(rectangle); + int area = intersection.width * intersection.height; + if (area > highestArea) { + selectedMonitor = currentMonitor; + highestArea = area; + } + } + return selectedMonitor; +} + +private Monitor getContainingMonitorInPixelsCoordinate(int xInPixels, int yInPixels) { + Monitor[] monitors = getMonitors(); + for (Monitor current : monitors) { + Rectangle clientArea = getMonitorClientAreaInPixels(current); + if (clientArea.contains(xInPixels, yInPixels)) { + return current; + } + } + return getPrimaryMonitor(); +} + +private Rectangle getMonitorClientAreaInPixels(Monitor monitor) { + int zoom = getApplicableMonitorZoom(monitor); + int widthInPixels = DPIUtil.scaleUp(monitor.clientWidth, zoom); + int heightInPixels = DPIUtil.scaleUp(monitor.clientHeight, zoom); + return new Rectangle(monitor.clientX, monitor.clientY, widthInPixels, heightInPixels); +} + +private Point getPixelsFromPoint(Monitor monitor, int x, int y) { + int zoom = getApplicableMonitorZoom(monitor); + int mappedX = DPIUtil.scaleUp(x - monitor.clientX, zoom) + monitor.clientX; + int mappedY = DPIUtil.scaleUp(y - monitor.clientY, zoom) + monitor.clientY; + return new Point(mappedX, mappedY); +} + +private Point getPointFromPixels(Monitor monitor, int x, int y) { + int zoom = getApplicableMonitorZoom(monitor); + int mappedX = DPIUtil.scaleDown(x - monitor.clientX, zoom) + monitor.clientX; + int mappedY = DPIUtil.scaleDown(y - monitor.clientY, zoom) + monitor.clientY; + return new Point(mappedX, mappedY); +} } 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 f7a75caf757..f30872a8c3a 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 @@ -1566,6 +1566,56 @@ public void setAlpha (int alpha) { } } +@Override +public Rectangle getBounds() { + if (getDisplay().isRescalingAtRuntime()) { + Rectangle boundsInPixels = getBoundsInPixels(); + return display.translateRectangleInPointsInDisplayCoordinateSystemByContainment(boundsInPixels.x, boundsInPixels.y, boundsInPixels.width, boundsInPixels.height); + } + return super.getBounds(); +} + +@Override +public Point getLocation() { + if (getDisplay().isRescalingAtRuntime()) { + Point locationInPixels = getLocationInPixels(); + return display.translateLocationInPointInDisplayCoordinateSystem(locationInPixels.x, locationInPixels.y); + } + return super.getLocation(); +} + +@Override +public void setLocation(Point location) { + if (location == null) error (SWT.ERROR_NULL_ARGUMENT); + setLocation(location.x, location.y); +} + +@Override +public void setLocation(int x, int y) { + if (getDisplay().isRescalingAtRuntime()) { + Point location = display.translateLocationInPixelsInDisplayCoordinateSystem(x, y); + setLocationInPixels(location.x, location.y); + } else { + super.setLocation(x, 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 width, int height) { + if (getDisplay().isRescalingAtRuntime()) { + Rectangle boundsInPixels = display.translateRectangleInPixelsInDisplayCoordinateSystemByContainment(x, y, width, height); + setBoundsInPixels(boundsInPixels.x, boundsInPixels.y, boundsInPixels.width, boundsInPixels.height); + } else { + super.setBounds(x, y, width, height); + } +} + @Override void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) { if (fullScreen) setFullScreen (false);