Skip to content

Commit 0dc4317

Browse files
committed
[win32] fallback for missing DPI change event
This commit adds a fallback mechanism if the OS doesn't send a DPI change as expected. When the process is started with System DPI awareness and only the thread is PerMonitorV2 aware, there are some scenarios, when the OS does not send a DPI change event when a child Shell is positioned and opened on another monitor as its parent Shell. To work around that limitation a check is added to Shell::WM_WINDOWPOSCHANGED to trigger a dpi change event if an unexpected DPI value is detected.
1 parent 9f60279 commit 0dc4317

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4928,21 +4928,24 @@ LRESULT WM_DESTROY (long wParam, long lParam) {
49284928
return null;
49294929
}
49304930

4931+
void handleMonitorSpecificDpiChange(int newNativeZoom, Rectangle newBoundsInPixels) {
4932+
DPIUtil.setDeviceZoom (newNativeZoom);
4933+
4934+
float scalingFactor = 1f * DPIUtil.getZoomForAutoscaleProperty(newNativeZoom) / DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
4935+
DPIZoomChangeRegistry.applyChange(this, newNativeZoom, scalingFactor);
4936+
4937+
this.setBoundsInPixels(newBoundsInPixels.y, newBoundsInPixels.y, newBoundsInPixels.width, newBoundsInPixels.height);
4938+
}
4939+
49314940
LRESULT WM_DPICHANGED (long wParam, long lParam) {
49324941
// Map DPI to Zoom and compare
49334942
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
49344943
if (getDisplay().isRescalingAtRuntime()) {
49354944
Device.win32_destroyUnusedHandles(getDisplay());
4936-
int oldNativeZoom = nativeZoom;
4937-
if (newNativeZoom != oldNativeZoom) {
4938-
DPIUtil.setDeviceZoom (newNativeZoom);
4939-
4940-
float scalingFactor = 1f * DPIUtil.getZoomForAutoscaleProperty(newNativeZoom) / DPIUtil.getZoomForAutoscaleProperty(oldNativeZoom);
4941-
DPIZoomChangeRegistry.applyChange(this, newNativeZoom, scalingFactor);
4942-
4945+
if (newNativeZoom != nativeZoom) {
49434946
RECT rect = new RECT ();
49444947
COM.MoveMemory(rect, lParam, RECT.sizeof);
4945-
this.setBoundsInPixels(rect.left, rect.top, rect.right - rect.left, rect.bottom-rect.top);
4948+
handleMonitorSpecificDpiChange(newNativeZoom, new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom-rect.top));
49464949
return LRESULT.ZERO;
49474950
}
49484951
} else {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,24 @@ LRESULT WM_WINDOWPOSCHANGING (long wParam, long lParam) {
26852685
return result;
26862686
}
26872687

2688+
@Override
2689+
LRESULT WM_WINDOWPOSCHANGED (long wParam, long lParam) {
2690+
LRESULT result = super.WM_WINDOWPOSCHANGED(wParam, lParam);
2691+
// When the process is started with System DPI awareness and
2692+
// only the thread is PerMonitorV2 aware, there are some scenarios, when the
2693+
// OS does not send a DPI change event when a child Shell is positioned and
2694+
// opened on another monitor as its parent Shell. To work around that limitation
2695+
// this check is added to trigger a dpi change event if an unexpected DPI value is
2696+
// detected.
2697+
if (display.isRescalingAtRuntime()) {
2698+
int dpiForWindow = DPIUtil.mapDPIToZoom(OS.GetDpiForWindow(getShell().handle));
2699+
if (dpiForWindow != nativeZoom) {
2700+
handleMonitorSpecificDpiChange(dpiForWindow, DPIUtil.scaleUp(getBounds(), dpiForWindow));
2701+
}
2702+
}
2703+
return result;
2704+
}
2705+
26882706
private static void handleDPIChange(Widget widget, int newZoom, float scalingFactor) {
26892707
if (!(widget instanceof Shell shell)) {
26902708
return;

0 commit comments

Comments
 (0)