Skip to content

Commit bf09d84

Browse files
committed
[Win32] Move DPI change handling from Control to Shell
Currently, DPI change handling is implemented in Control. However, according OS events are only created and reasonable at Shell level. This change thus moves the according implementations to the Shell class. It also limits the last queued DPI event storage for cancellation on subsequent events to the Shell class.
1 parent ac18a18 commit bf09d84

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

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

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.eclipse.swt.graphics.*;
2727
import org.eclipse.swt.internal.*;
2828
import org.eclipse.swt.internal.gdip.*;
29-
import org.eclipse.swt.internal.ole.win32.*;
3029
import org.eclipse.swt.internal.win32.*;
3130
import org.eclipse.swt.ole.win32.*;
3231

@@ -80,9 +79,6 @@ public abstract class Control extends Widget implements Drawable {
8079
int drawCount, foreground, background, backgroundAlpha = 255;
8180
boolean autoScaleDisabled = false;
8281

83-
/** Cache for currently processed DPI change event to be able to cancel it if a new one is triggered */
84-
Event currentDpiChangeEvent;
85-
8682
private static final String DATA_SHELL_ZOOM = "SHELL_ZOOM";
8783

8884
private static final String DATA_AUTOSCALE_DISABLED = "AUTOSCALE_DISABLED";
@@ -5014,20 +5010,6 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
50145010
return null;
50155011
}
50165012

5017-
private void handleMonitorSpecificDpiChange(int newNativeZoom, Rectangle newBoundsInPixels) {
5018-
DPIUtil.setDeviceZoom (newNativeZoom);
5019-
// Do not process DPI change for child shells asynchronous to avoid relayouting when
5020-
// repositioning the child shell to a different monitor upon opening
5021-
boolean processDpiChangeAsynchronous = getShell().getParent() == null;
5022-
Event zoomChangedEvent = createZoomChangedEvent(newNativeZoom, processDpiChangeAsynchronous);
5023-
if (currentDpiChangeEvent != null) {
5024-
currentDpiChangeEvent.doit = false;
5025-
}
5026-
currentDpiChangeEvent = zoomChangedEvent;
5027-
notifyListeners(SWT.ZoomChanged, zoomChangedEvent);
5028-
this.setBoundsInPixels(newBoundsInPixels.x, newBoundsInPixels.y, newBoundsInPixels.width, newBoundsInPixels.height);
5029-
}
5030-
50315013
Event createZoomChangedEvent(int zoom, boolean asyncExec) {
50325014
Event event = new Event();
50335015
event.type = SWT.ZoomChanged;
@@ -5040,38 +5022,12 @@ Event createZoomChangedEvent(int zoom, boolean asyncExec) {
50405022
return event;
50415023
}
50425024

5043-
LRESULT WM_DPICHANGED (long wParam, long lParam) {
5044-
// Map DPI to Zoom and compare
5045-
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
5046-
if (getDisplay().isRescalingAtRuntime()) {
5047-
Device.win32_destroyUnusedHandles(getDisplay());
5048-
RECT rect = new RECT ();
5049-
COM.MoveMemory(rect, lParam, RECT.sizeof);
5050-
handleMonitorSpecificDpiChange(newNativeZoom, new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom-rect.top));
5051-
return LRESULT.ZERO;
5052-
} else {
5053-
int newZoom = DPIUtil.getZoomForAutoscaleProperty (newNativeZoom);
5054-
int oldZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom);
5055-
if (newZoom != oldZoom) {
5056-
// Throw the DPI change event if zoom value changes
5057-
Event event = new Event();
5058-
event.type = SWT.ZoomChanged;
5059-
event.widget = this;
5060-
event.detail = DPIUtil.getZoomForAutoscaleProperty(newNativeZoom);
5061-
event.doit = true;
5062-
notifyListeners(SWT.ZoomChanged, event);
5063-
return LRESULT.ZERO;
5064-
}
5065-
}
5066-
return LRESULT.ONE;
5025+
LRESULT WM_DPICHANGED(long wParam, long lParam) {
5026+
return null;
50675027
}
50685028

