Skip to content

Commit 3d3406d

Browse files
akoch-yattaHeikoKlare
authored andcommitted
[win32] Refresh thread dpi awareness on hooks
This commit resets the DPI awareness for the WH_MSGFILTER hook, if called. For performance reasons that is only done, when runAsyncMessages will be triggered, as this can cause UI updates, which would be executed with the wrong DPI awareness context and cause UI glitches.
1 parent df0ae71 commit 3d3406d

File tree

1 file changed

+37
-4
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets

1 file changed

+37
-4
lines changed

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

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ public Widget findWidget (Widget widget, long id) {
14551455

14561456
long foregroundIdleProc (long code, long wParam, long lParam) {
14571457
if (code >= 0) {
1458-
if (!synchronizer.isMessagesEmpty()) {
1458+
Runnable processMessages = () -> {
14591459
sendPostExternalEventDispatchEvent ();
14601460
if (runMessagesInIdle) {
14611461
if (runMessagesInMessageProc) {
@@ -1481,6 +1481,15 @@ long foregroundIdleProc (long code, long wParam, long lParam) {
14811481
int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT;
14821482
if (!OS.PeekMessage (msg, 0, 0, 0, flags)) wakeThread ();
14831483
sendPreExternalEventDispatchEvent ();
1484+
};
1485+
if (!synchronizer.isMessagesEmpty()) {
1486+
// Windows hooks will inherit the thread DPI awareness from
1487+
// the process. Whatever DPI awareness was set before on
1488+
// the thread will be overwritten before the hook is called.
1489+
// This requires to reset the thread DPi awareness to make
1490+
// sure, all UI updates caused by this will be executed
1491+
// with the correct DPI awareness
1492+
runWithProperDPIAwareness(processMessages);
14841493
}
14851494
}
14861495
return OS.CallNextHookEx (idleHook, (int)code, wParam, lParam);
@@ -3424,9 +3433,17 @@ long msgFilterProc (long code, long wParam, long lParam) {
34243433
if (hookMsg.message == OS.WM_NULL) {
34253434
MSG msg = new MSG ();
34263435
int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT | OS.PM_QS_POSTMESSAGE;
3427-
if (!OS.PeekMessage (msg, 0, 0, 0, flags)) {
3428-
if (runAsyncMessages (false)) wakeThread ();
3429-
}
3436+
// Windows hooks will inherit the thread DPI awareness from
3437+
// the process. Whatever DPI awareness was set before on
3438+
// the thread will be overwritten before the hook is called.
3439+
// This requires to reset the thread DPi awareness to make
3440+
// sure, all UI updates caused by this will be executed
3441+
// with the correct DPI awareness
3442+
runWithProperDPIAwareness(() -> {
3443+
if (!OS.PeekMessage (msg, 0, 0, 0, flags)) {
3444+
if (runAsyncMessages (false)) wakeThread ();
3445+
}
3446+
});
34303447
}
34313448
break;
34323449
}
@@ -5382,4 +5399,20 @@ private boolean setDPIAwareness(int desiredDpiAwareness) {
53825399
return true;
53835400
}
53845401

5402+
private void runWithProperDPIAwareness(Runnable operation) {
5403+
if (isRescalingAtRuntime()) {
5404+
// refreshing is only necessary, when monitor specific scaling is active
5405+
long previousDPIAwareness = OS.GetThreadDpiAwarenessContext();
5406+
if (!setDPIAwareness(OS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) {
5407+
// awareness was not changed, so no need to reset it
5408+
previousDPIAwareness = 0;
5409+
}
5410+
operation.run();
5411+
if (previousDPIAwareness > 0) {
5412+
OS.SetThreadDpiAwarenessContext(previousDPIAwareness);
5413+
}
5414+
} else {
5415+
operation.run();
5416+
}
5417+
}
53855418
}

0 commit comments

Comments
 (0)