1616
1717
1818import java .util .*;
19+ import java .util .concurrent .atomic .*;
1920import java .util .stream .*;
2021
2122import org .eclipse .swt .*;
@@ -4760,7 +4761,7 @@ public boolean setParent (Composite parent) {
47604761 if (parent .nativeZoom != nativeZoom ) {
47614762 int newZoom = parent .nativeZoom ;
47624763 Event zoomChangedEvent = createZoomChangedEvent (newZoom );
4763- notifyListeners ( SWT . ZoomChanged , zoomChangedEvent );
4764+ sendZoomChangedEvent ( zoomChangedEvent , getShell () );
47644765 }
47654766 int flags = OS .SWP_NOSIZE | OS .SWP_NOMOVE | OS .SWP_NOACTIVATE ;
47664767 OS .SetWindowPos (topHandle , OS .HWND_BOTTOM , 0 , 0 , 0 , 0 , flags );
@@ -4953,9 +4954,14 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
49534954 return null ;
49544955}
49554956
4956- void handleMonitorSpecificDpiChange (int newNativeZoom , Rectangle newBoundsInPixels ) {
4957+ private void handleMonitorSpecificDpiChange (int newNativeZoom , Rectangle newBoundsInPixels ) {
49574958 DPIUtil .setDeviceZoom (newNativeZoom );
49584959 Event zoomChangedEvent = createZoomChangedEvent (newNativeZoom );
4960+ Shell shell = getShell ();
4961+ if (shell .currentDpiChangeEvent != null ) {
4962+ shell .currentDpiChangeEvent .doit = false ;
4963+ }
4964+ shell .currentDpiChangeEvent = zoomChangedEvent ;
49594965 notifyListeners (SWT .ZoomChanged , zoomChangedEvent );
49604966 this .setBoundsInPixels (newBoundsInPixels .x , newBoundsInPixels .y , newBoundsInPixels .width , newBoundsInPixels .height );
49614967}
@@ -4966,6 +4972,7 @@ private Event createZoomChangedEvent(int zoom) {
49664972 event .widget = this ;
49674973 event .detail = zoom ;
49684974 event .doit = true ;
4975+ event .data = new AtomicInteger (0 );
49694976 return event ;
49704977}
49714978
@@ -4974,12 +4981,10 @@ LRESULT WM_DPICHANGED (long wParam, long lParam) {
49744981 int newNativeZoom = DPIUtil .mapDPIToZoom (OS .HIWORD (wParam ));
49754982 if (getDisplay ().isRescalingAtRuntime ()) {
49764983 Device .win32_destroyUnusedHandles (getDisplay ());
4977- if (newNativeZoom != nativeZoom ) {
4978- RECT rect = new RECT ();
4979- COM .MoveMemory (rect , lParam , RECT .sizeof );
4980- handleMonitorSpecificDpiChange (newNativeZoom , new Rectangle (rect .left , rect .top , rect .right - rect .left , rect .bottom -rect .top ));
4981- return LRESULT .ZERO ;
4982- }
4984+ RECT rect = new RECT ();
4985+ COM .MoveMemory (rect , lParam , RECT .sizeof );
4986+ handleMonitorSpecificDpiChange (newNativeZoom , new Rectangle (rect .left , rect .top , rect .right - rect .left , rect .bottom -rect .top ));
4987+ return LRESULT .ZERO ;
49834988 } else {
49844989 int newZoom = DPIUtil .getZoomForAutoscaleProperty (newNativeZoom );
49854990 int oldZoom = DPIUtil .getZoomForAutoscaleProperty (nativeZoom );
@@ -5879,6 +5884,29 @@ LRESULT wmScrollChild (long wParam, long lParam) {
58795884 return null ;
58805885}
58815886
5887+ void sendZoomChangedEvent (Event event , Shell shell ) {
5888+ AtomicInteger handleDPIChangedScheduledTasksCount = (AtomicInteger ) event .data ;
5889+ handleDPIChangedScheduledTasksCount .incrementAndGet ();
5890+ getDisplay ().asyncExec (() -> {
5891+ try {
5892+ if (!this .isDisposed () && event .doit ) {
5893+ notifyListeners (SWT .ZoomChanged , event );
5894+ }
5895+ } finally {
5896+ if (shell .isDisposed ()) {
5897+ return ;
5898+ }
5899+ if (handleDPIChangedScheduledTasksCount .decrementAndGet () <= 0 ) {
5900+ if (event == shell .currentDpiChangeEvent ) {
5901+ shell .currentDpiChangeEvent = null ;
5902+ }
5903+ if (event .doit ) {
5904+ shell .WM_SIZE (0 , 0 );
5905+ }
5906+ }
5907+ }
5908+ });
5909+ }
58825910
58835911@ Override
58845912void handleDPIChange (Event event , float scalingFactor ) {
0 commit comments