Skip to content

Commit 4f60cb6

Browse files
akoch-yattafedejeanne
authored andcommitted
Redesigned the Display coordinate system for win32
This commit enforces displays to store x,y coordinates in point as the absolute pixels in the display coordinate system. while scaling the width and height to the points, following this the map methods are reimplemented to do the right conversion between the new display coordinate system and the coordinates within a control. contributes to eclipse-platform#62 and eclipse-platform#127
1 parent 03408d8 commit 4f60cb6

File tree

3 files changed

+197
-40
lines changed

3 files changed

+197
-40
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3969,8 +3969,9 @@ void subclass () {
39693969
*/
39703970
public Point toControl (int x, int y) {
39713971
checkWidget ();
3972-
int zoom = getZoom();
3973-
return DPIUtil.scaleDown(toControlInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom);
3972+
Point displayPointInPixels = getDisplay().translateLocationInPixelsInDisplayCoordinateSystem(x, y);
3973+
final Point controlPointInPixels = toControlInPixels(displayPointInPixels.x, displayPointInPixels.y);
3974+
return DPIUtil.scaleDown(controlPointInPixels, getZoom());
39743975
}
39753976

39763977
Point toControlInPixels (int x, int y) {
@@ -4003,9 +4004,7 @@ Point toControlInPixels (int x, int y) {
40034004
public Point toControl (Point point) {
40044005
checkWidget ();
40054006
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
4006-
int zoom = getZoom();
4007-
point = DPIUtil.scaleUp(point, zoom);
4008-
return DPIUtil.scaleDown(toControlInPixels(point.x, point.y), zoom);
4007+
return toControl(point.x, point.y);
40094008
}
40104009

40114010
/**
@@ -4031,7 +4030,8 @@ public Point toControl (Point point) {
40314030
public Point toDisplay (int x, int y) {
40324031
checkWidget ();
40334032
int zoom = getZoom();
4034-
return DPIUtil.scaleDown(toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom)), zoom);
4033+
Point displayPointInPixels = toDisplayInPixels(DPIUtil.scaleUp(x, zoom), DPIUtil.scaleUp(y, zoom));
4034+
return getDisplay().translateLocationInPointInDisplayCoordinateSystem(displayPointInPixels.x, displayPointInPixels.y);
40354035
}
40364036

40374037
Point toDisplayInPixels (int x, int y) {
@@ -4064,9 +4064,7 @@ Point toDisplayInPixels (int x, int y) {
40644064
public Point toDisplay (Point point) {
40654065
checkWidget ();
40664066
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
4067-
int zoom = getZoom();
4068-
point = DPIUtil.scaleUp(point, zoom);
4069-
return DPIUtil.scaleDown(toDisplayInPixels(point.x, point.y), zoom);
4067+
return toDisplay(point.x, point.y);
40704068
}
40714069

40724070
long topHandle () {

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java

Lines changed: 154 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,8 @@ public Control getCursorControl () {
16911691
*/
16921692
public Point getCursorLocation () {
16931693
checkDevice ();
1694-
return DPIUtil.autoScaleDown(getCursorLocationInPixels());
1694+
Point cursorLocationInPixels = getCursorLocationInPixels();
1695+
return translateLocationInPointInDisplayCoordinateSystem(cursorLocationInPixels.x, cursorLocationInPixels.y);
16951696
}
16961697

16971698
Point getCursorLocationInPixels () {
@@ -2170,18 +2171,25 @@ Monitor getMonitor (long hmonitor) {
21702171
OS.GetMonitorInfo (hmonitor, lpmi);
21712172
Monitor monitor = new Monitor ();
21722173
monitor.handle = hmonitor;
2173-
Rectangle boundsInPixels = new Rectangle (lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top);
2174-
monitor.setBounds (DPIUtil.autoScaleDown (boundsInPixels));
2175-
Rectangle clientAreaInPixels = new Rectangle (lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top);
2176-
monitor.setClientArea (DPIUtil.autoScaleDown (clientAreaInPixels));
2174+
Rectangle boundsInPixels = new Rectangle(lpmi.rcMonitor_left, lpmi.rcMonitor_top, lpmi.rcMonitor_right - lpmi.rcMonitor_left,lpmi.rcMonitor_bottom - lpmi.rcMonitor_top);
2175+
Rectangle clientAreaInPixels = new Rectangle(lpmi.rcWork_left, lpmi.rcWork_top, lpmi.rcWork_right - lpmi.rcWork_left, lpmi.rcWork_bottom - lpmi.rcWork_top);
21772176
int [] dpiX = new int[1];
21782177
int [] dpiY = new int[1];
21792178
int result = OS.GetDpiForMonitor (monitor.handle, OS.MDT_EFFECTIVE_DPI, dpiX, dpiY);
21802179
result = (result == OS.S_OK) ? DPIUtil.mapDPIToZoom (dpiX[0]) : 100;
2180+
2181+
int autoscaleZoom;
2182+
if (DPIUtil.isAutoScaleOnRuntimeActive()) {
2183+
autoscaleZoom = DPIUtil.getZoomForAutoscaleProperty(result);
2184+
} else {
2185+
autoscaleZoom = DPIUtil.getDeviceZoom();
2186+
}
21812187
if (result == 0) {
21822188
System.err.println("***WARNING: GetDpiForMonitor: SWT could not get valid monitor scaling factor.");
21832189
result = 100;
21842190
}
2191+
monitor.setBounds(getMonitorBoundsInPointsInDisplayCoordinateSystem(boundsInPixels, autoscaleZoom));
2192+
monitor.setClientArea(getMonitorBoundsInPointsInDisplayCoordinateSystem(clientAreaInPixels, autoscaleZoom));
21852193
/*
21862194
* Always return true monitor zoom value as fetched from native, else will lead
21872195
* to scaling issue on OS Win8.1 and above, for more details refer bug 537614.
@@ -2190,6 +2198,13 @@ Monitor getMonitor (long hmonitor) {
21902198
return monitor;
21912199
}
21922200

2201+
private Rectangle getMonitorBoundsInPointsInDisplayCoordinateSystem(Rectangle boundsInPixels, int zoom) {
2202+
Rectangle bounds = DPIUtil.scaleDown(boundsInPixels, zoom);
2203+
bounds.x = boundsInPixels.x;
2204+
bounds.y = boundsInPixels.y;
2205+
return bounds;
2206+
}
2207+
21932208
/**
21942209
* Returns an array of monitors attached to the device.
21952210
*
@@ -2969,9 +2984,7 @@ boolean isValidThread () {
29692984
public Point map (Control from, Control to, Point point) {
29702985
checkDevice ();
29712986
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
2972-
int zoom = getZoomLevelForMapping(from, to);
2973-
point = DPIUtil.scaleUp(point, zoom);
2974-
return DPIUtil.scaleDown(mapInPixels(from, to, point), zoom);
2987+
return map(from, to, point.x, point.y);
29752988
}
29762989

29772990
Point mapInPixels (Control from, Control to, Point point) {
@@ -3016,10 +3029,18 @@ Point mapInPixels (Control from, Control to, Point point) {
30163029
*/
30173030
public Point map (Control from, Control to, int x, int y) {
30183031
checkDevice ();
3019-
int zoom = getZoomLevelForMapping(from, to);
3020-
x = DPIUtil.scaleUp(x, zoom);
3021-
y = DPIUtil.scaleUp(y, zoom);
3022-
return DPIUtil.scaleDown(mapInPixels(from, to, x, y), zoom);
3032+
Point mappedPointInPoints;
3033+
if (from == null) {
3034+
Point mappedPointInpixels = mapInPixels(from, to, getPixelsFromPoint(to.getShell().getMonitor(), x, y));
3035+
mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom());
3036+
} else if (to == null) {
3037+
Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom()));
3038+
mappedPointInPoints = getPointFromPixels(from.getShell().getMonitor(), mappedPointInpixels.x, mappedPointInpixels.y);
3039+
} else {
3040+
Point mappedPointInpixels = mapInPixels(from, to, DPIUtil.scaleUp(new Point(x, y), from.getZoom()));
3041+
mappedPointInPoints = DPIUtil.scaleDown(mappedPointInpixels, to.getZoom());
3042+
}
3043+
return mappedPointInPoints;
30233044
}
30243045

30253046
Point mapInPixels (Control from, Control to, int x, int y) {
@@ -3035,15 +3056,6 @@ Point mapInPixels (Control from, Control to, int x, int y) {
30353056
return new Point (point.x, point.y);
30363057
}
30373058

3038-
private int getZoomLevelForMapping(Control from, Control to) {
3039-
if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
3040-
if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
3041-
if (to != null) {
3042-
return to.getZoom();
3043-
}
3044-
return from.getZoom();
3045-
}
3046-
30473059
/**
30483060
* Maps a point from one coordinate system to another.
30493061
* When the control is null, coordinates are mapped to
@@ -3083,9 +3095,7 @@ private int getZoomLevelForMapping(Control from, Control to) {
30833095
public Rectangle map (Control from, Control to, Rectangle rectangle) {
30843096
checkDevice ();
30853097
if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
3086-
int zoom = getZoomLevelForMapping(from, to);
3087-
rectangle = DPIUtil.scaleUp(rectangle, zoom);
3088-
return DPIUtil.scaleDown(mapInPixels(from, to, rectangle), zoom);
3098+
return map(from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
30893099
}
30903100

30913101
Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) {
@@ -3132,12 +3142,18 @@ Rectangle mapInPixels (Control from, Control to, Rectangle rectangle) {
31323142
*/
31333143
public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
31343144
checkDevice ();
3135-
int zoom = getZoomLevelForMapping(from, to);
3136-
x = DPIUtil.scaleUp(x, zoom);
3137-
y = DPIUtil.scaleUp(y, zoom);
3138-
width = DPIUtil.scaleUp(width, zoom);
3139-
height = DPIUtil.scaleUp(height, zoom);
3140-
return DPIUtil.scaleDown(mapInPixels(from, to, x, y, width, height), zoom);
3145+
Rectangle mappedRectangleInPoints;
3146+
if (from == null) {
3147+
Rectangle mappedRectangleInPixels = mapInPixels(from, to, translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, to.getShell().getMonitor()));
3148+
mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom());
3149+
} else if (to == null) {
3150+
Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom()));
3151+
mappedRectangleInPoints = translateRectangleInPointsInDisplayCoordinateSystem(mappedRectangleInPixels.x, mappedRectangleInPixels.y, mappedRectangleInPixels.width, mappedRectangleInPixels.height, from.getShell().getMonitor());
3152+
} else {
3153+
Rectangle mappedRectangleInPixels = mapInPixels(from, to, DPIUtil.scaleUp(new Rectangle(x, y, width, height), from.getZoom()));
3154+
mappedRectangleInPoints = DPIUtil.scaleDown(mappedRectangleInPixels, to.getZoom());
3155+
}
3156+
return mappedRectangleInPoints;
31413157
}
31423158