5069-
LRESULT WM_DISPLAYCHANGE (long wParam, long lParam) {
5070-
if (getDisplay().isRescalingAtRuntime()) {
5071-
Device.win32_destroyUnusedHandles(getDisplay());
5072-
return LRESULT.ZERO;
5073-
}
5074-
return LRESULT.ONE;
5029+
LRESULT WM_DISPLAYCHANGE(long wParam, long lParam) {
5030+
return null;
50755031
}
50765032

50775033
LRESULT WM_DRAWITEM (long wParam, long lParam) {
@@ -5980,7 +5936,6 @@ private boolean decrement() {
59805936
}
59815937

59825938
void sendZoomChangedEvent(Event event, Shell shell) {
5983-
this.currentDpiChangeEvent = event;
59845939
if (event.data instanceof DPIChangeExecution dpiExecData) {
59855940
dpiExecData.increment();
59865941
dpiExecData.process(this, () -> {
@@ -5993,9 +5948,6 @@ void sendZoomChangedEvent(Event event, Shell shell) {
59935948
return;
59945949
}
59955950
if (dpiExecData.decrement()) {
5996-
if (event == currentDpiChangeEvent) {
5997-
currentDpiChangeEvent = null;
5998-
}
59995951
if (event.doit) {
60005952
shell.WM_SIZE(0, 0);
60015953
}

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.eclipse.swt.events.*;
1919
import org.eclipse.swt.graphics.*;
2020
import org.eclipse.swt.internal.*;
21+
import org.eclipse.swt.internal.ole.win32.*;
2122
import org.eclipse.swt.internal.win32.*;
2223
import org.eclipse.swt.internal.win32.version.*;
2324

@@ -150,6 +151,10 @@ public class Shell extends Decorations {
150151
DialogProc = lpWndClass.lpfnWndProc;
151152
}
152153

154+
/** Cache for currently processed DPI change event to be able to cancel it if a new one is triggered */
155+
Event lastDpiChangeEvent;
156+
157+
153158
/**
154159
* Constructs a new instance of this class. This is equivalent
155160
* to calling <code>Shell((Display) null)</code>.
@@ -2430,6 +2435,57 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
24302435
return result;
24312436
}
24322437

2438+
@Override
2439+
LRESULT WM_DISPLAYCHANGE (long wParam, long lParam) {
2440+
if (getDisplay().isRescalingAtRuntime()) {
2441+
Device.win32_destroyUnusedHandles(getDisplay());
2442+
return LRESULT.ZERO;
2443+
}
2444+
return LRESULT.ONE;
2445+
}
2446+
2447+
@Override
2448+
LRESULT WM_DPICHANGED (long wParam, long lParam) {
2449+
// Map DPI to Zoom and compare
2450+
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
2451+
if (getDisplay().isRescalingAtRuntime()) {
2452+
Device.win32_destroyUnusedHandles(getDisplay());
2453+
RECT rect = new RECT ();
2454+
COM.MoveMemory(rect, lParam, RECT.sizeof);
2455+
Rectangle newBoundsInPixels = new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom-rect.top);
2456+
handleMonitorSpecificDpiChange(newNativeZoom, newBoundsInPixels);
2457+
return LRESULT.ZERO;
2458+
} else {
2459+
int newZoom = DPIUtil.getZoomForAutoscaleProperty (newNativeZoom);
2460+
int oldZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom);
2461+
if (newZoom != oldZoom) {
2462+
// Throw the DPI change event if zoom value changes
2463+
Event event = new Event();
2464+
event.type = SWT.ZoomChanged;
2465+
event.widget = this;
2466+
event.detail = DPIUtil.getZoomForAutoscaleProperty(newNativeZoom);
2467+
event.doit = true;
2468+
notifyListeners(SWT.ZoomChanged, event);
2469+
return LRESULT.ZERO;
2470+
}
2471+
}
2472+
return LRESULT.ONE;
2473+
}
2474+
2475+
private void handleMonitorSpecificDpiChange(int newNativeZoom, Rectangle newBoundsInPixels) {
2476+
DPIUtil.setDeviceZoom (newNativeZoom);
2477+
// Do not process DPI change for child shells asynchronous to avoid relayouting when
2478+
// repositioning the child shell to a different monitor upon opening
2479+
boolean processDpiChangeAsynchronous = getParent() == null;
2480+
Event zoomChangedEvent = createZoomChangedEvent(newNativeZoom, processDpiChangeAsynchronous);
2481+
if (lastDpiChangeEvent != null) {
2482+
lastDpiChangeEvent.doit = false;
2483+
}
2484+
lastDpiChangeEvent = zoomChangedEvent;
2485+
notifyListeners(SWT.ZoomChanged, zoomChangedEvent);
2486+
this.setBoundsInPixels(newBoundsInPixels.x, newBoundsInPixels.y, newBoundsInPixels.width, newBoundsInPixels.height);
2487+
}
2488+
24332489
@Override
24342490
LRESULT WM_ENTERIDLE (long wParam, long lParam) {
24352491
LRESULT result = super.WM_ENTERIDLE (wParam, lParam);

0 commit comments

Comments
 (0)