Skip to content

Commit 24c8513

Browse files
committed
Only consider rescaling at runtime enabled when DPI awareness mode fits
Activating rescaling at runtime requires a proper DPI awareness mode to be set. Currently, if setting the DPI awareness mode fails, rescaling may still be activated if the user requested to. With this change, setting the rescaling mode of a Display ensures that the correct DPI awareness for the UI thread is set and, in case an error occurs, the rescaling mode is not changed. It also adapts some faulty constants and provides according test cases for setting the rescaling behavior.
1 parent 5a7f375 commit 24c8513

File tree

5 files changed

+84
-21
lines changed

5 files changed

+84
-21
lines changed

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,8 @@ public class OS extends C {
369369
public static final short DMDUP_SIMPLEX = 1;
370370
public static final short DMDUP_VERTICAL = 2;
371371
public static final short DMDUP_HORIZONTAL = 3;
372-
public static final int DPI_AWARENESS_CONTEXT_UNAWARE = 16;
373-
public static final int DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17;
372+
public static final int DPI_AWARENESS_CONTEXT_UNAWARE = 24592;
373+
public static final int DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 24593;
374374
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;
375375
public static final int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34;
376376
public static final int DSTINVERT = 0x550009;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package org.eclipse.swt.widgets;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.eclipse.swt.internal.*;
6+
import org.eclipse.swt.internal.win32.*;
7+
import org.junit.jupiter.api.*;
8+
9+
public class DisplayWin32Test {
10+
11+
private Display display;
12+
13+
@BeforeAll
14+
public static void assumeIsFittingPlatform() {
15+
PlatformSpecificExecution.assumeIsFittingPlatform();
16+
}
17+
18+
@BeforeEach
19+
public void createDisplay() {
20+
display = new Display();
21+
}
22+
23+
@AfterEach
24+
public void destroyDisplay() {
25+
display.dispose();
26+
}
27+
28+
@Test
29+
public void setRescaleAtRuntime_activate() {
30+
display.setRescalingAtRuntime(true);
31+
assertTrue(display.isRescalingAtRuntime());
32+
assertEquals(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, OS.GetThreadDpiAwarenessContext());
33+
}
34+
35+
@Test
36+
public void setRescaleAtRuntime_deactivate() {
37+
display.setRescalingAtRuntime(false);
38+
assertFalse(display.isRescalingAtRuntime());
39+
assertEquals(OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, OS.GetThreadDpiAwarenessContext());
40+
}
41+
42+
@Test
43+
public void setRescaleAtRuntime_toggling() {
44+
display.setRescalingAtRuntime(false);
45+
assertFalse(display.isRescalingAtRuntime());
46+
assertEquals(OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, OS.GetThreadDpiAwarenessContext());
47+
display.setRescalingAtRuntime(true);
48+
assertTrue(display.isRescalingAtRuntime());
49+
assertEquals(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, OS.GetThreadDpiAwarenessContext());
50+
display.setRescalingAtRuntime(false);
51+
assertFalse(display.isRescalingAtRuntime());
52+
assertEquals(OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, OS.GetThreadDpiAwarenessContext());
53+
}
54+
55+
}

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6856,9 +6856,11 @@ public boolean isRescalingAtRuntime() {
68566856
* method on other operating system will have no effect.
68576857
*
68586858
* @param activate whether rescaling shall be activated or deactivated
6859+
* @return whether activating or deactivating the rescaling was successful
68596860
* @since 3.127
68606861
*/
6861-
public void setRescalingAtRuntime(boolean activate) {
6862+
public boolean setRescalingAtRuntime(boolean activate) {
68626863
// not implemented for Cocoa
6864+
return false;
68636865
}
68646866
}

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6290,10 +6290,12 @@ public boolean isRescalingAtRuntime() {
62906290
* method on other operating system will have no effect.
62916291
*
62926292
* @param activate whether rescaling shall be activated or deactivated
6293+
* @return whether activating or deactivating the rescaling was successful
62936294
* @since 3.127
62946295
*/
6295-
public void setRescalingAtRuntime(boolean activate) {
6296+
public boolean setRescalingAtRuntime(boolean activate) {
62966297
// not implemented for GTK
6298+
return false;
62976299
}
62986300

62996301
}

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

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5272,38 +5272,42 @@ public boolean isRescalingAtRuntime() {
52725272
* method on other operating system will have no effect.
52735273
*
52745274
* @param activate whether rescaling shall be activated or deactivated
5275+
* @return whether activating or deactivating the rescaling was successful
52755276
* @since 3.127
52765277
*/
5277-
public void setRescalingAtRuntime(boolean activate) {
5278-
rescalingAtRuntime = activate;
5279-
// dispose a existing font registry for the default display
5280-
SWTFontProvider.disposeFontRegistry(this);
5281-
setProperDPIAwareness();
5278+
public boolean setRescalingAtRuntime(boolean activate) {
5279+
int desiredApiAwareness = activate ? OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 : OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE;
5280+
if (setDPIAwareness(desiredApiAwareness)) {
5281+
rescalingAtRuntime = activate;
5282+
// dispose a existing font registry for the default display
5283+
SWTFontProvider.disposeFontRegistry(this);
5284+
return true;
5285+
}
5286+
return false;
52825287
}
52835288

5284-
private void setProperDPIAwareness() {
5285-
long desiredDpiAwareness = OS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE;
5289+
private boolean setDPIAwareness(int desiredDpiAwareness) {
52865290
if (OS.WIN32_BUILD < OS.WIN32_BUILD_WIN10_1607) {
52875291
System.err.println("***WARNING: the OS version does not support setting DPI awareness.");
5288-
return;
5292+
return false;
52895293
}
5290-
if (rescalingAtRuntime) {
5291-
desiredDpiAwareness = OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2;
5292-
// Auto scaling on runtime requires DPI awareness mode "Per Monitor V2"
5294+
if (desiredDpiAwareness == OS.GetThreadDpiAwarenessContext()) {
5295+
return true;
5296+
}
5297+
if (desiredDpiAwareness == OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) {
5298+
// "Per Monitor V2" only available in more recent Windows version
52935299
boolean perMonitorV2Available = OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_1809;
52945300
if (!perMonitorV2Available) {
5295-
System.err.println(
5296-
"***WARNING: rescaling at runtime is activated but the OS version does not support required DPI awareness mode PerMonitorV2.");
5297-
return;
5301+
System.err.println("***WARNING: the OS version does not support DPI awareness mode PerMonitorV2.");
5302+
return false;
52985303
}
52995304
}
5300-
if (desiredDpiAwareness == OS.GetThreadDpiAwarenessContext()) {
5301-
return;
5302-
}
53035305
long setDpiAwarenessResult = OS.SetThreadDpiAwarenessContext(desiredDpiAwareness);
53045306
if (setDpiAwarenessResult == 0L) {
53055307
System.err.println("***WARNING: setting DPI awareness failed.");
5308+
return false;
53065309
}
5310+
return true;
53075311
}
53085312

53095313
}

0 commit comments

Comments
 (0)