@@ -2811,7 +2811,7 @@ boolean findCell (int x, int y, TreeItem [] item, int [] index, RECT [] cellRect
28112811 itemRect [0 ].top = boundsInPixels .y ;
28122812 itemRect [0 ].bottom = boundsInPixels .y + boundsInPixels .height ;
28132813 } else {
2814- itemRect [0 ] = item [0 ].getBounds (order [index [0 ]], true , false , false , false , false , hDC );
2814+ itemRect [0 ] = item [0 ].getBounds (order [index [0 ]], true , true , false , false , false , hDC );
28152815 }
28162816 if (itemRect [0 ].right > cellRect [0 ].right ) found = true ;
28172817 quit = true ;
@@ -7397,6 +7397,8 @@ LRESULT wmNotify (NMHDR hdr, long wParam, long lParam) {
73977397 if (hdr .hwndFrom == itemToolTipHandle && itemToolTipHandle != 0 ) {
73987398 LRESULT result = wmNotifyToolTip (hdr , wParam , lParam );
73997399 if (result != null ) return result ;
7400+ } else if (hdr .code == OS .TTN_SHOW ) {
7401+ return positionTooltip (hdr , wParam , lParam , false );
74007402 }
74017403 if (hdr .hwndFrom == hwndHeader && hwndHeader != 0 ) {
74027404 LRESULT result = wmNotifyHeader (hdr , wParam , lParam );
@@ -8145,44 +8147,55 @@ LRESULT wmNotifyToolTip (NMHDR hdr, long wParam, long lParam) {
81458147 return wmNotifyToolTip (nmcd , lParam );
81468148 }
81478149 case OS .TTN_SHOW : {
8148- LRESULT result = super .wmNotify (hdr , wParam , lParam );
8149- if (result != null ) return result ;
8150- int pos = OS .GetMessagePos ();
8151- POINT pt = new POINT ();
8152- OS .POINTSTOPOINT (pt , pos );
8153- OS .ScreenToClient (handle , pt );
8154- int [] index = new int [1 ];
8155- TreeItem [] item = new TreeItem [1 ];
8156- RECT [] cellRect = new RECT [1 ], itemRect = new RECT [1 ];
8157- if (findCell (pt .x , pt .y , item , index , cellRect , itemRect )) {
8158- RECT toolRect = toolTipRect (itemRect [0 ]);
8159- OS .MapWindowPoints (handle , 0 , toolRect , 2 );
8160- int flags = OS .SWP_NOACTIVATE | OS .SWP_NOZORDER | OS .SWP_NOSIZE ;
8161- if (isCustomToolTip ()) flags &= ~OS .SWP_NOSIZE ;
8162- // Retrieve the monitor containing the cursor position, as tool tip placement
8163- // must occur on the same monitor to avoid potential infinite loops. When a tool tip
8164- // appears on a different monitor than the cursor, the operating system may
8165- // attempt to re-scale it based on that monitor's settings. This re-scaling
8166- // triggers additional display messages to SWT, creating an infinite loop
8167- // of positioning and re-scaling events.
8168- // Refer: https://github.com/eclipse-platform/eclipse.platform.swt/issues/557
8169- Point cursorLocation = display .getCursorLocation ();
8170- Rectangle monitorBounds = cursorLocation instanceof MonitorAwarePoint monitorAwarePoint
8171- ? getContainingMonitorBoundsInMultiZoomCoordinateSystem (monitorAwarePoint )
8172- : getContainingMonitorBoundsInSingleZoomCoordinateSystem (cursorLocation );
8173- if (monitorBounds == null ) {
8174- return null ;
8175- }
8176- Rectangle adjustedTooltipBounds = fitTooltipBoundsIntoMonitor (toolRect , monitorBounds );
8177- OS .SetWindowPos (itemToolTipHandle , 0 , adjustedTooltipBounds .x , adjustedTooltipBounds .y , adjustedTooltipBounds .width , adjustedTooltipBounds .height , flags );
8178- return LRESULT .ONE ;
8179- }
8180- return result ;
8150+ return positionTooltip (hdr , wParam , lParam , true );
81818151 }
81828152 }
81838153 return null ;
81848154}
81858155
8156+ private LRESULT positionTooltip (NMHDR hdr , long wParam , long lParam , boolean managedTooltip ) {
8157+ LRESULT result = super .wmNotify (hdr , wParam , lParam );
8158+ if (result != null ) return result ;
8159+ int flags = OS .SWP_NOACTIVATE | OS .SWP_NOZORDER | OS .SWP_NOSIZE ;
8160+ if (isCustomToolTip () || !managedTooltip ) flags &= ~OS .SWP_NOSIZE ;
8161+ int pos = OS .GetMessagePos ();
8162+ POINT pt = new POINT ();
8163+ OS .POINTSTOPOINT (pt , pos );
8164+ OS .ScreenToClient (handle , pt );
8165+ int [] index = new int [1 ];
8166+ TreeItem [] item = new TreeItem [1 ];
8167+ RECT [] cellRect = new RECT [1 ], itemRect = new RECT [1 ];
8168+ if (findCell (pt .x , pt .y , item , index , cellRect , itemRect )) {
8169+ RECT toolRect = managedTooltip ? toolTipRect (itemRect [0 ]) : itemRect [0 ];
8170+ OS .MapWindowPoints (handle , 0 , toolRect , 2 );
8171+ // Retrieve the monitor containing the cursor position, as tool tip placement
8172+ // must occur on the same monitor to avoid potential infinite loops. When a tool tip
8173+ // appears on a different monitor than the cursor, the operating system may
8174+ // attempt to re-scale it based on that monitor's settings. This re-scaling
8175+ // triggers additional display messages to SWT, creating an infinite loop
8176+ // of positioning and re-scaling events.
8177+ // Refer: https://github.com/eclipse-platform/eclipse.platform.swt/issues/557
8178+ Point cursorLocation = display .getCursorLocation ();
8179+ Rectangle monitorBounds = cursorLocation instanceof MonitorAwarePoint monitorAwarePoint
8180+ ? getContainingMonitorBoundsInMultiZoomCoordinateSystem (monitorAwarePoint )
8181+ : getContainingMonitorBoundsInSingleZoomCoordinateSystem (cursorLocation );
8182+ if (monitorBounds != null ) {
8183+ Rectangle adjustedTooltipBounds = fitTooltipBoundsIntoMonitor (toolRect , monitorBounds );
8184+ OS .SetWindowPos (hdr .hwndFrom , 0 , adjustedTooltipBounds .x , adjustedTooltipBounds .y , adjustedTooltipBounds .width , adjustedTooltipBounds .height , flags );
8185+ result = LRESULT .ONE ;
8186+ }
8187+ } else if (!managedTooltip ) {
8188+ // If managedTooltip is false and the cursor is not over the valid part of the
8189+ // target cell, Windows may still try to display the default tooltip. Since we
8190+ // can't prevent it from showing at this point, we set its bounds to zero to
8191+ // effectively hide it.
8192+ flags |= OS .SWP_NOMOVE ;
8193+ OS .SetWindowPos (hdr .hwndFrom , 0 , 0 , 0 , 0 , 0 , flags );
8194+ result = LRESULT .ONE ;
8195+ }
8196+ return result ;
8197+ }
8198+
81868199/**
81878200 * Adjust the tool tip to fit in a single monitor either by shifting its position or by adjusting it's width.
81888201 */
0 commit comments