1616
1717
1818import java .util .*;
19+ import java .util .concurrent .atomic .*;
1920import java .util .stream .*;
2021
2122import org .eclipse .swt .*;
@@ -78,6 +79,9 @@ public abstract class Control extends Widget implements Drawable {
7879 Font font ;
7980 int drawCount , foreground , background , backgroundAlpha = 255 ;
8081
82+ /** Cache for currently processed DPI change event to be able to cancel it if a new one is triggered */
83+ private Event currentDpiChangeEvent ;
84+
8185/**
8286 * Prevents uninitialized instances from being created outside the package.
8387 */
@@ -4757,7 +4761,7 @@ public boolean setParent (Composite parent) {
47574761 if (parent .nativeZoom != nativeZoom ) {
47584762 int newZoom = parent .nativeZoom ;
47594763 Event zoomChangedEvent = createZoomChangedEvent (newZoom );
4760- notifyListeners ( SWT . ZoomChanged , zoomChangedEvent );
4764+ sendZoomChangedEvent ( zoomChangedEvent , getShell () );
47614765 }
47624766 int flags = OS .SWP_NOSIZE | OS .SWP_NOMOVE | OS .SWP_NOACTIVATE ;
47634767 OS .SetWindowPos (topHandle , OS .HWND_BOTTOM , 0 , 0 , 0 , 0 , flags );
@@ -4950,11 +4954,15 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
49504954 return null ;
49514955}
49524956
4953- void handleMonitorSpecificDpiChange (int newNativeZoom , Rectangle newBoundsInPixels ) {
4957+ private void handleMonitorSpecificDpiChange (int newNativeZoom , Rectangle newBoundsInPixels ) {
49544958 DPIUtil .setDeviceZoom (newNativeZoom );
49554959 Event zoomChangedEvent = createZoomChangedEvent (newNativeZoom );
4956- notifyListeners (SWT .ZoomChanged , zoomChangedEvent );
4960+ if (currentDpiChangeEvent != null ) {
4961+ currentDpiChangeEvent .doit = false ;
4962+ }
4963+ currentDpiChangeEvent = zoomChangedEvent ;
49574964 this .setBoundsInPixels (newBoundsInPixels .x , newBoundsInPixels .y , newBoundsInPixels .width , newBoundsInPixels .height );
4965+ sendZoomChangedEvent (zoomChangedEvent , getShell ());
49584966}
49594967
49604968private Event createZoomChangedEvent (int zoom ) {
@@ -4963,6 +4971,7 @@ private Event createZoomChangedEvent(int zoom) {
49634971 event .widget = this ;
49644972 event .detail = zoom ;
49654973 event .doit = true ;
4974+ event .data = new AtomicInteger (0 );
49664975 return event ;
49674976}
49684977
@@ -5876,6 +5885,27 @@ LRESULT wmScrollChild (long wParam, long lParam) {
58765885 return null ;
58775886}
58785887
5888+ void sendZoomChangedEvent (Event event , Shell shell ) {
5889+ AtomicInteger handleDPIChangedScheduledTasksCount = (AtomicInteger ) event .data ;
5890+ handleDPIChangedScheduledTasksCount .incrementAndGet ();
5891+ getDisplay ().asyncExec (() -> {
5892+ try {
5893+ if (!this .isDisposed () && event .doit ) {
5894+ notifyListeners (SWT .ZoomChanged , event );
5895+ }
5896+ } finally {
5897+ if (shell .isDisposed ()) {
5898+ return ;
5899+ }
5900+ if (handleDPIChangedScheduledTasksCount .decrementAndGet () <= 0 ) {
5901+ currentDpiChangeEvent = null ;
5902+ if (event .doit ) {
5903+ shell .WM_SIZE (0 , 0 );
5904+ }
5905+ }
5906+ }
5907+ });
5908+ }
58795909
58805910@ Override
58815911void handleDPIChange (Event event , float scalingFactor ) {
0 commit comments