Skip to content

Commit c422be8

Browse files
HeikoKlarefedejeanne
authored andcommitted
[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 2d43ce9 commit c422be8

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";
@@ -5006,20 +5002,6 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
50065002
return null;
50075003
}
50085004

5009-
private void handleMonitorSpecificDpiChange(int newNativeZoom, Rectangle newBoundsInPixels) {
5010-
DPIUtil.setDeviceZoom (newNativeZoom);
5011-
// Do not process DPI change for child shells asynchronous to avoid relayouting when
5012-
// repositioning the child shell to a different monitor upon opening
5013-
boolean processDpiChangeAsynchronous = getShell().getParent() == null;
5014-
Event zoomChangedEvent = createZoomChangedEvent(newNativeZoom, processDpiChangeAsynchronous);
5015-
if (currentDpiChangeEvent != null) {
5016-
currentDpiChangeEvent.doit = false;
5017-
}
5018-
currentDpiChangeEvent = zoomChangedEvent;
5019-
notifyListeners(SWT.ZoomChanged, zoomChangedEvent);
5020-
this.setBoundsInPixels(newBoundsInPixels.x, newBoundsInPixels.y, newBoundsInPixels.width, newBoundsInPixels.height);
5021-
}
5022-
50235005
Event createZoomChangedEvent(int zoom, boolean asyncExec) {
50245006
Event event = new Event();
50255007
event.type = SWT.ZoomChanged;
@@ -5032,38 +5014,12 @@ Event createZoomChangedEvent(int zoom, boolean asyncExec) {
50325014
return event;
50335015
}
50345016

5035-
LRESULT WM_DPICHANGED (long wParam, long lParam) {
5036-
// Map DPI to Zoom and compare
5037-
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
5038-
if (getDisplay().isRescalingAtRuntime()) {
5039-
Device.win32_destroyUnusedHandles(getDisplay());
5040-
RECT rect = new RECT ();
5041-
COM.MoveMemory(rect, lParam, RECT.sizeof);
5042-
handleMonitorSpecificDpiChange(newNativeZoom, new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom-rect.top));
5043-
return LRESULT.ZERO;
5044-
} else {
5045-
int newZoom = DPIUtil.getZoomForAutoscaleProperty (newNativeZoom);
5046-
int oldZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom);
5047-
if (newZoom != oldZoom) {
5048-
// Throw the DPI change event if zoom value changes
5049-
Event event = new Event();
5050-
event.type = SWT.ZoomChanged;
5051-
event.widget = this;
5052-
event.detail = DPIUtil.getZoomForAutoscaleProperty(newNativeZoom);
5053-
event.doit = true;
5054-
notifyListeners(SWT.ZoomChanged, event);
5055-
return LRESULT.ZERO;
5056-
}
5057-
}
5058-
return LRESULT.ONE;
5017+
LRESULT WM_DPICHANGED(long wParam, long lParam) {
5018+
return null;
50595019
}
50605020

5061-
LRESULT WM_DISPLAYCHANGE (long wParam, long lParam) {
5062-
if (getDisplay().isRescalingAtRuntime()) {
5063-
Device.win32_destroyUnusedHandles(getDisplay());
5064-
return LRESULT.ZERO;
5065-
}
5066-
return LRESULT.ONE;
5021+
LRESULT WM_DISPLAYCHANGE(long wParam, long lParam) {
5022+
return null;
50675023
}
50685024

50695025
LRESULT WM_DRAWITEM (long wParam, long lParam) {
@@ -5972,7 +5928,6 @@ private boolean decrement() {
59725928
}
59735929

59745930
void sendZoomChangedEvent(Event event, Shell shell) {
5975-
this.currentDpiChangeEvent = event;
59765931
if (event.data instanceof DPIChangeExecution dpiExecData) {
59775932
dpiExecData.increment();
59785933
dpiExecData.process(this, () -> {
@@ -5985,9 +5940,6 @@ void sendZoomChangedEvent(Event event, Shell shell) {
59855940
return;
59865941
}
59875942
if (dpiExecData.decrement()) {
5988-
if (event == currentDpiChangeEvent) {
5989-
currentDpiChangeEvent = null;
5990-
}
59915943
if (event.doit) {
59925944
shell.WM_SIZE(0, 0);
59935945
}

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>.
@@ -2442,6 +2447,57 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
24422447
return result;
24432448
}
24442449

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

0 commit comments

Comments
 (0)