From fd93049d0106a7f8228adf9b2877c907735908df Mon Sep 17 00:00:00 2001 From: Amartya Parijat Date: Mon, 16 Jun 2025 15:07:14 +0200 Subject: [PATCH] Reorganized monitor-bound utils in Tree #62 This commit contributes to moving Tree:getContainingMonitorBoundsInPixels and Tree:fitRectangleBoundsIntoMonitor to CoordinateSystemMapper and Display, respectively for better clarity and encapsulation. contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/62 and https://github.com/eclipse-platform/eclipse.platform.swt/issues/128 --- .../swt/widgets/CoordinateSystemMapper.java | 2 + .../org/eclipse/swt/widgets/Display.java | 22 +++++++++ .../MultiZoomCoordinateSystemMapper.java | 7 +++ .../SingleZoomCoordinateSystemMapper.java | 13 +++++ .../win32/org/eclipse/swt/widgets/Tree.java | 48 ++----------------- 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoordinateSystemMapper.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoordinateSystemMapper.java index 28527ed39e4..652bcba719c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoordinateSystemMapper.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoordinateSystemMapper.java @@ -35,6 +35,8 @@ interface CoordinateSystemMapper { Rectangle translateToDisplayCoordinates(Rectangle rect, int zoom); + Rectangle getContainingMonitorBoundsInPixels(Point point); + void setCursorLocation(int x, int y); Point getCursorLocation(); 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 766f9176730..511fcdfec44 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 @@ -1724,6 +1724,28 @@ public Point getCursorLocation () { return coordinateSystemMapper.getCursorLocation(); } +Rectangle fitRectangleBoundsIntoMonitorWithCursor(RECT rect) { + Rectangle monitorBounds = coordinateSystemMapper.getContainingMonitorBoundsInPixels(getCursorLocation()); + if (monitorBounds == null) { + return null; + } + int rectWidth = rect.right - rect.left; + int rectHeight = rect.bottom - rect.top; + if (rect.left < monitorBounds.x) { + rect.left = monitorBounds.x; + } + int monitorBoundsRightEnd = monitorBounds.x + monitorBounds.width; + if (rect.right > monitorBoundsRightEnd) { + if (rectWidth <= monitorBounds.width) { + rect.left = monitorBoundsRightEnd - rectWidth; + } else { + rect.left = monitorBounds.x; + } + rectWidth = monitorBoundsRightEnd - rect.left; + } + return new Rectangle(rect.left, rect.top, rectWidth, rectHeight); +} + Point getCursorLocationInPixels () { POINT pt = new POINT (); OS.GetCursorPos (pt); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MultiZoomCoordinateSystemMapper.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MultiZoomCoordinateSystemMapper.java index 0edae112b5f..886a47701e3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MultiZoomCoordinateSystemMapper.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/MultiZoomCoordinateSystemMapper.java @@ -271,4 +271,11 @@ private int getApplicableMonitorZoom(Monitor monitor) { return DPIUtil.getZoomForAutoscaleProperty(monitor.zoom); } + @Override + public Rectangle getContainingMonitorBoundsInPixels(Point point) { + Monitor monitor = point instanceof MonitorAwarePoint monitorAwarePoint ? monitorAwarePoint.getMonitor() + : getContainingMonitorForPoints(point.x, point.y); + return getMonitorClientAreaInPixels(monitor); + } + } \ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/SingleZoomCoordinateSystemMapper.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/SingleZoomCoordinateSystemMapper.java index 84ae1fb64f7..e9253592996 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/SingleZoomCoordinateSystemMapper.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/SingleZoomCoordinateSystemMapper.java @@ -105,4 +105,17 @@ public Point getCursorLocation() { public void setCursorLocation(int x, int y) { display.setCursorLocationInPixels(DPIUtil.autoScaleUp(x), DPIUtil.autoScaleUp(y)); } + + @Override + public Rectangle getContainingMonitorBoundsInPixels(Point point) { + int zoom = DPIUtil.getDeviceZoom(); + point = DPIUtil.scaleUp(point, zoom); + for (Monitor monitor : display.getMonitors()) { + Rectangle monitorBounds = DPIUtil.scaleUp(monitor.getBounds(), zoom); + if (monitorBounds.contains(point)) { + return monitorBounds; + } + } + return null; + } } \ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java index ef7f6ca9d8d..3473b333564 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java @@ -8175,12 +8175,9 @@ private LRESULT positionTooltip(NMHDR hdr, long wParam, long lParam, boolean man // triggers additional display messages to SWT, creating an infinite loop // of positioning and re-scaling events. // Refer: https://github.com/eclipse-platform/eclipse.platform.swt/issues/557 - Point cursorLocation = display.getCursorLocation(); - Rectangle monitorBounds = cursorLocation instanceof MonitorAwarePoint monitorAwarePoint - ? getContainingMonitorBoundsInMultiZoomCoordinateSystem(monitorAwarePoint) - : getContainingMonitorBoundsInSingleZoomCoordinateSystem(cursorLocation); - if (monitorBounds != null) { - Rectangle adjustedTooltipBounds = fitTooltipBoundsIntoMonitor(toolRect, monitorBounds); + + Rectangle adjustedTooltipBounds = getDisplay().fitRectangleBoundsIntoMonitorWithCursor(toolRect); + if(adjustedTooltipBounds != null) { OS.SetWindowPos (hdr.hwndFrom, 0, adjustedTooltipBounds.x, adjustedTooltipBounds.y, adjustedTooltipBounds.width, adjustedTooltipBounds.height, flags); result = LRESULT.ONE; } @@ -8196,45 +8193,6 @@ private LRESULT positionTooltip(NMHDR hdr, long wParam, long lParam, boolean man return result; } -/** - * Adjust the tool tip to fit in a single monitor either by shifting its position or by adjusting it's width. - */ -private Rectangle fitTooltipBoundsIntoMonitor(RECT tooltipBounds, Rectangle monitorBounds) { - int tooltipWidth = tooltipBounds.right - tooltipBounds.left; - int tooltipHeight = tooltipBounds.bottom - tooltipBounds.top; - if (tooltipBounds.left < monitorBounds.x) { - tooltipBounds.left = monitorBounds.x; - } - int monitorBoundsRightEnd = monitorBounds.x + monitorBounds.width; - if (tooltipBounds.right > monitorBoundsRightEnd) { - if (tooltipWidth <= monitorBounds.width) { - tooltipBounds.left = monitorBoundsRightEnd - tooltipWidth; - } else { - tooltipBounds.left = monitorBounds.x; - } - tooltipWidth = monitorBoundsRightEnd - tooltipBounds.left; - } - return new Rectangle(tooltipBounds.left, tooltipBounds.top, tooltipWidth, tooltipHeight); -} - -private Rectangle getContainingMonitorBoundsInSingleZoomCoordinateSystem(Point point) { - int zoom = getZoom(); - point = DPIUtil.scaleUp(point, zoom); - for (Monitor monitor : display.getMonitors()) { - Rectangle monitorBounds = DPIUtil.scaleUp(monitor.getBounds(), zoom); - if (monitorBounds.contains(point)) { - return monitorBounds; - } - } - return null; -} - -private Rectangle getContainingMonitorBoundsInMultiZoomCoordinateSystem(MonitorAwarePoint point) { - Monitor monitor = point.getMonitor(); - return new Rectangle(monitor.x, monitor.y, DPIUtil.scaleUp(monitor.width, monitor.zoom), - DPIUtil.scaleUp(monitor.height, monitor.zoom)); -} - LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW nmcd, long lParam) { switch (nmcd.dwDrawStage) { case OS.CDDS_PREPAINT: {