31433159
Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int height) {
@@ -3155,6 +3171,53 @@ Rectangle mapInPixels (Control from, Control to, int x, int y, int width, int he
31553171
return new Rectangle (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
31563172
}
31573173

3174+
Point translateLocationInPixelsInDisplayCoordinateSystem(int x, int y) {
3175+
Monitor monitor = getContainingMonitor(x, y);
3176+
return getPixelsFromPoint(monitor, x, y);
3177+
}
3178+
3179+
Point translateLocationInPointInDisplayCoordinateSystem(int x, int y) {
3180+
Monitor monitor = getContainingMonitorInPixelsCoordinate(x, y);
3181+
return getPointFromPixels(monitor, x, y);
3182+
}
3183+
3184+
Rectangle translateRectangleInPixelsInDisplayCoordinateSystemByContainment(int x, int y, int width, int height) {
3185+
Monitor monitorByLocation = getContainingMonitor(x, y);
3186+
Monitor monitorByContainment = getContainingMonitor(x, y, width, height);
3187+
return translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, monitorByLocation, monitorByContainment);
3188+
}
3189+
3190+
private Rectangle translateRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height, Monitor monitor) {
3191+
return translateRectangleInPixelsInDisplayCoordinateSystem(x, y, width, height, monitor, monitor);
3192+
}
3193+
3194+
private Rectangle translateRectangleInPixelsInDisplayCoordinateSystem(int x, int y, int width, int height, Monitor monitorOfLocation, Monitor monitorOfArea) {
3195+
Point topLeft = getPixelsFromPoint(monitorOfLocation, x, y);
3196+
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitorOfArea.zoom);
3197+
int widthInPixels = DPIUtil.scaleUp(width, zoom);
3198+
int heightInPixels = DPIUtil.scaleUp(height, zoom);
3199+
return new Rectangle(topLeft.x, topLeft.y, widthInPixels, heightInPixels);
3200+
}
3201+
3202+
Rectangle translateRectangleInPointsInDisplayCoordinateSystemByContainment(int x, int y, int widthInPixels, int heightInPixels) {
3203+
Monitor monitorByLocation = getContainingMonitor(x, y);
3204+
Monitor monitorByContainment = getContainingMonitor(x, y, widthInPixels, heightInPixels);
3205+
return translateRectangleInPointsInDisplayCoordinateSystem(x, y, widthInPixels, heightInPixels, monitorByLocation, monitorByContainment);
3206+
}
3207+
3208+
private Rectangle translateRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels, Monitor monitor) {
3209+
return translateRectangleInPointsInDisplayCoordinateSystem(x, y, widthInPixels, heightInPixels, monitor, monitor);
3210+
}
3211+
3212+
3213+
private Rectangle translateRectangleInPointsInDisplayCoordinateSystem(int x, int y, int widthInPixels, int heightInPixels, Monitor monitorOfLocation, Monitor monitorOfArea) {
3214+
Point topLeft = getPointFromPixels(monitorOfLocation, x, y);
3215+
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitorOfArea.zoom);
3216+
int width = DPIUtil.scaleDown(widthInPixels, zoom);
3217+
int height = DPIUtil.scaleDown(heightInPixels, zoom);
3218+
return new Rectangle(topLeft.x, topLeft.y, width, height);
3219+
}
3220+
31583221
long messageProc (long hwnd, long msg, long wParam, long lParam) {
31593222
switch ((int)msg) {
31603223
case SWT_RUNASYNC: {
@@ -4380,7 +4443,8 @@ public void sendPostExternalEventDispatchEvent () {
43804443
*/
43814444
public void setCursorLocation (int x, int y) {
43824445
checkDevice ();
4383-
setCursorLocationInPixels (DPIUtil.autoScaleUp (x), DPIUtil.autoScaleUp (y));
4446+
Point cursorLocationInPixels = translateLocationInPixelsInDisplayCoordinateSystem(x, y);
4447+
setCursorLocationInPixels (cursorLocationInPixels.x, cursorLocationInPixels.y);
43844448
}
43854449

43864450
void setCursorLocationInPixels (int x, int y) {
@@ -5310,4 +5374,63 @@ private boolean setDPIAwareness(int desiredDpiAwareness) {
53105374
return true;
53115375
}
53125376

5377+
private Monitor getContainingMonitor(int x, int y) {
5378+
Monitor[] monitors = getMonitors();
5379+
for (Monitor currentMonitor : monitors) {
5380+
Rectangle clientArea = currentMonitor.getClientArea();
5381+
if (clientArea.contains(x, y)) {
5382+
return currentMonitor;
5383+
}
5384+
}
5385+
return getPrimaryMonitor();
5386+
}
5387+
5388+
private Monitor getContainingMonitor(int x, int y, int width, int height) {
5389+
Rectangle rectangle = new Rectangle(x, y, width, height);
5390+
Monitor[] monitors = getMonitors();
5391+
Monitor selectedMonitor = getPrimaryMonitor();
5392+
int highestArea = 0;
5393+
for (Monitor currentMonitor : monitors) {
5394+
Rectangle clientArea = currentMonitor.getClientArea();
5395+
Rectangle intersection = clientArea.intersection(rectangle);
5396+
int area = intersection.width * intersection.height;
5397+
if (area > highestArea) {
5398+
selectedMonitor = currentMonitor;
5399+
highestArea = area;
5400+
}
5401+
}
5402+
return selectedMonitor;
5403+
}
5404+
5405+
private Monitor getContainingMonitorInPixelsCoordinate(int xInPixels, int yInPixels) {
5406+
Monitor[] monitors = getMonitors();
5407+
for (Monitor current : monitors) {
5408+
Rectangle clientArea = getMonitorClientAreaInPixels(current);
5409+
if (clientArea.contains(xInPixels, yInPixels)) {
5410+
return current;
5411+
}
5412+
}
5413+
return getPrimaryMonitor();
5414+
}
5415+
5416+
private Rectangle getMonitorClientAreaInPixels(Monitor monitor) {
5417+
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
5418+
int widthInPixels = DPIUtil.scaleUp(monitor.clientWidth, zoom);
5419+
int heightInPixels = DPIUtil.scaleUp(monitor.clientHeight, zoom);
5420+
return new Rectangle(monitor.clientX, monitor.clientY, widthInPixels, heightInPixels);
5421+
}
5422+
5423+
private Point getPixelsFromPoint(Monitor monitor, int x, int y) {
5424+
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
5425+
int mappedX = DPIUtil.scaleUp(x - monitor.clientX, zoom) + monitor.clientX;
5426+
int mappedY = DPIUtil.scaleUp(y - monitor.clientY, zoom) + monitor.clientY;
5427+
return new Point(mappedX, mappedY);
5428+
}
5429+
5430+
private Point getPointFromPixels(Monitor monitor, int x, int y) {
5431+
int zoom = DPIUtil.getZoomForAutoscaleProperty(monitor.zoom);
5432+
int mappedX = DPIUtil.scaleDown(x - monitor.clientX, zoom) + monitor.clientX;
5433+
int mappedY = DPIUtil.scaleDown(y - monitor.clientY, zoom) + monitor.clientY;
5434+
return new Point(mappedX, mappedY);
5435+
}
53135436
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,42 @@ public void setAlpha (int alpha) {
15661566
}
15671567
}
15681568

1569+
@Override
1570+
public Rectangle getBounds() {
1571+
Rectangle boundsInPixels = getBoundsInPixels();
1572+
return display.translateRectangleInPointsInDisplayCoordinateSystemByContainment(boundsInPixels.x, boundsInPixels.y, boundsInPixels.width, boundsInPixels.height);
1573+
}
1574+
1575+
@Override
1576+
public Point getLocation() {
1577+
Point locationInPixels = getLocationInPixels();
1578+
return display.translateLocationInPointInDisplayCoordinateSystem(locationInPixels.x, locationInPixels.y);
1579+
}
1580+
1581+
@Override
1582+
public void setLocation(Point location) {
1583+
if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
1584+
setLocation(location.x, location.y);
1585+
}
1586+
1587+
@Override
1588+
public void setLocation(int x, int y) {
1589+
Point location = display.translateLocationInPixelsInDisplayCoordinateSystem(x, y);
1590+
setLocationInPixels(location.x, location.y);
1591+
}
1592+
1593+
@Override
1594+
public void setBounds(Rectangle rect) {
1595+
if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
1596+
setBounds(rect.x, rect.y, rect.width, rect.height);
1597+
}
1598+
1599+
@Override
1600+
public void setBounds(int x, int y, int width, int height) {
1601+
Rectangle boundsInPixels = display.translateRectangleInPixelsInDisplayCoordinateSystemByContainment(x, y, width, height);
1602+
setBoundsInPixels(boundsInPixels.x, boundsInPixels.y, boundsInPixels.width, boundsInPixels.height);
1603+
}
1604+
15691605
@Override
15701606
void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) {
15711607
if (fullScreen) setFullScreen (false);

0 commit comments

Comments
 (0)